Revision: 201019 RCL_3 PDK_3.0.0
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 25 May 2010 14:22:58 +0300
branchRCL_3
changeset 13 da2cedce4920
parent 12 d27dfa8884ad
child 14 a9c038d69df8
Revision: 201019 Kit: 2010121
analyzetool/analyzetoolcleaner/bwins/atoolcleaneru.def
analyzetool/analyzetoolcleaner/eabi/atoolcleaneru.def
analyzetool/analyzetoolcleaner/group/analyzetoolcleaner.mmp
analyzetool/analyzetoolcleaner/group/bld.inf
analyzetool/analyzetoolcleaner/inc/analyzetoolcleaner.h
analyzetool/analyzetoolcleaner/src/analyzetoolcleaner.cpp
analyzetool/commandlineengine/group/atool.vcproj
analyzetool/commandlineengine/group/bld.inf
analyzetool/commandlineengine/inc/ATCommonDefines.h
analyzetool/commandlineengine/inc/CATBase.h
analyzetool/commandlineengine/inc/CATDatParser.h
analyzetool/commandlineengine/inc/CATDataSaver.h
analyzetool/commandlineengine/inc/CATMemoryAddress.h
analyzetool/commandlineengine/inc/CATMmp.h
analyzetool/commandlineengine/inc/CATModule2.h
analyzetool/commandlineengine/inc/CATParseTraceFile.h
analyzetool/commandlineengine/inc/CATParseXML.h
analyzetool/commandlineengine/inc/CATProject.h
analyzetool/commandlineengine/inc/cataddr2line.h
analyzetool/commandlineengine/inc/cataddr2lineserver.h
analyzetool/commandlineengine/inc/catalloc.h
analyzetool/commandlineengine/inc/catallocs.h
analyzetool/commandlineengine/inc/catdbghelper.h
analyzetool/commandlineengine/inc/catfilereader.h
analyzetool/commandlineengine/inc/catromsymbol.h
analyzetool/commandlineengine/inc/iaddresstoline.h
analyzetool/commandlineengine/inc/stdafx.h
analyzetool/commandlineengine/install/addr2line.exe
analyzetool/commandlineengine/install/atool.exe
analyzetool/commandlineengine/install/binutils-2.19.1-src.zip
analyzetool/commandlineengine/install/xerces-c_2_7.dll
analyzetool/commandlineengine/lib/xerces-c_2.lib
analyzetool/commandlineengine/src/CATBase.cpp
analyzetool/commandlineengine/src/CATDatParser.cpp
analyzetool/commandlineengine/src/CATDataSaver.cpp
analyzetool/commandlineengine/src/CATMemoryAddress.cpp
analyzetool/commandlineengine/src/CATMmp.cpp
analyzetool/commandlineengine/src/CATModule2.cpp
analyzetool/commandlineengine/src/CATParseTraceFile.cpp
analyzetool/commandlineengine/src/CATParseXML.cpp
analyzetool/commandlineengine/src/CATProject.cpp
analyzetool/commandlineengine/src/arguments.cpp
analyzetool/commandlineengine/src/atool.cpp
analyzetool/commandlineengine/src/cataddr2line.cpp
analyzetool/commandlineengine/src/cataddr2lineserver.cpp
analyzetool/commandlineengine/src/catalloc.cpp
analyzetool/commandlineengine/src/catallocs.cpp
analyzetool/commandlineengine/src/catdbghelper.cpp
analyzetool/commandlineengine/src/catfilereader.cpp
analyzetool/commandlineengine/src/catromsymbol.cpp
analyzetool/commandlineengine/src/helps.cpp
analyzetool/commandlineengine/src/librarychecks.cpp
analyzetool/commandlineengine/src/stdafx.cpp
analyzetool/commandlineengine/src/utility.cpp
analyzetool/commandlineengine/src/version.cpp
analyzetool/dynamicmemoryhook/bwins/atoolmemoryhooku.def
analyzetool/dynamicmemoryhook/eabi/atoolmemoryhooku.def
analyzetool/dynamicmemoryhook/group/atoolmemoryhook.mmp
analyzetool/dynamicmemoryhook/group/bld.inf
analyzetool/dynamicmemoryhook/inc/analyzetoolallocator.h
analyzetool/dynamicmemoryhook/inc/analyzetooleventhandler.h
analyzetool/dynamicmemoryhook/inc/analyzetooleventhandlernotifier.h
analyzetool/dynamicmemoryhook/inc/analyzetoolfastlog.h
analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.h
analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.inl
analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.h
analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.inl
analyzetool/dynamicmemoryhook/inc/analyzetoolpanics.pan
analyzetool/dynamicmemoryhook/inc/codeblock.h
analyzetool/dynamicmemoryhook/inc/customuser.h
analyzetool/dynamicmemoryhook/inc/threadstack.h
analyzetool/dynamicmemoryhook/sis/analyzetoolmemoryhook.pkg
analyzetool/dynamicmemoryhook/src/analyzetoolallocator.cpp
analyzetool/dynamicmemoryhook/src/analyzetooleventhandler.cpp
analyzetool/dynamicmemoryhook/src/analyzetoolfastlog.cpp
analyzetool/dynamicmemoryhook/src/analyzetoolmainallocator.cpp
analyzetool/dynamicmemoryhook/src/analyzetoolmemoryallocator.cpp
analyzetool/dynamicmemoryhook/src/codeblock.cpp
analyzetool/dynamicmemoryhook/src/customuser.cpp
analyzetool/dynamicmemoryhook/src/threadstack.cpp
analyzetool/envpatcher/EnvPatcher.pl
analyzetool/envpatcher/ReadMe.txt
analyzetool/group/ReleaseNotes_AnalyzeTool.txt
analyzetool/group/atool_stub_sis.mk
analyzetool/group/bld.inf
analyzetool/inc/atlog.h
analyzetool/kerneleventhandler/group/atoolkerneleventhandler.mmp
analyzetool/kerneleventhandler/group/bld.inf
analyzetool/kerneleventhandler/inc/analyzetool.h
analyzetool/kerneleventhandler/inc/analyzetool.inl
analyzetool/kerneleventhandler/inc/analyzetoolchannel.h
analyzetool/kerneleventhandler/inc/analyzetooldevice.h
analyzetool/kerneleventhandler/inc/analyzetooleventhandler.h
analyzetool/kerneleventhandler/inc/analyzetooltraceconstants.h
analyzetool/kerneleventhandler/inc/atcommon.h
analyzetool/kerneleventhandler/sis/analyzetooldevicedriver.pkg
analyzetool/kerneleventhandler/src/analyzetoolchannel.cpp
analyzetool/kerneleventhandler/src/analyzetooldevice.cpp
analyzetool/kerneleventhandler/src/analyzetooleventhandler.cpp
analyzetool/rom/analyzetool.iby
analyzetool/rom/analyzetool_rom.iby
analyzetool/sis/AnalyzeTool.pkg
analyzetool/sis/AnalyzeTool_udeb.pkg
analyzetool/sis/analyzeTool_stub.pkg
analyzetool/staticlib/group/atoolstaticlib.mmp
analyzetool/staticlib/group/bld.inf
analyzetool/staticlib/src/atoolstaticlib.cpp
analyzetool/storageserver/client/bwins/atoolstorageserverclntu.def
analyzetool/storageserver/client/eabi/atoolstorageserverclntu.def
analyzetool/storageserver/client/group/atoolstorageserverclnt.mmp
analyzetool/storageserver/client/inc/atstorageserverclnt.h
analyzetool/storageserver/client/src/atstorageserverclnt.cpp
analyzetool/storageserver/group/bld.inf
analyzetool/storageserver/inc/atstorageservercommon.h
analyzetool/storageserver/server/group/atoolstorageserver.mmp
analyzetool/storageserver/server/inc/atdllinfo.h
analyzetool/storageserver/server/inc/atdriveinfo.h
analyzetool/storageserver/server/inc/atdynprocessinfo.h
analyzetool/storageserver/server/inc/atmemoryentry.h
analyzetool/storageserver/server/inc/atstorageserver.h
analyzetool/storageserver/server/inc/atstorageserversession.h
analyzetool/storageserver/server/src/atdllinfo.cpp
analyzetool/storageserver/server/src/atdriveinfo.cpp
analyzetool/storageserver/server/src/atdynprocessinfo.cpp
analyzetool/storageserver/server/src/atmemoryentry.cpp
analyzetool/storageserver/server/src/atstorageserver.cpp
analyzetool/storageserver/server/src/atstorageserversession.cpp
analyzetool/storageserver/sis/atstorageserver.pkg
analyzetool/storageserver/sis/atstorageserver_udeb.pkg
analyzetool/symbian_version.hrh
group/bld.inf
hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h
hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h
hti/hti_plat/hti_api/inc/HtiVersion.h
piprofiler/engine/group/ProfilerEngine.mmp
piprofiler/engine/group/ProfilerEshell.mmp
piprofiler/engine/group/bld.inf
piprofiler/engine/inc/ProfilerEngine.h
piprofiler/engine/inc/ProfilerErrorChecker.h
piprofiler/engine/inc/ProfilerEshell.h
piprofiler/engine/inc/ProfilerTimer.h
piprofiler/engine/inc/SamplerController.h
piprofiler/engine/inc/SamplerPluginLoader.h
piprofiler/engine/inc/WriterController.h
piprofiler/engine/inc/WriterPluginLoader.h
piprofiler/engine/src/ProfilerEngine.cpp
piprofiler/engine/src/ProfilerErrorChecker.cpp
piprofiler/engine/src/ProfilerEshell.cpp
piprofiler/engine/src/ProfilerTimer.cpp
piprofiler/engine/src/SamplerController.cpp
piprofiler/engine/src/SamplerPluginLoader.cpp
piprofiler/engine/src/WriterController.cpp
piprofiler/engine/src/WriterPluginLoader.cpp
piprofiler/group/ReleaseNotes_PIProfiler.txt
piprofiler/group/bld.inf
piprofiler/piprofiler_plat/group/bld.inf
piprofiler/piprofiler_plat/inc/EngineUIDs.h
piprofiler/piprofiler_plat/inc/PluginDriver.h
piprofiler/piprofiler_plat/inc/PluginDriver.inl
piprofiler/piprofiler_plat/inc/PluginSampler.h
piprofiler/piprofiler_plat/inc/ProfilerAttributes.h
piprofiler/piprofiler_plat/inc/ProfilerConfig.h
piprofiler/piprofiler_plat/inc/ProfilerEngineAPI.h
piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.h
piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.inl
piprofiler/piprofiler_plat/inc/ProfilerGenericClassesCommon.h
piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.h
piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.inl
piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.h
piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.inl
piprofiler/piprofiler_plat/inc/ProfilerSession.h
piprofiler/piprofiler_plat/inc/ProfilerTraces.h
piprofiler/piprofiler_plat/inc/ProfilerVersion.h
piprofiler/piprofiler_plat/inc/SamplerPluginInterface.h
piprofiler/piprofiler_plat/inc/SamplerPluginInterface.inl
piprofiler/piprofiler_plat/inc/WriterPluginInterface.h
piprofiler/piprofiler_plat/inc/WriterPluginInterface.inl
piprofiler/piprofiler_plat/piprofiler_api.metaxml
piprofiler/plugins/BUPplugin/data/2001E5B6.rss
piprofiler/plugins/BUPplugin/group/BUPPlugin.mmp
piprofiler/plugins/BUPplugin/group/TouchAnimDll.mmp
piprofiler/plugins/BUPplugin/group/bld.inf
piprofiler/plugins/BUPplugin/inc/BupPlugin.h
piprofiler/plugins/BUPplugin/inc/TouchEventAnimDll.h
piprofiler/plugins/BUPplugin/inc/TouchEventClientDll.h
piprofiler/plugins/BUPplugin/sis/BupPlugin_S60-30.pkg
piprofiler/plugins/BUPplugin/src/BupPlugin.cpp
piprofiler/plugins/BUPplugin/src/BupPluginImplementationTable.cpp
piprofiler/plugins/BUPplugin/src/TouchEventAnimDll.cpp
piprofiler/plugins/BUPplugin/src/TouchEventClientDll.cpp
piprofiler/plugins/DebugOutputWriterPlugin/data/2001E5BA.rss
piprofiler/plugins/DebugOutputWriterPlugin/group/DebOutWriterPlugin.mmp
piprofiler/plugins/DebugOutputWriterPlugin/group/bld.inf
piprofiler/plugins/DebugOutputWriterPlugin/inc/DebOutWriterPlugin.h
piprofiler/plugins/DebugOutputWriterPlugin/sis/DebOutWriterPlugin_EKA2.pkg
piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPlugin.cpp
piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPluginImplementationTable.cpp
piprofiler/plugins/DiskWriterPlugin/data/2001E5BB.rss
piprofiler/plugins/DiskWriterPlugin/group/DiskWriterPlugin.mmp
piprofiler/plugins/DiskWriterPlugin/group/bld.inf
piprofiler/plugins/DiskWriterPlugin/inc/DiskWriterPlugin.h
piprofiler/plugins/DiskWriterPlugin/sis/DiskWriterPlugin_EKA2.pkg
piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPlugin.cpp
piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPluginImplementationTable.cpp
piprofiler/plugins/GeneralsPlugin/data/2001E5B2.rss
piprofiler/plugins/GeneralsPlugin/group/GeneralsPlugin.mmp
piprofiler/plugins/GeneralsPlugin/group/GeneralsSampler.mmp
piprofiler/plugins/GeneralsPlugin/group/bld.inf
piprofiler/plugins/GeneralsPlugin/inc/GeneralsConfig.h
piprofiler/plugins/GeneralsPlugin/inc/GeneralsDriver.h
piprofiler/plugins/GeneralsPlugin/inc/GeneralsPlugin.h
piprofiler/plugins/GeneralsPlugin/inc/GfcSamplerImpl.h
piprofiler/plugins/GeneralsPlugin/inc/GppSamplerImpl.h
piprofiler/plugins/GeneralsPlugin/inc/IttEventHandler.h
piprofiler/plugins/GeneralsPlugin/inc/IttSamplerImpl.h
piprofiler/plugins/GeneralsPlugin/inc/MemSamplerImpl.h
piprofiler/plugins/GeneralsPlugin/inc/MemoryEventHandler.h
piprofiler/plugins/GeneralsPlugin/inc/PriSamplerImpl.h
piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp
piprofiler/plugins/GeneralsPlugin/src/GeneralsPlugin.cpp
piprofiler/plugins/GeneralsPlugin/src/GeneralsPluginImplementationTable.cpp
piprofiler/plugins/GeneralsPlugin/src/GeneralsSampler.cia
piprofiler/plugins/GeneralsPlugin/src/GppSamplerImpl.cpp
piprofiler/plugins/GeneralsPlugin/src/IttEventHandler.cpp
piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp
piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp
piprofiler/plugins/GeneralsPlugin/src/MemoryEventHandler.cpp
piprofiler/plugins/GeneralsPlugin/src/PriSamplerImpl.cpp
piprofiler/rom/piprofiler.iby
piprofiler/rom/piprofiler_ldd.iby
stif/Parser/src/StifParser.cpp
stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp
stif/group/ReleaseNote.txt
stif/inc/version.h
stif/sis/Stif_31.sis
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/bwins/atoolcleaneru.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+	?GetCallBackAddress@@YAPAV?$TFixedArray@K$09@@XZ @ 1 NONAME ; class TFixedArray<unsigned long, 10> * GetCallBackAddress(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/eabi/atoolcleaneru.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+	_Z18GetCallBackAddressv @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/group/analyzetoolcleaner.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for atoolcleaner.
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET			atoolcleaner.dll
+TARGETTYPE	  	dll
+UID 			0x1000008d 0x2002DC71
+CAPABILITY		ALL -TCB
+EPOCALLOWDLLDATA
+
+SMPSAFE
+
+SOURCEPATH  ../src
+SOURCE analyzetoolcleaner.cpp
+
+USERINCLUDE   ../inc
+USERINCLUDE   ../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY flogger.lib
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,8 @@
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../inc/analyzetoolcleaner.h  OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetoolcleaner.h)
+
+PRJ_MMPFILES
+analyzetoolcleaner.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/inc/analyzetoolcleaner.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class TAnalyzeToolCleanerBase.
+*
+*/
+
+#ifndef __ANALYZETOOLCLEANER_H__
+#define __ANALYZETOOLCLEANER_H__
+
+// INCLUDES
+#include <e32std.h>
+
+// CONSTANTS
+#define ATCLEANERTABLESIZE 10
+#define ATCLEANERTABLE TFixedArray<TUint32, ATCLEANERTABLESIZE>
+_LIT( KATCleanerDllName, "atoolcleaner.dll" );
+
+// CLASS DECLARATION
+
+/**
+*  Cleaner base class
+*/
+class TAnalyzeToolCleanerBase
+    {
+public:
+    /**
+    * Cleanup function which uninstall allocator
+    */
+    virtual void Cleanup() = 0;
+    };
+
+// CLASS DECLARATION
+
+/**
+*  Cleaner class
+*/
+class THookCleaner
+    {
+public:
+    /**
+    * C++ default constructor.
+    */
+    THookCleaner();
+    
+    /**
+    * Destructor.
+    */
+    ~THookCleaner();
+    
+    ATCLEANERTABLE iTable;
+    };
+#endif // __ANALYZETOOLCLEANER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/src/analyzetoolcleaner.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  THookCleaner implementation
+*
+*/
+
+// INCLUDES
+#include "analyzetoolcleaner.h"
+#include <e32debug.h>
+#include "atlog.h"
+
+// Global cleaner object
+static THookCleaner cleaner;
+
+// ordinal 1
+EXPORT_C ATCLEANERTABLE* GetCallBackAddress()
+    {
+    LOGSTR1( "ATC GetCallBackAddress()" );
+    
+    return &( cleaner.iTable );
+    }
+
+// -----------------------------------------------------------------------------
+// THookCleaner::THookCleaner()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+THookCleaner::THookCleaner()
+    {
+    LOGSTR1( "ATC THookCleaner::THookCleaner()" );
+    
+    iTable.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// THookCleaner::~THookCleaner()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+THookCleaner::~THookCleaner()
+    {
+    LOGSTR1( "ATC THookCleaner::~THookCleaner()" );
+    
+    for ( TUint i = 0; i < ATCLEANERTABLESIZE; i++ )
+        {
+        if ( iTable.At( i ) )
+            {
+            TAnalyzeToolCleanerBase* obj =
+                    ( TAnalyzeToolCleanerBase* ) iTable.At( i );
+            obj->Cleanup();
+            }
+        }
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/group/atool.vcproj	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="atool"
+	ProjectGUID="{2C50DD86-958B-4189-8DA2-DB388C71F65F}"
+	RootNamespace="atool"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				TreatWChar_tAsBuiltInType="false"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderThrough="..\inc\stdafx.h"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\lib\xerces-c_2.lib ..\lib\dbghelp.lib Version.lib"
+				OutputFile="..\install\atool.exe"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/atool.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="0"
+				TreatWChar_tAsBuiltInType="false"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\lib\xerces-c_2.lib ..\lib\dbghelp.lib Version.lib"
+				OutputFile="..\install\atool.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\arguments.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\atool.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\cataddr2line.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\cataddr2lineserver.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\catalloc.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\catallocs.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATBase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATDataSaver.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATDatParser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\catdbghelper.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\catfilereader.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATMemoryAddress.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATMmp.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATModule2.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATParseTraceFile.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATParseXML.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\CATProject.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\catromsymbol.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\helps.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\librarychecks.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\stdafx.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\utility.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\version.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\inc\ATCommonDefines.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\cataddr2line.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\cataddr2lineserver.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\catalloc.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\catallocs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATBase.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATDataSaver.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATDatParser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\catdbghelper.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\catfilereader.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATMemoryAddress.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATMmp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATModule2.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATParseTraceFile.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATParseXML.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\CATProject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\catromsymbol.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\iaddresstoline.h"
+				>
+			</File>
+			<File
+				RelativePath="..\inc\stdafx.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+PRJ_EXPORTS
+../install/atool.exe          +/tools/
+../install/addr2line.exe      +/tools/
+../install/xerces-c_2_7.dll   +/tools/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/ATCommonDefines.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,598 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Common defines for cpp files.
+*
+*/
+
+
+#ifndef __ATCOMMONDEFINES_H__
+#define __ATCOMMONDEFINES_H__
+
+#include "../inc/stdafx.h"
+
+using namespace std;
+
+/**
+* Atool return code.
+*/
+struct AT_RETURN_CODE {
+	/**
+	* Enumeration containing all return codes used by atool.
+	* When error happens this value set as the exit code.
+	* Note! Values can be only added not modified/deleted.
+	*/
+	enum RETURN_CODE {
+		/* basic */
+		OK = 0,							/** All ok. */
+		INVALID_ARGUMENT_ERROR = 1,		/** Arguments failty. */
+		AT_LIBS_MISSING = 2,			/** Missing at libraries cannot compile hooked apps. */
+		CANNOT_FIND_EPOCROOT = 3,		/** Epocroot not set. */
+		UNHANDLED_EXCEPTION = 4,		/** General return code when unhandled exception occurs. */
+		/* compile errors */
+		MAKEFILE_ERROR = 5,				/** Cannot read/create etc makefiles sbs1/2. */
+		COMPILE_ERROR = 6,				/** Some error related to compilation of code. */
+		UNKNOWN = 7,					/** General compilation error not specific. */
+		NO_SUPPORTED_MODULES_ERROR = 8,	/** Cannot find supported modules from project. */
+		KERNEL_SIDE_MODULE_ERROR = 9,	/** Cannot find supported modules from project because kernel side. */
+		/* Analyze errors */
+		WRONG_DATA_FILE_VERSION = 10,	/** Invalid data file version in internal gathering mode. */
+		INVALID_DATA_FILE = 11,			/** Data file content invalid. */
+		ANALYZE_ERROR = 12,				/** General error in analyze part not specific. */
+		EMPTY_DATA_FILE = 13,			/** Data file is empty. */
+		SYMBOL_FILE_ERROR = 14,			/** Symbol file content invalid or do not exist. */
+		/* building&releasing errors */
+		RELEASABLES_ERROR = 20,			/** Cannot find the binaries of module. */
+		RESTORE_MODULES_ERROR = 21,		/** Error restoring mmp file to original. */
+		CREATING_TEMP_CPP_ERROR = 22,	/** Error creating temporary cpps to store variables to s60 core.*/
+		CLEANING_TEMP_ERROR = 23,		/** Error cleaning atool_temp folder from module. */
+		READ_MAKEFILE_ERROR = 24,		/** Some error when reading makefile of module / project (sbs1/2). */
+		MODIFY_MODULES_ERROR = 25,		/** Error modifying module mmp file. */
+		INVALID_MMP_DEFINED = 27,		/** Specified module does not exist in project. */
+		/* Attribute file related */
+		WRITE_ATTRIBUTES_ERROR = 30,	/** Error writing the cfg file into atool_temp folder (contains arguments).*/
+		READ_ATTRIBUTES_ERROR = 31,		/** Error reading hooking related arguments from cfg file. */
+		/* User issued exit */
+		USER_ISSUED_EXIT = 40,			/** User aborted the run of application. */
+	};
+};
+
+// Debug logging to console
+extern bool g_bDebugConsole;
+// Debug logging to windows api debug
+extern bool g_bDebugDbgView;
+// Debug (low level functions).
+extern bool g_bDebugLowLevel;
+
+// Temporary directory definition's.
+const char AT_TEMP_DIR[] = "atool_temp";
+const char AT_TEMP_LST_DIR[] = "atool_temp\\static_lsts\\";
+
+// makefile dir is used in atool.cpp to check will we use sbs2 (in analyze and clear)
+#define RAPTOR_MAKEFILE_DIR "atool_temp\\build"
+
+// Atool version number and date
+#define ATOOL_VERSION "1.9.1" // NOTE! This version number is written also to temporary cpp file.
+#define ATOOL_DATE "29th April 2010"
+
+// Default/min/max call stack sizes
+const int AT_ALLOC_CALL_STACK_SIZE_DEFAULT = 40;
+const int AT_FREE_CALL_STACK_SIZE_DEFAULT = 0;
+const int AT_CALL_STACK_SIZE_MIN = 0;
+const int AT_CALL_STACK_SIZE_MAX = 256;
+
+// What version of data file contains timestamps in dll's.
+const int AT_DLL_TIMESTAMP_DATA_VERSION = 2;
+
+// Constant compatibility string in temporary cpp.
+// Api version ; current version.
+#define ATOOL_COMPATIBILITY_STRING "1.7.5;1.9.1"
+
+// Datafile version
+#define AT_DATA_FILE_VERSION "DATA_FILE_VERSION 11"
+
+// Latest dbghelp.dll version
+const int DBGHELP_VERSION_MAJ = 6;
+const int DBGHELP_VERSION_MIN = 3;
+const int DBGHELP_VERSION_BUILD = 0;
+const int DBGHELP_VERSION_REVIS = 0;
+const char DBGHELP_DLL_NAME[] = "dbghelp.dll";
+
+
+// Build summary constants
+const string AT_BUILD_SUMMARY_HEADER = "\n###  AnalyzeTool  ###\n### Build Summary ###\n\n";
+const string AT_BUILD_SUMMARY_INSTRUMENTED_BUILD_COMPLETE = "Instrumented build complete: ";
+const string AT_BUILD_SUMMARY_TARGET = "\tTarget: ";
+const string AT_BUILD_SUMMARY_FAILED = "Build failed: ";
+const string AT_BUILD_SUMMARY_ERRORS = "\tErrors: ";
+const string AT_BUILD_SUMMARY_DATA_FILE_NAME = "\tInternal data gathering filename: ";
+const string AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE = "Normal build complete: ";
+const string AT_BUILD_SUMMARY_STATIC_LIBRARY = "\tModule is static library.";
+const string AT_BUILD_SUMMARY_UNSUPPORTED_TARGET_TYPE = "\tModule has unsupported target type.";
+const string AT_BUILD_SUMMARY_UNSUPPORTED_COMPILE_DEFINITION = "\tModule defined unsupported compile definition.";
+const string AT_BUILD_SUMMARY_BUILD_TYPE = "Build type: ";
+const string AT_BUILD_SUMMARY_BUILD_TARGET = "Build target: ";
+const string AT_BUILD_SUMMARY_BUILD_PLATFORM = "Build platform: ";
+const string AT_BUILD_SUMMARY_BUILD_VARIANT = "Build variant: ";
+const string AT_BUILD_SUMMARY_LOGGING_MODE = "Data gathering mode: ";
+const string AT_BUILD_SUMMARY_ALLOC_CALL_STACK_SIZE = "Allocation call stack size: ";
+const string AT_BUILD_SUMMARY_FREE_CALL_STACK_SIZE = "Free call stack size: ";
+const string AT_BUILD_SUMMARY_FILE = "monitored internal";
+const string AT_BUILD_SUMMARY_TRACE = "monitored external";
+const string AT_BUILD_SUMMARY_TRACE_FAST = "external";
+
+const string AT_UNSUPPORTED_TARGET_TYPE = "\tModule has unsupported target type.";
+const string AT_UNSUPPORTED_COMPILE_DEFINITION = "\tModule defined unsupported compile definition.";
+
+// List of locations under epocroot where analyzetool.h can be found.
+// Add all possible to this list so core version information can be read
+// from file.
+const string AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER[] = {
+	"epoc32\\include\\domain\\osextensions\\analyzetool\\analyzetool.h",
+	"epoc32\\include\\oem\\analyzetool\\analyzetool.h",
+	"epoc32\\include\\platform\\analyzetool\\analyzetool.h"
+};
+const string AT_CORE_VERSION_NUMBER_TAG = "ANALYZETOOL_CORE_VERSION_FOR_CLE";
+
+// Temporary cpp name
+const char AT_TEMP_CPP_LOWER_START[] = "0a1b2c3d_atool_temp_";
+const char AT_TEMP_CPP_LOWER_END[] = ".cpp";
+
+const char TAB_CHAR_VALUE = 9;
+const char SPACE_CHAR_VALUE = 32;
+
+// Bldmake error msg
+#define AT_BLDMAKE_ERROR "AnalyzeTool : bldmake bldfiles error.\n"
+
+// File copy/move/etc... message definitions
+#define AT_MSG "AnalyzeTool : "
+#define AT_MSG_SYSTEM_CALL "AnalyzeTool : System call, "
+#define AT_FILE_TO " to "
+
+// -c messages
+#define AT_CLEANING_DONE "AnalyzeTool : Cleaning done."
+#define AT_CLEANING_NOTHING_FOUND "AnalyzeTool : Nothing found to clean."
+
+// Analyzing data without process start or dll load
+#define AT_ANALYZE_INSUFFICIENT_LOGGING_DATA "Insufficient logging data to locate code lines for memory addresses.\nLogging has been started after process start."
+#define AT_ANALYZE_NO_PROCESS_START "AnalyzeTool : No processes start information found in test run data."
+#define AT_ANALYZE_NO_DLL_LOAD "AnalyzeTool : No dll load information found in test run data."
+#define AT_ANALYZE_CANNOT_PINPOINT "AnalyzeTool : Memory addresses cannot be pinpointed."
+#define AT_ANALYZE_ABNORMAL_EXIT "Abnormal process end"
+
+// Analyzing without map / lst files
+#define AT_ANALYZE_MISSING_LST_MAP_FILES "AnalyzeTool : Missing lst or map files, memory addresses shown only to module level.\n"
+//#define AT_UNINSTRUMENT_FAILED_IN_ANALYZE_MESSAGE "AnalyzeTool: Error creating map/lst files, leaks shown only to module level.\nRun atool -u to try create lst/map files again after binaries build successfully.\n"
+
+// Mmp error msg
+#define INVALID_MMP_ERROR "AnalyzeTool : Error, Specified mmp is invalid.\n"
+
+// Make error msg
+#define MAKE_ERROR "AnalyzeTool : Error, Running make.\n"
+
+#define AT_NOT_BEEN_BUILD_ERROR "AnalyzeTool : Error, project has not been build using AnalyzeTool.\n"
+
+// Makefile errors
+#define LEVEL1_MAKEFILE_ERROR "AnalyzeTool : Error, reading level 1 makefile.\n"
+#define LEVEL2_MAKEFILE_ERROR "AnalyzeTool : Error, reading level 2 makefile.\n"
+#define MAKEFILE_ERROR_TIP "AnalyzeTool : Tip, your environment might require you to use -variant [target] argument.\n";
+
+//Variant messages
+#define INVALID_VARIANT_ERROR "AnalyzeTool : Error,Specified variant is invalid.\n"
+#define USING_DEFAULT_VARIANT_MESSAGE "AnalyzeTool : Note, Using DEFAULT variant.\n"
+#define NO_DEFAULT_VARIANT_ERROR "AnalyzeTool : Error, environment does not specify DEFAULT variant (No variant support?).\n"
+
+// Variant dir is the dir where all variants are defined
+#define VARIANT_DIR "\\epoc32\\tools\\variant\\"
+
+// Variants defined extension name of the variant must equal filename
+#define VARIANT_FILE_EXTENSION ".VAR"
+
+//Max file name length
+const int MAX_FILENAME_LENGTH = 1024;
+
+//Max line length when reading lines from text file.2048 should be enought.
+const int MAX_LINE_LENGTH = 2048*8;
+
+// ATs project file name to store project attributes
+#define AT_PROJECT_ATTRIBUTES_FILE_NAME "project.cfg"
+const string AT_PROJECT_ATTRIBUTES_SEPARATOR( ":$:" );
+
+// ATs level1 makefile name
+#define AT_LEVEL_1_MAKEFILE_NAME "main.at"
+
+// ATs level2 makefiles extension
+#define AT_LEVEL_2_MAKEFILE_EXT "atm"
+
+//Default logging level
+const int DEFAULT_LOGGING_LEVEL = 3;
+
+//Minimun value of logging level 
+const int MIN_LOGGING_LEVEL = 0;
+
+//Maximun value of logging level
+const int MAX_LOGGING_LEVEL = 3;
+
+//Const char represeting dash
+const char DASH = '\\';
+
+/**
+ * Table of file extension not to delete
+ * from atools temp directory when compiling
+ * note define all in lowercase
+ */
+const string TEMP_EXTENSION_NO_DELETE[] = {
+	"xml",
+	"dat",
+	"tmp",
+	"cpp",
+	"at",
+	"atm",
+	"cfg"
+};
+
+// Allowed characters/digits, other than these will be filtered out when using CATBase FilterString
+const char CFILTERSTRING[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
+
+/**
+ * Table of unsupported target types
+ * (i.e. mmp file syntax targettype in makefile)
+ * List of target types which will not be hooked:
+*/
+const string UNSUPPORTED_TARGET_TYPES[] = {
+	"CTL",
+	"ECOMIIC",
+	"IMPLIB",
+	"KDLL",
+	"KEXT",
+	"KLIB",
+	"LDD",
+	/* "LIB",  currently have own vector in project.*/
+	"MDA",
+	"MDL",
+	"NONE",
+	"NOTIFIER",
+	"PDD",
+	"RDL",
+	"STDLIB",
+	"VAR"
+};
+
+/**
+* Kernel side target types
+*/
+const string KERNEL_SIDE_TARGET_TYPES[] = {
+	"VAR",
+	"LDD",
+	"PDD",
+	"KEXT"
+};
+
+// Kernel mode compile definition
+const string KERNEL_MODE_COMPILE_DEFINITION = "__KERNEL_MODE__";
+
+/**
+* MMP file changes for AT
+* Note "SOURCE            0a1b2c3d_atool_temp_TARGET.cpp" is added also.
+*/
+const string MMPFILECHANGES[] = {
+	"//*** AnalyzeTool changes start ***",
+	"SOURCEPATH        atool_temp",
+	"LIBRARY           AToolMemoryHook.lib",
+	"STATICLIBRARY     AToolStaticLib.lib",
+	"OPTION ARMCC --interleave",
+	"//*** AnalyzeTool changes end ***"
+};
+
+//MMP file changes for AT
+//For targettype Dll
+const string MMPFILECHANGES_DLL[] = {
+	"//*** AnalyzeTool changes start ***",
+	"OPTION ARMCC --interleave",
+	"//*** AnalyzeTool changes end ***"
+};
+
+// Trace file constants definitions
+#define LABEL_DATA_FILE_VERSION "DATA_FILE_VERSION"
+#define LABEL_PROCESS_START     "PROCESS_START"
+#define LABEL_DLL_LOAD          "DLL_LOAD"
+#define LABEL_DLL_UNLOAD		"DLL_UNLOAD"
+#define LABEL_MEM_LEAK          "MEM_LEAK"
+#define LABEL_PROCESS_END       "PROCESS_END"
+#define LABEL_ERROR_OCCURED     "ERROR_OCCURED"
+#define LABEL_HANDLE_LEAK       "HANDLE_LEAK"
+#define LABEL_TEST_START        "TEST_START"
+#define LABEL_TEST_END          "TEST_END"
+#define LABEL_LOGGING_CANCELLED "LOGGING_CANCELLED"
+
+// AddressToLine related constants
+
+#define LABEL_ABNORMAL "ABNORMAL"
+const int FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5 = 0x8000;
+const int FUNCTIONS_OFFSET_IN_GCCE = 0x8000;
+const int FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW = 0x400000;
+#define TEXT_NO_HANDLE_LEAKS "No handle leaks."
+
+// Make file constant labels
+#define MAKEFILE_TARGETTYPE_STRING "# TargetType "
+#define MAKEFILE_BASIC_TARGETTYPE_STRING "# BasicTargetType "
+#define MAKEFILE_TARGET_STRING "# Target "
+#define MAKEFILE_FEATURE_VARIANT_NAME "# FeatureVariantName "
+#define MAKEFILE_FEATURE_VARIANT_UREL_LABEL "# FeatureVariantURELLabel "
+#define MAKEFILE_FEATURE_VARIANT_UDEB_LABEL "# FeatureVariantUDEBLabel "
+#define UDEB_OPTIMIZATION_LEVEL 0
+
+// Listing file contant labels
+#define LST_FILE_SOURCE_FILE_LABEL "Source file:"
+
+/**
+* Struct for saving module info from .dat file and number of leaks in module.
+*/
+struct DLL_LOAD_INFO
+{
+	string sModuleName; /** name of the code segment/binary */
+	unsigned long iStartAddress; /** start address of code segment (in memory) */
+	unsigned long iEndAddress; /** end address of code segment (in memory) */
+	int iLeaks; /** leak count in this code segment */
+	unsigned long iPID; /** process id which loaded this code segment */
+	int iSubTestStartOpenHandles; /** open handle count when sub test started */
+	int iSubTestEndOpenHandles; /** open handle count when sub test ended */
+	// Load/Unload times, note these are micro seconds from 1970 so size is huge.
+	unsigned long long iLoadTime; /** code segment load time */
+	unsigned long long iUnloadTime; /** code segment unload time */
+	/**
+	* Default constructor to set default values
+	*/
+	DLL_LOAD_INFO() {
+		iStartAddress = 0;
+		iEndAddress = 0;
+		iLeaks = 0;
+		iPID = 0;
+		iSubTestStartOpenHandles = 0;
+		iSubTestEndOpenHandles = 0;
+		iLoadTime = 0;
+		iUnloadTime = 0;
+	};
+};
+
+/**
+* Struct for saving symbol information from listing file
+*/
+struct LINE_IN_FILE
+{
+	int iLine; /** line number */
+	string sFileName; /** filename */
+	string sFunction; /** function / symbol */
+	string sMangledName; /** function / symbol name in mangled / coded form */
+	string sLstName; /** listing filename */
+};
+
+/**
+* Struct for saving symbol information from map file
+*/
+struct MAP_FUNC_INFO
+{
+	int iAddress; /** memory address (start of symbol) */
+	int iFuncLength; /** symbol length */
+	string sMangledName;/** symbol name in mangled / coded form */
+	string sWholeLine; /** whole symbol line from map file */
+	string sFunctionName; /** symbol clear name */
+};
+
+/**
+* State that represents the outcome
+* of locating memory address code line from module
+*/
+enum ADDRESS_TO_LINE_STATE {
+	no_map_data = 0, /** Map data was missing */
+	out_of_function_range, /** Could not locate it to any function */
+	mangled_symbol_name, /** symbol name but mangled / coded form */
+	only_function_name, /** Only got function name not code line */
+	succesfull /** Have line number, function, etc...*/
+};
+
+/**
+* Struct to store detail data and state when
+* locating memory addresses code lines
+*/
+struct ADDRESS_TO_LINE_ITEM {
+	ADDRESS_TO_LINE_STATE eState; /** outcome */
+	string sFileName; /** Filename of address */
+	string sFunctionName; /** Function name of address */
+	string sMangledFunctionName; /** function/Symbol name */
+	int iFunctionLineNumber; /** Functions line number */
+	int iExactLineNumber; /** Exact line number of address */
+};
+
+/**
+* Struct to store  memory leaks
+* call stack entry data
+*/
+struct CALL_STACK_ITEM {
+	string sAddress; /** Address in string */
+	int iAddress; /** Address in number (converted)*/
+	int iLocation; /** Location. i.e. corresponds m_vDllLoadModList's index*/
+	int iCalculatedLeakAddress; /** calculated address from code segment start */
+	bool bBuildUdeb; /** Optimization level */
+	string sModuleName; /** Modules name were leak is*/
+	ADDRESS_TO_LINE_ITEM addressToLine; /** Data from locating code line for memory address */
+};
+
+/**
+* Enumerations used in argument structure.
+*/
+enum MAIN_SWITCH
+{
+	SWITCH_UNKNOWN = 0, /** not defined */
+	SWITCH_ANALYZE = 1, /** analyze */
+	SWITCH_HOOK = 2, /** compile/instrument */
+	SWITCH_UNHOOK = 3, /** uninstrument */
+	SWITCH_PARSE_TRACE = 5, /** parse raw data */
+	SWITCH_CLEAN = 6, /** clean AT changes */
+	SWITCH_VERSION = 9, /** display version infromation */
+	SWITCH_HELP = 10, /** show help with syntax examples */
+	SWITCH_DBGHELP_VERSION = 11
+};
+
+/**
+* Enumeration used when hooking project.
+*/
+enum HOOK_SWITCH
+{
+	HOOK_UNKNOWN = 0, /** not defined */
+	HOOK_INTERNAL, /** monitored internal data gathering */
+	HOOK_EXTERNAL, /** monitored external data gathering */
+	HOOK_EXTERNAL_FAST, /** external data gathering */
+	HOOK_EXTENSION_INTERNAL, /** Extension call, monitored internal data gathering */
+	HOOK_EXTENSION_EXTERNAL, /** Extension call, monitored external data gathering */
+	HOOK_EXTENSION_EXTERNAL_FAST, /** Extension call, external data gathering */
+	HOOK_EXTENSION_UNINSTRUMENT, /** Extension call, uninstrument (post-build)*/
+	HOOK_EXTENSION_FAILED, /** Extension call, build failed, cleanup */
+	HOOK_OLD_EXTENSION_INSTRUMENT, /** Old extension call, instrument project */
+	HOOK_OLD_EXTENSION_UNINSTRUMENT, /** Old extension call, uninstrument project */
+	HOOK_OLD_EXTENSION_FAILED /** Old extension call, cleanup */
+};
+
+/**
+* Represents hooking parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_HOOK
+{
+	bool bNoBuild; /** Only intrument project? (no build) */ 
+	bool bDataFileName; /** Is internal data gathering filename defined */
+	bool bAbldTest; /** Is build only for test modules (abld test build.. */
+	string sDataFileName; /** Internal data gathering filename */
+	int iBuildSystem; /** 1 = sbs, 2 = raptor */
+	int iLoggingMode; /** Just for old parameter parsing. 1=trace, 2=file, 0=? */
+	int iAllocCallStackSize; /** Call stack size when memory allocated */
+	int iFreeCallStackSize; /** Call stack size when memory freed */
+	string sBuildCmd; /** Original build command / user defined or given */
+	vector<string> vBuildCmd; /** Build command split in vector */
+	string sPlatform; /** Build platform */
+	string sBuildType; /** Build type (udeb/urel) */
+	string sFeatureVariant; /** Build variant defined */
+	vector<string> vTargetPrograms; /** User defined single or multiple modules from project? */
+	/**
+	* Default constructor to set default values.
+	*/
+	ARGUMENTS_HOOK()
+	{
+		bNoBuild = false;
+		bAbldTest = false;
+		bDataFileName = false;
+		sDataFileName = "";
+		iBuildSystem = 0;
+		iLoggingMode = 0;
+		iAllocCallStackSize = AT_ALLOC_CALL_STACK_SIZE_DEFAULT;
+		iFreeCallStackSize = AT_FREE_CALL_STACK_SIZE_DEFAULT;
+		sBuildCmd = "";
+		sPlatform = "";
+		sBuildType = "";
+		sFeatureVariant = "";
+		vTargetPrograms.clear();
+	};
+};
+
+/**
+* Represents analyze parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_ANALYZE
+{
+	string sDataFile; /** Data file to be analyzed */
+	string sOutputFile; /** Output file */
+	bool bSymbolFile; /** Is rom/rofs symbol file(s) defined? */
+	vector<string> vSymbolFiles; /** Collection of symbol files */
+	int iLoggingLevel; /** Logging level of report */
+	/**
+	* Default constructor to set default values.
+	*/
+	ARGUMENTS_ANALYZE()
+	{
+		sDataFile = "";
+		sOutputFile = "";
+		bSymbolFile = false;
+		iLoggingLevel = 3;
+	};
+};
+
+/**
+* Represents raw trace parsing parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_PARSE
+{
+	bool bDataFile; /** Is raw data file defined */
+	string sDataFile; /** Raw data file (input) */
+	bool bOutputFile; /** Is output file defined */
+	string sOutputFile; /** Output (AT specific data file)*/
+	/**
+	* Default constructor to set default values.
+	*/
+	ARGUMENTS_PARSE()
+	{
+		bDataFile = false;
+		sDataFile = "";
+		bOutputFile = false;
+		sOutputFile = "";
+	};
+};
+
+
+/**
+* Represents main parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS
+{
+	// Base arguments.
+	MAIN_SWITCH eMainSwitch; /** mandatory/main parameter */
+	HOOK_SWITCH eHookSwitch; /** if compile/instrument its "mode" */
+	bool bHelp; /** show help? */
+	bool bDebugConsole; /** enable debug logging to console? */
+	bool bDebugDbgView; /** enable debug logging to win api? */
+	bool bDebugLowLevel; /** enable debug logging for also low level functions? */
+	bool bEnableSbs2; /** use raptor as build system? */
+	ARGUMENTS_HOOK HOOK; /** hooking/instrument/compiling attributes */
+	ARGUMENTS_ANALYZE ANALYZE; /** analyze related attributes */
+	ARGUMENTS_PARSE PARSE; /** parsing related attributes */
+	/**
+	* Default constructor to set default values.
+	*/
+	ARGUMENTS()
+	{
+		eMainSwitch = SWITCH_UNKNOWN;
+		eHookSwitch = HOOK_UNKNOWN;
+		bHelp = false;
+		bDebugConsole = false;
+		bDebugDbgView = false;
+		bEnableSbs2 = false;
+	};
+};
+
+// DEBUG MACROS
+// constant string for all beginning of all debug messages
+const char START_LOG_MESSAGE[] = "*** CLE ";
+// Log normal function entry (AAA = class::function )
+#define LOG_FUNC_ENTRY( AAA ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << "ENTRY: " << AAA << endl; OutputDebugString( strs.str().c_str() );  } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << "ENTRY: " << AAA << endl; cout << strs.str();  } }
+// Log normal function exit
+#define LOG_FUNC_EXIT( AAA ){ if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << "EXIT: " << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << "EXIT: " << AAA << endl; cout << strs.str(); } }
+// Log low level function entry
+#define LOG_LOW_FUNC_ENTRY( AAA ) { if ( g_bDebugLowLevel ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } } }
+// Log low level function exit
+#define LOG_LOW_FUNC_EXIT( AAA ) {  if ( g_bDebugLowLevel ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } } }
+// Log stringstream (string, int, etc..) i.e. string1 << int1 << "log this"
+#define LOG_STRING( AAA ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } }
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATBase.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,418 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATBase "utility" class.
+*
+*/
+
+#ifndef __CATBASE_H__
+#define __CATBASE_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* This class implements lot of utility type of functions used all around atool project.
+* All functions are static so they can be used without inheritance of this class. But still
+* this is a base class of almost all others.
+*/
+class CATBase
+{
+public:
+	
+	/**
+	* Constructor
+	*/
+	CATBase();
+
+	/**
+	* Destructor
+	*/
+	virtual ~CATBase(void);
+
+public:
+	
+	/**
+	* FilterExtraSpaces
+	* Filters/replaces multiple continuous spaces with single. Won't leave
+	* spaces in start or end of string.
+	* @param sString to filter.
+	* @return void.
+	*/
+	static void FilterExtraSpaces( string& sString );
+
+	/**
+	* Convert hex value in string to signed decimal.
+	* @param sHex
+	* @param iDec
+	* @return true if successful
+	*/
+	static bool hexToDec( string& sHex, int& iDec );
+
+	/**
+	* Convert hex value in string to unsigned decimal
+	* @param sHex
+	* @param iDec
+	* @return true if successful
+	*/
+	static bool hexToDec( string& sHex, unsigned int& iDec );
+
+	/**
+	* Convert hex value in string to unsigned long.
+	* @param sHex
+	* @param ulDec
+	* @return true if successful
+	*/
+	static bool hexToDec( string& sHex, unsigned long& ulDec );
+
+	/**
+	* Convert hex value in string to unsigned long long.
+	* @param sHex
+	* @param ullDec
+	* @return true if successful
+	*/
+	static bool hexToDec( string& sHex, unsigned long long& ullDec );
+
+	/**
+	* Convert hex value to integer
+	* @param value
+	* @return unsigned long
+	*/
+	static unsigned long _httoi(const TCHAR *value);
+
+	/**
+	* Convert integer to hex string.
+	* @param i
+	* @return hex string
+	*/
+	static string NumberToHexString( unsigned int i );
+
+	/**
+	* Convert long to hex string.
+	* @param i
+	* @return hex string
+	*/
+	static string NumberToHexString( unsigned long i );
+
+	/**
+	* Helper function checks is given character hex.
+	* @param value value to check.
+	* @return true if value is hex char.
+	*/
+	static bool IsHexCharacter(const TCHAR *value);
+
+	/**
+	* Parse string to vector of strings using
+	* separator. (Tokenizer with delimeter).
+	* @param sInput string to split
+	* @char separator
+	* return vector<string>
+	*/
+	static vector<string> ParseStringToVector( const string& sInput, char separator );
+
+	/**
+	* Remove spaces and tabulatures from beginning and
+	* end of given string.
+	* @param sInput String to trim.
+	*/
+	static void TrimString( string& sInput );
+
+	/**
+	* Searches files with given extension from path.
+	* @param pPathAndExt path with extension
+	* @return string filename
+	*/
+	static string GetFileNameUsingExt( const char* pPathAndExt );
+
+	/**
+	* Changes all BackSlash characters to Slash character from string.
+	* @param sInput String including backslashes.
+	* @return String without backslashes.
+	*/
+	static string ChangeSlashToBackSlash( string sInput );
+
+	/**
+	* Changes given string to uppercase
+	* @param sInput
+	*/
+	static void ChangeToUpper( string& sInput );
+
+	/**
+	* Converts any uppercase letter to lowercase.
+	*
+	* @param sInput Reference to string.
+	*/
+	static void ChangeToLower( string& sInput );
+
+	/**
+	* Filter string out of unwanted characters. The list of allowed
+	* characters is defined in CFILTERSTRING.
+	* @param sString string to filter.
+	* @return filtered string.
+	*/
+	static string FilterString( const string& sString );
+
+	/**
+	* Removes path and extension from given filename string
+	* @param sFileName
+	* @param bReverseFindExt if true extension will be looked starting from end
+	* @return string
+	*/
+	static string RemovePathAndExt( string sFileName, bool bReverseFindExt = false );
+
+	/**
+	* Check if given file exists.
+	* @param pFilename Pointer to file name.
+	* @return False If file does not exists.
+	*/
+	static bool FileExists( const char* pFilename );
+
+	/**
+	* Check if given file is flagged read only.
+	* @param pFileName pointer to file name
+	* @return true if read only flag set.
+	*/
+	static bool IsFileReadOnly( const char* pFileName );
+
+	/**
+	* Set file read only.
+	* @param pFileName Pointer to file name
+	* @return true if successful.
+	*/
+	static bool SetFileReadOnly( const char* pFileName );
+
+	/**
+	* Set file writable (remove read only flag).
+	*
+	* @param pFilename Pointer to file name.
+	* @return true if successful.
+	*/
+	static bool SetFileWritable( const char* pFileName );
+
+	/**
+	* Copy file to given path
+	* @param sFile
+	* @param sToPath
+	* @return true if successful
+	*/
+	static bool FileCopyToPath(const string& sFile, const string& sToPath);
+
+	/**
+	* Move file to given path
+	* @param sFile File to be moved
+	* @param sToPath path where to move file
+	* @return true if successful
+	*/
+	static bool FileMoveToPath(const string& sFile, const string& sToPath);
+
+	/**
+	* Delete file
+	* Note! if file does not exists no error message is displayed
+	* but function returns false
+	* @param sFile File to be deleted
+	* @param bPrint display messages or not, default true
+	* @return true if successful
+	*/
+	static bool FileDelete(const string& sFile, bool bPrint = true );
+    
+	/**
+	* Delete dir
+	* Note! if dir does not exists no error message is displayed
+	* but function returns false.
+	* This function wont delete directory if string does not contain
+	* AT_TEMP...
+	* @param sDir Directory to be deleted
+	* @param bPrint display message or not, default true
+	* @return true if successful
+	*/
+	static bool DirDelete(const string& sDir, bool bPrint = true );
+
+	/**
+	* Create dir
+	* Note! if dir cannot be created no error message is displayed
+	* but function returns false.
+	* @param sDir Directory to be deleted
+	* @param pPrint display message or not, default true
+	* @return true if successful
+	*/
+	static bool DirCreate(const string& sDir, bool pPrint = true );
+
+	/**
+	* Create temp path string for given
+	* mmpfile (full path+mmpname)
+	* @param sMmpFileWithPath
+	* @return string containing full path to
+	* AnalyzeTool temporary directory
+	*/
+	static string CreateTempPath(const string& sMmpFileWithPath);
+
+	/**
+	* Search files with extensions from given path.
+	* @param pPathAndExt path with extension definition
+	* @param bPrintErrors do print errors?
+	* @param sErrorLog errors
+	* @return true if found.
+	*/
+	static bool SearchFileWithExtension( const char* pPathAndExt, bool bPrintErrors, string& sErrorLog );
+
+	/**
+	* Helper function to parse filename or path from given string
+	* @param bFileName if true returns filename otherwise the path
+	* @param sInput string where to get path or filename
+	* @return string filename or path
+	*/
+	static string GetPathOrFileName( bool bFileName, string sInput );
+
+	/**
+	* Function returns string from begin of given string until next space,
+	* characters until next space are removed from sInput string.
+	*
+	* @param sInput Line where data is separated with spaces.
+	* @param bEraseFromInput If true characters before space will be removed.
+	* @return string String until next space.
+	*/
+	static string GetStringUntilNextSpace( string& sInput, bool bEraseFromInput = true );
+
+	/**
+	* Convert unix path to windows
+	* @param sPath
+	*/
+	static void ConvertUnixPathToWin( string& sPath );
+
+	/**
+	* Create Temporary AT Cpp file
+	* @param sId unique id to add in file name
+	* @param sPath where to create
+	* @param sS60FileName of the logging file
+	* @param iLogOption logging mode
+	* @param iIsDebug build type
+	* @param iAllocCallStackSize
+	* @param iFreeCallStackSize
+	* @return true if successful
+	*/
+	static bool CreateTemporaryCpp( const string& sId
+								 ,const string& sPath
+								 ,const string& sS60FileName
+								 ,int iLogOption
+								 ,int iIsDebug
+								 ,int iAllocCallStackSize
+								 ,int iFreeCallStackSize );
+	/**
+	* Acquire a list of files in given directory
+	* @param sDirectory can end to \ or x but not to *
+	* @param bListDirs if true directories will be listed as well, default false
+	* @param bAddPathToFile if true given sDirectory path is added to file string, default false
+	* @return vector<string> list of files in folder
+	*/
+	static vector<string> DirList(const string& sDirectory, bool bListDirs = false, bool bAddPathToFile = false);
+
+	/**
+	* Get extension from given "file" string
+	* returns string after last . if any otherwise returns same
+	* what was given
+	* @param sString 
+	* @return string string after last '.' if no '.' returns given string
+	*/
+	static string GetExtension(const string& sString);
+
+	/**
+	* Convert TCHAR pointer to string
+	* @param charArray to convert
+	* @return string
+	*/
+	static string ConvertTCHARtoString(TCHAR* charArray);
+
+	/**
+	* if given string contains two dots '.' this will remove
+	* all characters after first '.'
+	*/
+	static void RemoveAllAfterDotIfTwoDots(string& sString);
+
+	/**
+	* checks given file is it data file
+	* @param sFile
+	* @return true if it is datafile
+	*/
+	static bool IsDataFile( string sFile );
+
+	/**
+	* Parses a path string containing ".." to a valid
+	* path without relations. If given string does
+	* not contain relations it will not be changed
+	* @param sPathString
+	* @return void
+	*/
+	static void ParseRelativePathString(string& sPathString);
+
+	/**
+	* Remove relative path ".." from string
+	* @param sString string to remove from
+	* @param iDots index of ".."
+	* @return void
+	*/
+	static void RemoveRelativePath(string& sString, size_t iDots);
+
+	/**
+	* Check if given directory exists.
+	*
+	* @param pDirname Pointer to directory name.
+	* @return False If directory does not exists.
+	*/	
+	static bool DirectoryExists( const char* pDirname );
+
+	/**
+	* Checks from constant array is this targettype
+	* unsupported by AT
+	* @param sTargetType type to check
+	* @return true if it is supported by atool
+	*/
+	static bool IsTargetTypeSupported(string sTargetType);
+
+	/**
+	* Checks from constant array is this targettype
+	* kernel side.
+	* @param sTargetType type to check
+	* @return true if it is kernel type
+	*/
+	static bool IsTargetTypeKernelSide(string sTargetType);
+
+	/**
+	* Check is given variant defined in environment.(SBS v.1)
+	* @param sEpocroot
+	* @param sVariantName
+	* @return true if it is.
+	*/
+	static bool CheckVariant( const string& sEpocroot, const string& sVariantName );
+
+	/**
+	* Check has the environment defined "DEFAULT" variant
+	* @param sEpocRoot
+	* @return true if it is
+	*/
+	static  bool IsDefaultVariant( const string& sEpocRoot );
+
+	/**
+	* Check is all character ascii
+	* @param pInput pointer to characters
+	* @param iLength length of the string
+	* @return true if all character are ascii
+	*/
+	static bool IsAscii( const char* pInput, const unsigned int iLength );
+
+	/**
+	* Get current environments epocroot.
+	* @param sEpocRoot value is stored in this if successful.
+	* @return true if successful.
+	*/
+	static bool GetEpocRoot( string& sEpocRoot );
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATDatParser.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATDatParser class and its used enumerations.
+*
+*/
+
+
+#ifndef __CATDatParser_H__
+#define __CATDatParser_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+#include "CATDataSaver.h"
+
+// Forward declarations.
+class CATModule2;
+class CATMemoryAddress;
+class CATRomSymbol;
+
+/**
+* Provides the analyze feature for AnalyzeTool specific data file.
+* Is used by CATProject. Uses CATModule2 and/or CATRomSymbol to locate symbols or
+* codelines of memory addressses. Uses CATDataSaver to create report.
+*/
+class CATDatParser : public CATBase
+{
+
+public:
+	/**
+	* enumeration representing the "mode" depending on build system
+	*/
+	enum ANALYZE_MODE
+	{
+		SBS_1 = 0,
+		SBS_2 = 1
+	};
+	/**
+	* Representing current process state
+	*/
+	enum PROCESS_STATE
+	{
+		not_started = 0,
+		ongoing = 1,
+		stopped = 2
+	};
+
+	/**
+	* Constructor.
+	*/
+	CATDatParser();
+
+#ifndef MODULE_TEST
+private:
+#endif
+	/**
+	* Real constructor.
+	*/
+	void Construct();
+	
+	/**
+	* Prevent copy
+	*/
+	CATDatParser& operator =( const CATDatParser& /*other*/ ) { }
+	CATDatParser( const CATDatParser& /*other*/ ) { }
+	
+public:
+	/**
+	* Constructor for SBS2
+	* @param pModules pointer to vector containing project modules
+	*/
+	CATDatParser( vector<CATModule2*>* pModules );
+
+	/**
+	* Destructor
+	*/
+	~CATDatParser();
+
+	/**
+	* Set offset to be used with mapfiles
+	* @param iOffSet
+	*/
+	void SetOffSet( int iOffSet );
+
+	/**
+	* Get offset value
+	* @return int
+	*/
+	int GetOffSet( ) const;
+	
+	/**
+	* Analyze data file set
+	* This method includes try/catch in parsing
+	* @return int error codes specified in CATProject (0=OK)
+	*/
+	int Analyze();
+
+	/**
+	* Set log level
+	* @param iLogLevel
+	*/
+	void SetLogLevel(int iLogLevel);
+	/**
+	* Get Log level
+	* @return int
+	*/
+	int GetLogLevel() const ;
+
+	/**
+	* Set data file to be analyzed
+	* @param sInputFile
+	*/
+	void SetInputFile(const string& sInputFile);
+
+	/**
+	* Set output file
+	* @param sOutputFile
+	*/
+	void SetOutputFile(const string& sOutputFile);
+
+	/**
+	* Set rom symbol file(s).
+	* @param sRomSymbolFile
+	*/
+	void SetRomSymbolFiles(const vector<string>& vRomSymbolFile);
+
+	/**
+	* Set print flag
+	* @param pPringFlag
+	*/
+	void SetPringFlag( bool bPrintFlag );
+
+	/**
+	* Set addr2line.exe pinpoint state
+	* @param bInput
+	*/
+	void SetAddr2lineExeState( bool bInput );
+
+	/**
+	* Set project platform.
+	* @param sPlatform platform.
+	*/
+	void SetProjectPlatform( const string& sPlatform );
+
+	/**
+	* Set projects build type. Use enumeration defined in CATProject.
+	* @param eBuildType.
+	*/
+	void SetProjectBuildType( int eBuildType );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	/**
+	* Start parsing datafile
+	* @return error codes defined in CATProject
+	*/
+	int Parse();
+	
+	/**
+	* Helper functio to print header of report
+	*/
+	void Header();
+
+	/**
+	* Helper functio to print footer of report
+	*/
+	void Footer();
+
+	/**
+	* Helper function reseting/clearing all
+	* member variables related to parsing
+	*/
+	void ClearParsingVariables();
+
+	// Helpers for data file tags
+	bool ParseProcessStart( string& sLine );
+	bool ParseDllLoad( string& sLine );
+	bool ParseDllUnload( string& sLine );
+	bool ParseMemLeak( string& sLine );
+	bool ParseProcessEnd( string& sLine );
+	bool ParseHandleLeak( string& sLine );
+	bool ParseTestStart( string& sLine );
+	bool ParseTestEnd( string& sLine );
+	bool ParseLoggingCancelled( string& sLine );
+	bool ParseErrorOccured( string& sLine );
+
+	void PrintMemLeak(const string& sTime,
+					   const string& sLeakSize,
+					   const string& sLeakAddr,
+					   const string& sModuleName);
+
+	// Utilities
+	string ConvertTimeToLocalTime( string sInputTime );
+
+	/**
+	* Create a winscw module into pModules vector.
+	* Used when we have dll load of module not in project to create them
+	* after this they are used in locating code lines.
+	* @param sBinaryName name of the binary with extension.
+	* @return true if successful.
+	*/
+	bool CreateWinscwModule( const string& sBinaryName );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	void CleanMemoryAddresses();
+
+	// Members
+	unsigned int m_iDataVersion; // Version of data file.
+	int m_eProcess_state; // is process started, etc..
+	bool m_bProcessStartFound;
+	bool m_bDllLoadFound;
+	int m_iLogLevel; // specified logging level
+	string m_sInputFile; // input file
+	vector<string> m_vRomSymbolFiles; // Rom symbol file.
+	string m_sOutputFile; // output file
+	string m_sInputFileTemp; // temporary input file (parsed from trace)
+	ifstream m_In; // Handle to input file
+	// Datasaver
+	CATDataSaver m_DataSaver;
+
+	// Modules to be used in pinpointing
+	vector<CATModule2*>* m_pModules;
+
+	// Rom symbol file.
+	CATRomSymbol* m_pRomSymbol;
+
+	// Build type from dat.
+	int m_eBuildType;
+	// Build type from project.
+	int m_eProjectBuildType;
+	// Offset of map file.
+	int m_iOffSet;
+	// Platform of project.
+	string m_sProjectPlatform;
+
+	// Process related
+	unsigned long m_iCurrentProcessId;
+	string m_sCurrentProcessName;
+	int m_iTotalRuns;
+	int m_iSuccesfullRuns;
+	
+	// Leak counting related
+	int m_iTotalNumberOfLeaks;
+	bool m_bSubtestOnGoing;
+	int m_iPinPointedLeaks;
+	int m_iPinPointedSubTestLeaks;
+	int m_iLeakNumber;
+	
+	// Handle count related
+	int m_iSubtestStartHandleCount;
+	vector<string> m_vHandleLeaks;
+
+	// Module related
+	vector<DLL_LOAD_INFO> m_vDllLoadModList;
+	vector<DLL_LOAD_INFO> m_vDllLoadModListSubTest;
+	
+	// Sbs 1 support functions
+	int FindModuleUsingAddress( unsigned long iAddress ) const;
+	//int FindModuleUsingPID( unsigned long iPID ) const;
+	int FindModuleUsingName( const char* pModName );
+
+	// Memory addresses
+	vector<CATMemoryAddress*> m_vMemoryAddress;
+
+};
+#endif
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATDataSaver.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,214 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATDataSaver class and element type enumeration.
+*
+*/
+
+
+#ifndef __CATDATASAVER_H__
+#define __CATDATASAVER_H__
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/framework/LocalFileFormatTarget.hpp>
+#include "ATCommonDefines.h"
+
+/**
+* Represents element types
+*/
+enum element_types
+{
+	RESULT = 0,
+	RUN,
+	LEAK,
+	CALLSTACK,
+	ITEM,
+	RUN_END,
+	ERROR_IN_RUN,
+	MEM_LEAKS,
+	MEM_LEAK_MODULE,
+	HANDLE_LEAKS,
+	HANDLE_LEAK_MODULE,
+	TEST_START,
+	TEST_END,
+	SUBTEST_MEM_LEAKS,
+	SUBTEST_MEM_LEAK_MODULE,
+	LOGGING_CANCELLED,
+	SUBTEST_HANDLE_LEAKS
+};
+
+//#define CARBIDE_DATA 0
+#define XML_DATA     1
+#define TEXT_DATA    2
+
+/**
+* TProvides features for creating the analyze report in
+* basic text or XML formats. Uses xerces library for XML output.
+*/
+class CATDataSaver
+{
+
+public:
+
+	/**
+	* Constructor.
+	*/
+	CATDataSaver( void );
+
+	/**
+	* Destructor.
+	*/
+	~CATDataSaver(void);
+
+	/**
+	* Save all lines to file with given format.
+	* @param pFileName Pointer to file name.
+	* @param iDataToSave Format of data.
+	*/
+	void SaveLinesToFile( const char* pFileName, int iDataToSave );
+
+	/**
+	* Prints all saved lines to screen.
+	*/
+	void PrintLinesToScreen( void );
+
+	/**
+	* Adds saved line to first in database.
+	*/
+	void AddLineToFirst( void );
+
+	/**
+	* Adds saved line to last in database.
+	*/
+	void AddLineToLast();
+
+	/**
+	* Adds string to current line.
+	* @param pData string to add
+	* @param bSaveCarbideData add string to xml?
+	*/
+	void AddString( const char* pData, bool bSaveCarbideData = false );
+
+	/**
+	* Converts integer to string and adds it to current line.
+	* @param iValue integer value to add
+	* @param bSaveCarbideData add string to xml?
+	*/
+	void AddInteger( int iValue, bool bSaveCarbideData = false );
+
+	/**
+	* Sets logging level.
+	* If value is invalid DEFAULT_LOGGING_LEVEL is used
+	* value must be between MIN_LOGGING_LEVEL and MAX_LOGGING_LEVEL
+	* @param iLoggingLevel Logging level.
+	*/
+	void SetLoggingLevel( int iLoggingLevel );
+
+	/**
+	* Gets logging level.
+	* @return Logging level.
+	*/
+	int GetLoggingLevel( void );
+
+	/**
+	* Sets print immediately flag.
+	* @param bPrintImmediately
+	*/
+	void SetPrintFlag( bool bPrintImmediately );
+
+	/**
+	* Sets data header for carbide data.
+	*/
+	void SaveCarbideDataHeader( void );
+
+	/**
+	* Initializes xercer xml parser.
+	*/
+	bool InitXML( void );
+
+	/**
+	* Writes data to xml tree.
+	* @param sInput data 
+	* @param iElementType element to write
+	*/
+	void SaveXML( string sInput, int iElementType );
+
+	/**
+	* Converts char* -> wchar_t*.
+	* @param str
+	* @return LPWSTR
+	*/
+	static LPWSTR CharToWChar( const char* str );
+
+	/**
+	* Converts wchar_t* -> char*.
+	* @param sInput
+	* @param Source
+	*/
+	static void WCharToChar( string& sInput, const WCHAR* Source );
+
+	/**
+	* Set is build type debug?
+	* @param bUdebBuild true if build type debug
+	*/
+	void SetBuild( bool bUdebBuild );
+
+	/**
+	* Add xml data for extension
+	* @param sInput data
+	*/
+	void AddCarbideData( const string& sInput );
+
+	/**
+	* Convert given integer to string
+	* @param iValueToConvert
+	* @return string
+	*/
+	static string IntegerToString( int iValueToConvert );
+
+#ifndef MODULE_TEST
+private:
+#endif
+	vector<string> m_vLines;
+	string m_sLine;
+	string m_sCarbideDataLine;
+
+	string m_sCarbideDataHeader;
+
+	int m_iLoggingLevel;
+	int m_iRunNumber;
+	bool m_bPrintImmediately;
+	bool m_bXMLInitOk;
+	bool m_bUdebBuild;
+
+	xercesc::DOMDocument* m_pDomDoc;
+	xercesc::DOMElement* m_pRootElem;
+	xercesc::DOMElement* m_pCurrentLeakElem;
+	xercesc::DOMWriter* m_Serializer;
+	xercesc::DOMElement* m_pRunElement;
+	xercesc::DOMElement* m_pMemoryLeaks;
+	xercesc::DOMElement* m_pHandleLeaks;
+	xercesc::DOMElement* m_pCurrentSubTestElem;
+	xercesc::DOMElement* m_pSubtestMemoryLeaks;
+
+	/**
+	* Utility to get sub string from string using char as separator
+	* @param sInput
+	* @param cCharacter
+	* @return string
+	*/
+	string GetStringUntilNextGivenChar( string& sInput, char cCharacter );
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATMemoryAddress.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines the CATMemoryAddress class.
+*
+*/
+
+
+#ifndef __CATMEMORYADDRESS_H__
+#define __CATMEMORYADDRESS_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* Represents a single memory address / call stack item.
+* State tells the "success" of locating the symbol / code line.
+* Contains some utility functions used in this feature.
+*/
+class CATMemoryAddress
+{
+public:
+	/**
+	* Enumeration representing the state of locating code lines.
+	*/
+	enum ADDRESS_TO_LINE_STATE
+	{
+		OUT_OF_PROCESS = 0, /** Not located code line.*/
+		OUT_OF_RANGE, /** Outside functions range. */
+		SYMBOL, /** Symbol/ Function located (no codeline) */
+		FUNCTION, /** Function and line number.*/
+		EXACT /** Exact code line located with all information.*/
+	};
+	/**
+	* Constructor
+	* @param sAddress
+	* @param iOffSet value used if need to use offset value
+	*/
+	CATMemoryAddress( string& sAddress, unsigned long iOffSet );
+	/**
+	* Destructor
+	*/
+	virtual ~CATMemoryAddress();
+	/**
+	* Find which binary this address belongs to.
+	* Sets also the offsetfrommodulestart.
+	* @param vDlls container of binarys to find from.
+	* @return true if found
+	*/
+	bool FindSetModuleName(vector<DLL_LOAD_INFO>* vDlls);
+	/**
+	* Get vector index to which module we found this address to belong to.
+	* @return -1 if not set.
+	*/
+	int GetDllLoadInfoIndex();
+	/**
+	* Note return value includes the set offset.
+	* So this value is not binary start - address.
+	* Instead it is.
+	* memory address - binary start address + offset
+	* @return adress
+	*/
+	unsigned long GetOffSetFromModuleStart();
+	/**
+	* Get the binary start address
+	* @return binary start address
+	*/
+	unsigned long GetModuleStartAddress() const;
+	/**
+	* Set time
+	* @param ullTime
+	*/
+	void SetTime( unsigned long long& ullTime );
+	/**
+	* Get time
+	* @return unsigned long long
+	*/
+	unsigned long long GetTime();
+	/**
+	* Set address
+	* @param sAddess
+	*/
+	void SetAddress( string& sAddress );
+	/**
+	* Get address string
+	* @return string
+	*/
+	string GetAddressString();
+	/**
+	* Set address
+	* @param iAddress
+	*/
+	void SetAddress( unsigned long iAddress );
+	/**
+	* Get Address
+	* @return unsigned long
+	*/
+	unsigned long GetAddress();
+	/**
+	* Set module name
+	* @param sModuleName
+	*/
+	void SetModuleName( string& sModuleName );
+	/**
+	* Get module name
+	* @return string
+	*/
+	string GetModuleName();
+	/**
+	* Set state of locating code line
+	* @param eState
+	*/
+	void SetAddressToLineState( ADDRESS_TO_LINE_STATE eState );
+	/**
+	* Get current state of locating code line
+	* @return int
+	*/
+	int GetAddressToLineState();
+	/**
+	* Set filename
+	* @param sFileName
+	*/
+	void SetFileName(string& sFileName);
+	/**
+	* Get filename
+	* @return string
+	*/
+	string GetFileName();
+	/**
+	* Set function name
+	* @param sFunctionName
+	*/
+	void SetFunctionName(string& sFunctionName);
+	/**
+	* Get function name
+	* @return string
+	*/
+	string GetFunctionName();
+	/**
+	* Set function line number
+	* @param iFunctionLineNumber
+	*/
+	void SetFunctionLineNumber(int iFunctionLineNumber);
+	/**
+	* Get function line number
+	* @return int
+	*/
+	int GetFunctionLineNumber();
+	/**
+	* Set exact line number
+	* @param iExactLineNumber
+	*/
+	void SetExactLineNumber(int iExactLineNumber);
+	/**
+	* Get exact line number
+	* @return int
+	*/
+	int GetExactLineNumber();
+	/**
+	* Set module start address
+	* @param iAddress
+	*/
+	void SetModuleStartAddress(unsigned long iAddress);
+
+#ifndef MODULE_TEST
+private:
+#endif
+	// Used offset to add to addresses
+	unsigned long m_iOffSet;
+	// Address related members
+	string m_sAddress;
+	unsigned long m_iAddress;
+
+	// Time (microseconds from 1970)
+	unsigned long long m_iTime;
+
+	// Module related members(if FindSetModule is successful)
+	string m_sModuleName;
+	unsigned long m_iOffSetFromModuleStart;
+	unsigned long m_iModuleStartAddress;
+
+	// Module to which address belong.
+	int m_iDllLoadinfoIndex;
+
+	// Pin pointing related members
+	int m_ePinPointState;
+	string m_sFileName;
+	string m_sFunctionName;
+
+	int m_iFunctionLineNumber;
+	int m_iExactLineNumber;
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATMmp.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,106 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class responsible of handling mmp files.
+*
+*/
+
+
+#ifndef __CATMMP_H__
+#define __CATMMP_H__
+
+// Includes
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+
+/**
+* CATMmp represents mmp file of module.
+* All mmp file related actions are done using this class.
+* @author
+*/
+class CATMmp : public CATBase
+{
+
+public:
+
+	// Constructor
+	CATMmp();
+	
+	// Destructor
+	~CATMmp();
+	
+	string m_sMmpFile; /** The mmp file with path */
+
+	/**
+	* Makes AnalyzeTool changes to given mmp file.
+	* @param sTargetType target type of module i.e. exe / dll
+	* @param sId unique identification string added to source file name
+	* @return true if editing was successful.
+	*/
+	bool EditMmpFile(const string& sTargetType, const string& sId);
+
+	/**
+	* Backups mmp file to atool_temp/file
+	* to path/atool_temp/filename.mmp.tmp.
+	* Calling this function results always to 
+	* none edited mmp & none edited backup.
+	* @return true if successful.
+	*/
+	bool BackupMmpFile();
+
+	/**
+	* Restores backup from temporary directory (replacing current).
+	* @return true if successful.
+	*/
+	bool RestoreMmpFile();
+
+	/**
+	* VerifyAndRecover mmp file.
+	* Wont change mmp if it is not edited
+	* Replaces mmp file using backup if it exists and it is
+	* not edited otherwise removes changes from mmp file.
+	* @return true if successful
+	*/
+	bool VerifyAndRecover();
+
+#ifndef MODULE_TEST
+private:
+#endif
+		/**
+	* Checks if the given mmp file is modified by AT
+	* @param bBackup if true checks backup
+	* @return bool true if it is edited
+	*/
+	bool IsMmpEdited(bool bBackup = false );
+
+	/**
+	* CreateBackupPath creates string containinig
+	* full path to backup mmp file
+	*/
+	string CreateMmpBackupPath();
+
+	/**
+	* Removes AnalyzeTool changes from given file
+	* @param bBackup if true removes changes from backup
+	* @return true if successfully removed changes
+	*/
+	bool RemoveMmpFileChanges(bool bBackup = false);
+
+	/**
+	* Removes write protections from mmp file and its backup if exists.
+	* @return true if successful.
+	*/
+	bool RemoveWriteProtections();
+
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATModule2.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,545 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a module in project (sbs2).
+*
+*/
+
+
+#ifndef __CATMODULE2_H__
+#define __CATMODULE2_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+#include "CATMmp.h"
+
+// Forward declarations.
+class CATMemoryAddress;
+class IAddressToLine;
+
+/**
+* CATModule2 represents a module/component (single binary) in project.
+* CATProject contains a collection of these.
+*/
+class CATModule2 : public CATBase
+{
+
+public:
+	/**
+	* Constructor.
+	*/
+	CATModule2(void);
+	
+	/**
+	* Destructor.
+	*/
+	~CATModule2(void);
+	
+	/**
+	* Read modules attributes from SBS v.1 makefile.
+	* Also copies makefile to temporary directory if successful.
+	*/
+	bool ReadMakeFile();
+
+	/**
+	* Read modules attributes from SBS v.1 makefile.
+	* From make file which is in modules temporary directory.
+	*/
+	bool ReadMakeFileFromTemp();
+
+	/**
+	* Add sources using line where source files separated by spaces.
+	* @param sSourceLine.
+	*/
+	void AddSources(string& sSourceLine);
+
+	/**
+	* Add sources by giving source file and its corresponding listing file.
+	* @param sSourceFile
+	* @param sLstFile
+	*/
+	void AddSource(const string& sSourceFile, const string& sLstFile);
+
+	/**
+	* Create AT temporary cpp file for module.
+	* @param sS60FileName.
+	* @param eLoggingMode.
+	* @param eBuildType.
+	* @param iAllocCallStackSize.
+	* @param iFreeCallStackSize.
+	* @return true if successful.
+	*/
+	bool CreateTempCpp(const string& sS60FileName
+		, int eLoggingMode
+		, int eBuildType
+		, int iAllocCallStackSize
+		, int iFreeCallStackSize );
+
+	/**
+	* Add AT changes to modules mmp file.
+	* @return true if successful.
+	*/
+	bool ModifyMmp();
+
+	/**
+	* Restore any changes made to modules mmp file.
+	* @return true if successful.
+	*/
+	bool RestoreMmp();
+
+	/**
+	* Verify tha mmp does not contain AnalyzeTool made changes.
+	* If it does contain them will remove them manually or using backup.
+	* @return true if successful.
+	*/
+	bool VerifyAndRecoverMmp();
+
+	/**
+	* Copy modules releasables to its temporary dir.
+	* This includes map & lst files.
+	* @return true if successful.
+	*/
+	bool CopyReleasables();
+
+	/**
+	* Copy modules listing files to given directory.
+	* After copy they will be deleted.
+	* @param sDir target directory.
+	* @return true if successful.
+	*/
+	bool CopyLstFilesToDir( const string& sDir );
+
+	/**
+	* Delete modules lst files from their source
+	* directories.
+	* @return true if succesfful.
+	*/
+	bool DeleteLstFilesFromSrc();
+
+	/**
+	* Clean modules temporary directory of files,
+	* not defined in UNDELETE list.
+	* @return true if successful
+	*/
+	bool CleanTemporaryDir();
+
+	/**
+	* Delete modules temporary directory.
+	* @return true if successful.
+	*/
+	bool DeleteTemporaryDir();
+
+	/**
+	* Locate codeline of given memory address.
+	* Given address must be calculated to correspond map file addresses.
+	* @param pMemoryAddress object where to store results.
+	* @return true if successful.
+	*/
+	bool AddressToLine(CATMemoryAddress* pMemoryAddress);
+
+	/**
+	* Check does modules symbol file(s) exist.
+	* @return true if it exists.
+	*/
+	bool SymbolFileExist( void );
+
+	/**
+	* Check does modules map file(s) exists.
+	* @return true if it exists.
+	*/
+	bool MapFileExist( void );
+
+	/**
+	* Check does modules binary file(s) exist.
+	* @return true if it exists.
+	*/
+	bool BinaryFileExist( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	/**
+	* Read modules attributes from make file.
+	*/
+	bool ReadMakeFilePrivate();
+
+	/**
+	* Locate codeline of given memory address (winscw platform).
+	* Given address must be calculated to correspond map file addresses.
+	* @param pMemoryAddress object where to store results.
+	* @return true if successful.
+	*/
+	bool AddressToLineWinscw(CATMemoryAddress* pMemoryAddress );
+
+	/**
+	* Locate codeline of given memory address (armv5 platform).
+	* Given address must be calculated to correspond map file addresses.
+	* @param pMemoryAddress object where to store results.
+	* @return true if successful.
+	*/
+	bool AddressToLineArmv5(CATMemoryAddress* pMemoryAddress );
+
+	/**
+	* Locate codeline of given memory address.
+	* Given address must be calculated to correspond map file addresses.
+	* @param pMemoryAddress object where to store results.
+	* @return true if successful.
+	*/
+	bool AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress );
+
+	/**
+	* Search map file data (symbols) using given address.
+	* @param iAddress memory address.
+	* @return index of the symbol or -1 if not found.
+	*/
+	int GetSymbolIndexUsingAddress(unsigned long iAddress) const;
+
+	/**
+	* Search listing  files data using the given symbol name.
+	* @param sSymbolName symbols name to find.
+	* @return index of the found lst data or -1 if not found.
+	*/
+	int GetLineInFileIndexUsingSymbolName(const string& sSymbolName) const;
+	
+	/**
+	* Search the exact code line from given file.
+	* @param sFileName listing file to search from.
+	* @param iLine functions line number.
+	* @param iFromFuncAddress how many bytes from functions start.
+	* @return line number or -1 if not found.
+	*/
+	int FindLeakCodeLine( string& sFileName, int iLine, unsigned long iFromFuncAddress ) const;
+
+public:
+
+	/**
+	* Set used build system (CATProject::BUILD_SYSTEM).
+	* @param eBuildSystem.
+	*/
+	void SetBuildSystem( int eBuildSystem );
+
+	/**
+	* Get defined build system.
+	* @return int CATProject::BUILD_SYSTEM
+	*/
+	int GetBuildSystem( void ) const ;
+
+	/**
+	* Set SBS v.1 makefile.
+	* @param sMakeFile
+	*/
+	void SetMakeFile( const string& sMakeFile );
+	
+	/**
+	* Get SBS v.1 makefile.
+	* @return string makefile.
+	*/
+	string GetMakeFile( void ) const;
+
+	/**
+	* Initialize module ready for locating code lines.
+	* with memory addresses (reads map and listing files).
+	* return true if successful.
+	*/
+	bool InitializeAddressToLine();
+	
+	/**
+	* Set modules mmp file.
+	* This also creates temporary dir if it is missing.
+	* @return true if successful.
+	*/
+	bool SetMmpFile(const string& sMmpFile);
+
+	/**
+	* Create modules own temporary directory.
+	* @return true if successful.
+	*/
+	bool CreateTemporaryDirectory();
+
+	/**
+	* Get modules mmp file.
+	* @return mmp file.
+	*/
+	string GetMmpFile() const;
+
+	/**
+	* Get modules atool_temp directory path.
+	* @return atool_temp directory path.
+	*/
+	string GetTempPath() const;
+
+	/**
+	* Get S60 logging file name.
+	* @return s60 logging file name.
+	*/
+	string GetS60FileName() const;
+
+	/**
+	* Set target binary name.
+	* @param sTarget binary file name.
+	*/
+	void SetTarget(const string& sTarget);
+
+	/**
+	* Get target binary name.
+	* @return modules binary file name.
+	*/
+	string GetTarget() const;
+
+	/**
+	* Set binary target type.
+	* @param sTargetType binary target type.
+	*/
+	void SetTargetType(const string& sTargetType);
+
+	/**
+	* Get binary target type.
+	* @return binary target type.
+	*/
+	string GetTargetType() const;
+
+	/**
+	* Set requested binary target file extension.
+	* @param sRequestedTargetExt binary target file extension.
+	*/
+	void SetRequestedTargetExt( const string& sRequestedTargetExt );
+
+	/**
+	* Get requested binary target file extension.
+	* @return binary target file extension.
+	*/
+	string GetRequestedTargetExt() const;
+
+	/**
+	* Get full name of modules binary.
+	* @return modules binary files full name.
+	*/
+	string GetBinaryName() const;
+
+	/**
+	* Set variant platform.
+	* @param sVariantPlatform variant platform.
+	*/
+	void SetVariantPlatform(const string& sVariantPlatform);
+
+	/**
+	* Get variant platform.
+	* @return variant platform.
+	*/
+	string GetVariantPlatform() const;
+
+	/**
+	* Set variant type.
+	* @param sVariantType variant type.
+	*/
+	void SetVariantType(const string& sVariantType);
+
+	/**
+	* Get variant type.
+	* @return variant type.
+	*/
+	string GetVariantType() const;
+
+	/**
+	* Set feature variant.
+	* @param sFeatureVariant feature variant.
+	*/
+	void SetFeatureVariant(const string& sFeatureVariant);
+
+	/**
+	* Get feature variant.
+	* @return feature variant.
+	*/
+	string GetFeatureVariant() const;
+
+	/**
+	* Set feature variant name.
+	* @param sFeatureVariantName feature variant name.
+	*/
+	void SetFeatureVariantName(const string& sFeatureVariantName);
+
+	/**
+	* Get feature variant name.
+	* @return feature variant name.
+	*/
+	string GetFeatureVariantName() const;
+
+	/**
+	* Set release path.
+	* @param sReleasePath release path.
+	*/
+	void SetReleasePath(const string& sReleasePath);
+
+	/**
+	* Get release path.
+	* @return release path.
+	*/
+	string GetReleasePath() const;
+
+	/**
+	* Set full variant path.
+	* @param sFullVariantPath full variant path.
+	*/
+	void SetFullVariantPath(const string& sFullVariantPath);
+
+	/**
+	* Get full variant path.
+	* @return full variant path.
+	*/
+	string GetFullVariantPath() const;
+
+	/**
+	* Set compile definition(s) of the module.
+	* @param sCompileDefinitions
+	*/
+	void SetCompileDefinitions( const string& sCompileDefinitions );
+
+	/**
+	* Get compile definition(s) of the module.
+	* @return compile definition(s).
+	*/
+	string GetCompileDefinitions() const;
+
+	/**
+	* Is modules target type udeb?
+	* @return true if modules target type is udeb.
+	*/
+	bool IsUDEB() const;
+
+	/**
+	* Is module build successfully?
+	* This includes check of listing and map files from temporary directory.
+	* @return true if module build successfully.
+	*/
+	bool IsMakeSuccessfull();
+
+	/**
+	* Get error string. This includes possible erros what are generated when
+	* IsMakeSuccesfull is called.
+	* @return error string.
+	*/
+	string GetErrors() const;
+
+	/**
+	* Create build complete file to modules temporary directory.
+	* @return true if build complete file created successfully.
+	*/
+	bool CreateBuildCompleteFile( void );
+
+	/**
+	* Read map file (armv5 platform).
+	* @return true if map file read successfully.
+	*/
+	bool ReadMapFileArmv5();
+
+	/**
+	* Set compile info text
+	* @param sCompileInfoText
+	*/
+	void SetCompileInfoText( string sCompileInfoText );
+
+	/**
+	* Get compile info text
+	* @return compile info text
+	*/
+	string GetCompileInfoText() const;
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	/**
+	* Struct for saving source information
+	* sCpp is source file.
+	* sLst sources corresponding lst file.
+	* bStatic true if source information from static library.
+	*/
+	struct SOURCE
+	{
+		bool bStatic;
+		string sCpp;
+		string sLst;
+		SOURCE() : bStatic(false), sCpp(""), sLst("") {}
+	};
+
+	// Build system
+	int m_eBuildSystem;
+	// Sbs v.1 makefile
+	string m_sMakeFile;
+	// Mmp file.
+	CATMmp m_Mmp;
+	// Temporary directory with path.
+	string m_sTempPath;
+	// Target.
+	string m_sTarget;
+	// Target type.
+	string m_sTargetType;
+	// True target extension.
+	string m_sRequestedTargetExt;
+	// Variant platform.
+	string m_sVariantPlatform;
+	// Variant type.
+	string m_sVariantType;
+	// Feature variant.
+	string m_sFeatureVariant;
+	// Feature variant name.
+	string m_sFeatureVariantName;
+	// Release path (releasables).
+	string m_sReleasePath;
+	// Full variant path (path to releasables).
+	string m_sFullVariantPath;
+	// String to store information of compile
+	string m_sCompileInfoText;
+	// String to store possible error messages.
+	string m_sErrors;
+	// Compile definition(s)
+	string m_sCompileDefinitions;
+	// Source files.
+	vector<SOURCE> m_vSources;
+	// Listing data.
+	vector<LINE_IN_FILE> m_vLineInFile;
+	// Modules map data (symbols).
+	vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+	// File logging mode filename.
+	string m_sS60FileName;
+	// Is all data loaded for address to code line functions.
+	bool m_bAddressToLineInitialized;
+	// Read listing files (armv5 platform).
+	bool ReadListingFilesArmv5();
+	// Get listing file name of given source file.
+    string GetLstNameOfSource(string sSource) const;
+	// Copy listing files to temporary directory.
+	bool CopyLstFilesToTemp();
+	// Copy map file to temporary directory.
+	bool CopyMapFileToTemp();
+	// Get full map file name.
+	string GetMapFile() const;
+	// Get full symbol file name.
+	string GetSymbolFile() const;
+	// Get full binary file name.
+	string GetBinaryFile() const;
+	// Helper function to check is platform armv5.
+	bool IsPlatformArmv5() const;
+	// Get "unique" id of module
+	string GetUniqueId() const;
+	// Sbs v.1 variant urel label.
+	string m_sFeatureVariantURELLabel;
+	// Sbs v.1 variant udeb label.
+	string m_sFeatureVariantUDEBLabel;
+	// Object used to get codelines of memory addresses.
+	IAddressToLine* m_pAddressToLine;
+};
+#endif
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATParseTraceFile.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for class CATParseTrace, CProcessData and
+*               CSubTestData.
+*
+*/
+
+
+#ifndef __CATPARSETRACEFILE_H__
+#define __CATPARSETRACEFILE_H__
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATDataSaver.h"
+#include "../inc/CATBase.h"
+#include "../inc/catallocs.h"
+
+/**
+* Parses raw trace data to AnalyzeTool specific data file.
+*/
+class CATParseTraceFile : public CATBase
+{
+public:
+	/**
+	* Constructor
+	*/
+	CATParseTraceFile();
+
+	/**
+	* Main function to start parse.
+	*
+	* @param pFileName A trace file name
+	* @param pOutputFileName Pointer to output file name
+	*/
+	bool StartParse( const char* pFileName, const char* pOutputFileName );
+
+	/**
+	* Get data saver
+	* @return CATDataSaver*
+	*/
+	CATDataSaver* GetDataSaver(void);	
+
+#ifndef MODULE_TEST
+private:
+#endif
+	CATDataSaver m_DataSaver; /** Data saver */
+};
+
+/**
+* Represents data of a single subtest.
+*/
+class CSubTestData : public CATAllocs
+{
+public:
+	// Members
+
+	bool bRunning; /** Is sub test running */
+	vector<string> vData; /** data */
+	string sSubTestName; /** test name */
+	string sStartTime; /** start time */
+	string sEndTime; /** end time */
+	string sSubTestStartHandleCount; /** handle count at start */
+	string sSubTestEndHandleCount; /** handle count at end */
+};
+
+/**
+* Represents data of a single run.
+*/
+class CProcessData : public CATAllocs
+{
+public:
+	// Members
+
+	bool bProcessOnGoing; /** is process on going */
+	int iProcessID; /** process id (pid)*/
+	vector<string> vData; /** data */
+	vector<string> vHandleLeaks; /** handle leak(s) */
+	vector<CSubTestData> vSubTests; /** process sub test(s) */
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATParseXML.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declarations for the class CATParseXML.
+*
+*/
+
+
+#ifndef __CATPARSEXML_H__
+#define __CATPARSEXML_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* CATParseXML is used to parse xml data.
+*/
+class CATParseXML
+{
+public:
+	/**
+	* Constructor
+	*/
+	CATParseXML(void);
+	
+	/**
+    * Destructor
+    */
+	virtual ~CATParseXML(void);
+
+	/**
+	* Find epocroot path in xml file
+	* @param sourcePath Location of the xml file
+	*/
+	string GetEpocRootPathFromXML(const char* sourcePath);
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATProject.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,629 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a project.
+*
+*/
+
+
+#ifndef __CATPROJECT_H__
+#define __CATPROJECT_H__
+
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+
+class CATModule2;
+class CATDatParser;
+
+// Raptor cmd and makefile constants used
+#define RAPTOR_CMD_BASE "sbs -b bld.inf  --makefile=atool_temp/build/make_build --config="
+#define RAPTOR_MAKEFILE "atool_temp\\build\\make_build.default"
+#define RAPTOR_MAKEFILE_LOG " --logfile=atool_temp\\build\\makefile.xml"
+#define RAPTOR_BUILD_LOG " --logfile=atool_temp\\build\\build.xml"
+#define RAPTOR_REALLYCLEAN_LOG " --logfile=atool_temp\\build\\reallyclean.xml"
+#define RAPTOR_BUILD_LOG_NAME "atool_temp\\build\\build.xml"
+#define RAPTOR_LISTING_LOG " --logfile=atool_temp\\build\\listing.xml"
+
+#define RAPTOR_NOBUILD_SWITCH " --nobuild"
+#define RAPTOR_MAKEFILE_SWITCH "--makefile=atool_temp/build/make_build"
+
+
+// Raptor makefile constant variable names
+#define RAPTOR_PROJECT_META "PROJECT_META:="
+#define RAPTOR_SOURCE "SOURCE:="
+#define RAPTOR_TARGET "TARGET:="
+#define RAPTOR_TARGETYPE "TARGETTYPE:="
+#define RAPTOR_REQUESTEDTARGETEXT "REQUESTEDTARGETEXT:="
+#define RAPTOR_VARIANTPLATFORM "VARIANTPLATFORM:="
+#define RAPTOR_VARIANTTYPE "VARIANTTYPE:="
+#define RAPTOR_FEATUREVARIANT "FEATUREVARIANT:="
+#define RAPTOR_FEATUREVARIANTNAME "FEATUREVARIANTNAME:="
+#define RAPTOR_RELEASEPATH "RELEASEPATH:="
+#define RAPTOR_FULLVARIANTPATH "FULLVARIANTPATH:="
+#define RAPTOR_COMPILE_DEFINITIONS "CDEFS:="
+
+// Sbs v.1 makefile constants.
+#define MAKEFILE_SEARCH_STRING "@perl -S checksource.pl"
+#define MMPFILE_SEARCH_STRING "PRJ_MMPFILES MMP"
+#define MMPTESTFILE_SEARCH_STRING "PRJ_TESTMMPFILES MMP"
+#define SOURCE_PATH "SOURCEPATH"
+#define SOURCE_STRING "SOURCE"
+#define TARGET_STRING "TARGET"
+
+/**
+* CATProject represents a project (collection of modules).
+* It has to be set mode in which it operates like
+* compile / analyze and necessary parameters for that.
+* Then call Run method which also returs error codes
+* defined in AT_ERROR_CODES enumeration.
+* @author
+*/
+class CATProject : public CATBase
+{
+public:
+	
+	/**
+	* Enumeration representing used build systems
+	*/
+	enum BUILD_SYSTEM {
+		SBS_V1 = 1,
+		SBS_V2 = 2
+	};
+
+	/**
+	* Enumeration representing the mode project is run.
+	*/
+	enum PROJECT_MODE {
+		COMPILE = 0,
+		INSTRUMENT = 1,
+		UNINSTRUMENT = 2,
+		UNINSTRUMENT_FAILED =3,
+		FAILED = 4,
+		CLEAN = 5,
+		ANALYZE = 6,
+		INSTRUMENT_CONSOLE = 7,
+		UNINSTRUMENT_CONSOLE = 8,
+		FAILED_CONSOLE = 9,
+		NOT_DEFINED = 10
+	};
+
+	/**
+	* Enumeration repserenting the logging mode.
+	*/
+	enum LOGGING_MODE {
+		DEFAULT = 0,
+		FILE = 1,
+		TRACE = 2,
+		TRACE_FAST = 3
+	};
+
+	/**
+	* Enumeration representing build type.
+	*/
+	enum BUILD_TYPE {
+		UREL = 0,
+		UDEB = 1
+	};
+
+public:
+
+	/**
+	* Constructor
+	*/
+	CATProject();
+
+	/**
+	* Destructor
+	*/
+	~CATProject();
+
+	/**
+	* Set arguments.
+	* @param arguments.
+	* @return true if arguments ok.
+	*/
+	bool SetArguments( ARGUMENTS& arguments );
+
+	/**
+	* Set build system to be used with project.
+	* See BUILD_SYSTEM enumeration for available systems.
+	* @param eSystem system.
+	*/
+	void SetBuildSystem( BUILD_SYSTEM eSystem );
+
+	/**
+	* Set mode which to run.
+	* See PROJECT_MODE enumeration for available modes.
+	* @param eMode mode.
+	*/
+	void SetMode(PROJECT_MODE eMode);
+
+	/**
+	* Get project mode.
+	* @return mode of project.
+	*/
+	int GetMode() const;
+
+	/**
+	* Set epocroot.
+	* @param sEpocroot
+	*/
+	void SetEpocRoot( const string& sEpocRoot );
+
+	/**
+	* Set project platform.
+	* @param sPlatform platform.
+	*/
+	void SetPlatform( const string& sPlatform );
+
+	/**
+	* Set variant.
+	* @sVariant variant.
+	*/
+	void SetVariant( const string& sVariant );
+
+	/**
+	* Set logging mode. See LOGGING_MODE enumeration for available modes.
+	* @param eLogginMode logging mode.
+	*/
+	void SetLoggingMode( LOGGING_MODE eLoggingMode);
+
+	/**
+	* Set build type. See BUILD_TYPE enumeration for available types.
+	* @param eType build type.
+	*/
+	void SetBuildType( BUILD_TYPE eType );
+	
+	/**
+	* Set S60 logging filename.
+	* @param sFileName filename.
+	*/
+	void SetS60FileName( const string& sFileName);
+
+	/**
+	* Set target module.
+	* @param sTargetModule target module name.
+	*/
+	void SetTargetModule( const string& sTargetModule );
+
+	/**
+	* Set multiple target modules used in project.
+	* @param vTargetModules target module names.
+	*/
+	void SetTargetModules( const vector<string>& vTargetModules );
+
+	/**
+	* Set Binary target name to create analysis results to.
+	* @param sBinaryTarget binary target name.
+	*/
+	void SetBinaryTarget( const string& sBinaryTarget );
+
+	/**
+	* Set data file to analyze.
+	* @param sDataFile datafile.
+	*/
+	void SetDataFile( const string& sDataFile );
+
+	/**
+	* Set rom symbol file(s) used in analyze.
+	* @param sRomSymbolFile.
+	*/
+	void SetRomSymbolFiles(const vector<string>& vRomSymbolFiles);
+
+	/**
+	* Set the logging level of analysis report.
+	* @param iLogLevel log level.
+	*/
+	void SetLogLevel( int iLogLevel );
+
+	/**
+	* Set the size of allocation call stack to be written in temporary cpp.
+	* @param iAllocCallStackSize
+	*/
+	void SetAllocCallStackSize( int iAllocCallStackSize );
+
+	/**
+	* Set the size of free call stack to be written in temporary cpp.
+	* @param iFreeCallStackSize
+	*/
+	void SetFreeCallStackSize( int iFreeCallStackSize );
+
+	/**
+	* Set the output file name to store analyse report.
+	* @param sDataFileOutput data file name.
+	*/
+	void SetDataFileOutput( const string& sDataFileOutput );
+
+	/**
+	* Set build command used in compile phase.
+	* @param sBuildCommand build command.
+	*/
+	void SetBuildCommand( const string& sBuildCommand );
+
+	/**
+	* Run the set mode.
+	* @return error code.
+	*/
+	int Run();
+
+	/**
+	* Run recovery, used when "instatly" need to recover modules and exit.
+	*/
+	int RunRecoveryAndExit();
+
+	/**
+	* Get build type string.
+	* @param eType type from which to get correponding string.
+	* @return types corresponding string.
+	*/
+	static string GetBuildTypeString( int eType );
+
+	/**
+	* Reads projects configuration file if it exists.
+	* @return false in case the data contains information that project is uninstrumented. Otherwise returns always true.
+	*/
+	bool IsUninstrumented();
+
+#ifndef MODULE_TEST
+private:
+#endif
+	/**
+	* Run compiling in console.
+	* @return error code.
+	*/
+	int RunCompile( void );
+
+	/**
+	* Run cleaning project.
+	* @return error code.
+	*/
+	int RunClean( void );
+
+	/**
+	* Run running analyze.
+	* @return error code.
+	*/
+	int RunAnalyze( void );
+
+	/**
+    * Run instrumenting of project for Carbide extension (pre-build).
+	* @return error code.
+	*/
+	int RunInstrument( void );
+
+	/**
+	* Run uninstrumenting of project for Carbide extension (post-build).
+	* @return error code.
+	*/
+	int RunUninstrument( void );
+
+	/**
+	* Run uninstrumenting of project for Carbide extension(post-build), when build failed.
+	* @return error code.
+	*/
+	int RunUninstrumentFailed( void );
+
+	/**
+	* Run console instrumenting.
+	* @return error code.
+	*/
+	int RunInstrumentConsole( void );
+
+	/**
+	* Run Console uninstrumenting.
+	* @return error code.
+	*/
+	int RunUninstrumentConsole( void );
+
+	/**
+	* Run console uninstrumenting, when build failed.
+	* @return error code.
+	*/
+	int RunFailedConsole( void );
+
+	/**
+	* Show summary of compilation.
+	*/
+	void DisplayCompileSummary( void );
+
+	/**
+	* Show summary, build target, build type, logging mode...
+	*/
+	void DisplayBuildSummary( void );
+
+	/**
+	* Create make files.
+	* @return true if successful
+	*/
+	bool CreateMakeFile( void );
+	/**
+	* Create SBS v.1 make files.
+	* @return true if successful.
+	*/
+	bool CreateMakeFileSbs1( void );
+	/**
+	* Copy sbs1 makefile to temporary folder.
+	* @return true if successful.
+	*/
+	bool CopyMakeFileSbs1ToTemporaryFolder( void );
+	/**
+	* Run really clean in SBS v.1.
+	* @return true if successful.
+	*/
+	bool RunReallyCleanSbs1( void );
+	/**
+	* Run really clean in SBS v.2.
+	* @return true if successful.
+	*/
+	bool RunReallyCleanSbs2( void );
+	/**
+	* Run export in SBS v.1.
+	* @return true if successful.
+	*/
+	bool RunExportSbs1( void );
+	/**
+	* Create make files (level2) SBS v.1.
+	* @return true if successful.
+	*/
+	bool CreateMakeFileSbs1Level2( void );
+	/**
+	* Create makefile SBS v.2.
+	* @return true if successful.
+	*/
+	bool CreateMakeFileSbs2( void );
+	/**
+	* Read makefile.
+	* @return true if successful.
+	*/
+	bool ReadMakeFile( void );
+	/**
+	* Read SBS v.1 makefile.
+	* @return true if successful.
+	*/
+	bool ReadMakeFileSbs1( void );
+	/**
+	* Read SBS v.1 makefile (Level1).
+	* @return true if successful.
+	*/
+	bool ReadMakeFileSbs1Level1( void );
+	/**
+	* Read SBS v.2 makefiles.
+	* @return true if successful.
+	*/
+	bool ReadMakeFileSbs2( void );
+	/**
+	* Read specified SBS v.2 makefile.
+	* @param sMakeFile makefile to be read.
+	* @return true if succesful.
+	*/
+	bool ReadMakeFileSbs2( string& sMakeFile );
+
+	/**
+	* Filter unsupported and static libraries to their own vectors.
+	* Unsupported include kernel types, modules with kernel mode compile definition.
+	* @return true if successful.
+	*/
+	bool FilterModules();
+
+	/**
+	* Creates temporary directories for all modules
+	* in member vector.
+	* @return true if successful.
+	*/
+	bool CreateTemporaryDirectories();
+
+	/**
+	* Creates tempororary cpp files for all modules
+	* in member vector.
+	* @return true if successful.
+	*/
+	bool CreateTemporaryCpps();
+
+	/**
+	* Hooks all modules in member vector
+	* (modifies mmp files)
+	* @return true if successful
+	*/
+	bool ModifyModules( void );
+
+	/**
+	* Unhooks all modules in member vector
+	* (removes changes from mmp files)
+	* @return true if successful
+	*/
+	bool RestoreModules( void );
+
+	/**
+	* Verifys that member vectors modules
+	* mmp files unchanged. Restores if they are
+	* from backup or from original.
+	* @return true if successful
+	*/
+	bool VerifyAndRecoverModules( void );
+
+	/**
+	* Runs compilation.
+	* @return true if successful.
+	*/
+	bool Compile( void );
+	/**
+	* @return true if successful.
+	*/
+	bool CompileSbs1( void );
+	/**
+	* @return true if successful.
+	*/
+	bool CompileSbs2( void );
+
+	/**
+	* Runs listing creatation.
+	* @return true if successful
+	*/
+	bool CreateListings( void );
+	/**
+	* @return true if successful.
+	*/
+	bool CreateListingsSbs1( void );
+	/**
+	* @return true if successful.
+	*/
+	bool CreateListingsSbs2( void );
+	/**
+	* Copies releasables of modules including lst & map files
+	* for all modules in project to their temporary directories.
+	* @return true if successful.
+	*/
+	bool CopyReleasables( void );
+	/**
+	* Deletes all atool_temp directories
+	* of member vector modules.
+	* @return true if successful.
+	*/
+	bool DeleteTemporaryDirs( void );
+	/**
+	* Deletes files from atool_temp directory
+	* of member vector modules which extension not defined
+	* in TEMP_EXTENSION_NO_DELETE table.
+	* @return true if successful.
+	*/
+	bool CleanTemporaryDirs( void );
+	/**
+	* Writes class attributes to a file
+	* under atool_temp directory.
+	* @return true if successful.
+	*/
+	bool WriteAttributes( void ) const;
+	/**
+	* Read class attributes from a file
+	* under atool_temp directory.
+	* @return true if successful.
+	*/
+	bool ReadAttributes( void );
+
+	/**
+	* Creates atool_temp directory if it does not
+	* exist in current directory.
+	* @return true if successful.
+	*/
+	bool MakeTempDirIfNotExist( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	/**
+	* Clean all module vectors.
+	*/
+	void CleanModuleVectors();
+
+	/**
+	* Get build type as string.
+	* @return buildtype string.
+	*/
+	string GetBuildTypeString();
+
+	/**
+	* Helper function to add target module(s)
+	* if any defined in class to given sbs command.
+	* @param sCmd command to add modules to.
+	*/
+	void AddTargetModuleIfDefined(string& sCmd);
+
+	/**
+	* Run given system/abld command to all defined target modules in vector.
+	* Space char (if its missing) will be added to given command + one target
+	* module at a time.
+	* @param sCommand sCommand to run.
+	* @return true if none system call sets error level other than 0.
+	*/
+	bool RunAbldCommandToAllTargets( const string& sCommand );
+
+	/**
+	* Check is target module in project.
+	* If no modules / targets defined return value is true.
+	* @return true if target module is in project.
+	*/
+	bool IsTargetModuleInProject( void ) const;
+
+	/**
+	* Initializes member make file variable with correct full path to point (epoc32/build)...
+	* @return true if successful.
+	*/
+	bool InitSbs1MakeFileWithPath();
+
+	/**
+	* Initializes member make file variable with correct full path to (atoo_temp...)
+	* @return true if successful.
+	*/
+	bool InitSbs1MakeFileWithPathToTemp();
+
+#ifndef MODULE_TEST
+private:
+#endif
+	// System current directory.
+	char m_cCurrentDir[ MAX_LINE_LENGTH ];
+	// Projects build system
+	int m_eBuildSystem;
+	// Project modules.
+	vector<CATModule2*> m_vModules;
+	// Static libraries.
+	vector<CATModule2*> m_vStaticLibraries;
+	// Unsupported project modules.
+	vector<CATModule2*> m_vUnsupportedModules;
+	// Run mode.
+	int m_eMode;
+	// Logging level (used in analyse).
+	int m_iLoggingLevel;
+	// Is project unsinstrumented.
+	bool m_bUninstrumented;
+	// Is build just for test modules
+	bool m_bAbldTest;
+	// Build command.
+	string m_sBuildCommand;
+	// Epocroot
+	string m_sEpocRoot;
+	// Platform i.e. armv5.
+	string m_sPlatform;
+	// SBS2 variant.
+	string m_sVariant;
+	// Logging mode (used in compile,instrumenting).
+	int m_eLoggingMode;
+	// Allocation call stack size
+	int m_iAllocCallStackSize;
+	// Free call stack size
+	int m_iFreeCallStackSize;
+	// Build type udeb / urel.
+	int m_eBuildType;
+	// Sbs v.1 level 1 make file
+	string m_sMakeFile;
+	// User given S60 log file name.
+	string m_sS60FileName;
+	// Target module.
+	string m_sTargetModule;
+	// Target modules (used in carbide instrumenting).
+	vector<string> m_vTargetModules;
+	// Binary target (used in analyse).
+	string m_sBinaryTarget;
+	// User given datafile to analyse.
+	string m_sDataFile;
+	//
+	vector<string> m_vRomSymbolFiles;
+	// Temporary data file name if user gave trace file.
+	string m_sDataFileTemp;
+	// User given output file to store analyse results.
+	string m_sDataFileOutput;
+	// Analyser object.
+	CATDatParser* m_pAnalyzer;
+};
+#endif
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/cataddr2line.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Windows debug api implementation for IAddressToLine interface.
+*
+*/
+
+#ifndef __CATADDR2LINE_H__
+#define __CATADDR2LINE_H__
+
+#include "iaddresstoline.h"
+#include "../inc/cataddr2lineserver.h"
+
+// Allowed characters in output.
+//const char ADDR2LINEALLOWEDCHARS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :/\\_.-";
+
+/**
+* Implements addresstoline interface using one of the GNU binutils tool called addr2line.
+* This is used on gcce platform. In release build type also map files are used.
+*/
+class CATAddr2line : public IAddressToLine
+{
+
+public:
+	
+	/**
+	* Constructor
+	*/
+	CATAddr2line();
+
+	/**
+	* Open binary.
+	* @sString Full filename with path to binary.
+	* @iLong base address of binary.
+	* @return true if successful.
+	*/
+	bool Open( const string& sString, const unsigned long iLong);
+
+	/**
+	* Get error string. In case of any method failed use this to acquire details on error.
+	* @return error string.
+	*/
+	string GetError( void );
+
+	/**
+	* Close binary.
+	* @return true if succesful.
+	*/
+	bool Close( void );
+
+	/**
+	* Locate code line and file for given address.
+	* @result
+	* @return true if successful.
+	*/
+	bool AddressToLine( CATMemoryAddress* result );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	// Modules map data (symbols).
+	vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+
+	//Map file name
+	string m_sMapFileName;
+
+	//Addr2line server class
+	CATAddr2lineServer server;
+
+	/**
+	* Get function name for given address.
+	* @iAddress Memory address as unsigned long.
+	* @return Function name as string or empty string if not found.
+	*/
+	string GetFunctionNameUsingAddress( unsigned long iAddress );
+
+	/**
+	* Read map file (armv5 platform).
+	* @return true if map file read successfully.
+	*/
+	bool ReadMapFileArmv5();
+
+	//Note: New filtering functions commented out until they are taken into use.
+	//These were part of task which would filter unwanted characters, etc.. from results.
+
+	/**
+	* Filter any char not defined in constant
+	* ADDR2LINEALLOWEDCHARS from given string.
+	* @param sString string to be filtered.
+	*/
+	//void FilterString( string &sString );
+
+	/**
+	* Find first occurence of LF/CR from string.
+	* @param sString string to find LF/CR.
+	* @return position of first occurence.
+	*/
+	//size_t FindLineFeed( const string& sString );
+
+	/**
+	* Erase all LF/CR from start of the string until other
+	* characters are found.
+	* @param sString string to erase LF/CR.
+	*/
+	//void EraseUntilNoLineFeed( string& sString );
+
+	/**
+	* Split string containing multiple lines with mixed line feeds to
+	* vector of lines.
+	* @sMultiLineString string containing multiple lines.
+	* @return vector containing one line per cell.
+	*/
+	//vector<string> SplitToStrings( string& sMultiLineString );
+	
+	//Debugging for addr2line task.
+	//ofstream debug;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/cataddr2lineserver.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATAddr2lineServer class.
+*
+*/
+
+#ifndef __CATADDR2LINESERVER_H__
+#define __CATADDR2LINESERVER_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+
+#define BUFSIZE 4096
+ 
+/**
+* This class "runs" the addr2line binary as a server for CATAddr2Line.
+* It redirects the pipes from the tool.
+*/
+class CATAddr2lineServer
+{
+public:
+
+	//Creator
+	CATAddr2lineServer();
+	
+	//Destructor
+	~CATAddr2lineServer();
+
+	/**
+	* Get function name for given address.
+	* @sFullPathAndBinaryName
+	* @return True if initialization succesfull.
+	*/
+	bool Initialize( const string& sFullPathAndBinaryName );
+
+	/**
+	* Write data to a pipe.
+	* @sAddress
+	*/
+	VOID WriteToPipe( const string& sAddress );
+
+	/**
+	* Read data to a pipe.
+	* @return Data from pipe.
+	*/
+	string ReadFromPipe(VOID);
+
+	/**
+	* Gets process created state.
+	* @return True if process created successfully.
+	*/
+	bool GetProcessCreatedState( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+	HANDLE m_hChildStdinRd, m_hChildStdinWr, m_hChildStdinWrDup, 
+	       m_hChildStdoutRd, m_hChildStdoutWr, m_hChildStdoutRdDup, 
+	       m_hChildErroutRd, m_hChildErroutWr, m_hChildErroutRdDup, 
+           m_hSaveStdin, m_hSaveStdout, m_hSaveErrout; 
+
+    SECURITY_ATTRIBUTES m_saAttr;
+    string m_sFullPathAndBinaryName;
+	bool m_bProcessCreated;
+
+	/**
+	* Creates child process for addr2line.exe.
+	* @return True if process created successfully.
+	*/
+	BOOL CreateChildProcess(VOID); 
+
+	/**
+	* Prints error and returns false.
+	* @param sInput error string.
+	* @return false.
+	*/
+	bool PrintErrorAndExit( const string sInput );
+
+
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catalloc.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATAlloc class.
+*
+*/
+
+
+#ifndef __CATALLOC_H__
+#define __CATALLOC_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* Class representing single memory allocation.
+*/
+class CATAlloc
+{
+public:
+	/**
+	* Constructor.
+	*/
+	CATAlloc() : m_iCSCount(0) {}
+
+	/**
+	* Destructor.
+	*/
+	~CATAlloc(){}
+
+	/**
+	* Get alloc string after address, it contains:
+	* time, size, call stack..
+	* @return string allocation string
+	*/
+	string GetAllocString();
+
+	// Members
+
+	string m_sTime; /** Allocation time */
+
+	string m_sSize; /** Allocation size */
+
+	unsigned long m_iCSCount; /** Call stack address count */
+
+	map<unsigned long,string> m_vCallStack; /** Call stack where packet number is key */
+	
+};
+#endif
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catallocs.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATAllocs "collection" class.
+*/
+
+#ifndef __CATALLOCS_H__
+#define __CATALLOCS_H__
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+#include "../inc/catalloc.h"
+
+/**
+* Class representing a collection of memory allocations.
+* It is used to acquire the data of memory leaks by giving all
+* data on single allocations and frees.
+*/
+class CATAllocs : public CATBase
+{
+public:
+	
+	/**
+	* "old" alloc message (prior to 1.6).
+	* @param sAllocString allocation string
+	*/
+	void Alloc( const string& sAllocString );
+
+	/*
+	* Alloc header message (multimessage call stack).
+	* @param sAllocHString allocation string
+	*/
+	void AllocH( const string& sAllocHString );
+
+	/*
+	* Alloc fragment message (fragment of call stack in multimessage alloc).
+	* @param sAllocFString allocation string
+	*/
+	void AllocF( const string& sAllocFString );
+
+	/**
+	* Free message.
+	* @param sFreeString string
+	*/
+	void Free( const string& sFreeString );
+	
+	/**
+	* Free header message.
+	* (not implemented yeat.)
+	* @param sFreeHString string
+	*/
+	void FreeH( const string& sFreeHString );
+
+	/**
+	* Free fragment message.
+	* (not implemented yeat.)
+	* @param sFreeFString string
+	*/
+	void FreeF( const string& sFreeFString );
+
+	/**
+	* Get "leak" list ordered by allocation time.
+	* @param vLeakList container where leaks stored
+	*/
+	void GetLeakList( vector<string>& vLeakList);
+	
+	/**
+	* Clear leaks.
+	*/
+	void ClearAllocs();
+#ifndef MODULE_TEST
+private:
+#endif
+	map<string, CATAlloc> m_vAllocs; /** Collection of allocation(s) */
+};
+#endif
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catdbghelper.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,97 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines the CATDbgHelper class.
+*
+*/
+
+
+#include "iaddresstoline.h"
+// Static variable to represent state of dbghelper api.
+static bool CDBGHELPER_OPEN = false;
+static unsigned int CDBGHELPER_CLIENTS = 0;
+
+// Used "virtual" offset for all loaded modules and addresses.
+// This is used so no module is loaded to the binary address range of atool.exe.
+const unsigned long AT_VIRTUAL_OFFSET_DBGHELPER = 0x1000000;
+
+/**
+* Provides feature to locate code lines using Windows Debug Api. This is done
+* by using dbghelper library. Implements the IAddressToLine interface.
+*/
+class CATDbgHelper : public IAddressToLine
+{
+
+public:
+	
+	/**
+	* Constructor
+	*/
+	CATDbgHelper();
+	
+	/**
+	* Destructor
+	*/
+	~CATDbgHelper();
+
+	/**
+	* Open binary.
+	* @sString Full filename with path to binary.
+	* @iLong base address of binary.
+	* @return true if successful.
+	*/
+	bool Open( const string& sString, const unsigned long iLong);
+	
+	/**
+	* Get error string. In case of any method failed use this to acquire details on error.
+	* @return error string.
+	*/
+	string GetError( void );
+
+	/**
+	* Close binary.
+	* @return true if succesful.
+	*/
+	bool Close( void );
+
+	/**
+	* Read map file for function's.
+	*/
+	void ReadMapFile( const string sMapFileName );
+
+	/**
+	* Locate code line and file for given address.
+	* @result
+	* @return true if successful.
+	*/
+	bool AddressToLine( CATMemoryAddress* result );
+
+	/**
+	* Try get function name for address (only when map is read).
+	* @result
+	* @return true if succesful.
+	*/
+	bool AddressToFunction( CATMemoryAddress* result );
+
+#ifndef MODULE_TEST
+private:
+#endif
+	// Base address used.
+	DWORD64 m_BaseAddress;
+	// Map file read?
+	bool m_bMap;
+	// Map file functions.
+	vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+	// Binary in file system.
+	PSTR m_pBinaryFile;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catfilereader.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATFileReader class.
+*
+*/
+
+
+#ifndef __CATFILEREADER_H__
+#define __CATFILEREADER_H__
+
+#include "ATCommonDefines.h"
+
+/**
+* Provides a feature to read a file as single block into memory and parse it
+* from there line by line (iterating). This can fail or be very slow if file
+* size is bigger than available physical memory for process.
+* But is faster when file fits in free physical memory.
+*/
+class CATFileReader
+{
+public:
+	/**
+	* Constructor.
+	*/
+	CATFileReader();
+	/**
+	* Destructor.
+	*/
+	~CATFileReader();
+#ifndef MODULE_TEST
+private:
+#endif
+	/**
+	* Prevent copy of this class.
+	*/
+	CATFileReader& operator =( const CATFileReader& /*other*/ ) { }
+	CATFileReader( const CATFileReader& /*other*/ ) { }
+public:
+	/**
+	* Open/Read file.
+	* @param cFile file to be read/opened.
+	* @return true if succesful.
+	*/
+	bool Open( const char* cFile );
+	/**
+	* Close file.
+	* @return true if succesful.
+	*/
+	bool Close( void );
+	/**
+	* Get line from file.
+	* @sLine where line content is stored.
+	* @return true if lines left.
+	*/
+	bool GetLine( string& sLine );
+	/**
+	* Set the line delimiter.
+	* @param cDelimiter char that ends the line.
+	*/
+	void SetDelimiter( char cDelimiter );
+	/**
+	* Get current line delimiter.
+	* @return char that ends the line.
+	*/
+	char GetDelimiter() const;
+#ifndef MODULE_TEST
+private:
+#endif
+	// Stream where file content is stored.
+	stringstream m_stream;
+	// Line delimiting character used.
+	char m_cDelimiter;
+};
+#endif
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catromsymbol.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,196 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines CATRomSymbol, RofsBinary classes and Symbol
+*               structure.
+*
+*/
+
+
+#ifndef __CATROMSYMBOL_H__
+#define __CATROMSYMBOL_H__
+
+#include "ATCommonDefines.h"
+#include "iaddresstoline.h"
+
+const string ROM_SYMBOL_IDENTIFY_STRING = "80";
+const string ROFS_SYMBOL_IDENTIFY_STRING = "00";
+const int IDENTIFY_MAX_LINES_READ = 20;
+
+/**
+* Represents a single symbol in a binary.
+*/
+struct Symbol
+{
+	unsigned long iStartAddress; /** Start address */
+	unsigned long iEndAddress; /** End address */
+	string sFunction; /** Function/Symbol name */
+	/**
+	* Default constructor for structure to set default values
+	*/
+	Symbol() { iStartAddress=0; iEndAddress=0; sFunction = ""; }
+	/**
+	* Empty destructor
+	*/
+	~Symbol() {}
+};
+
+
+/**
+* Represents a single binary in ROM/ROFS which
+* contains a collection of Symbols.
+*/
+class RofsBinary {
+public:
+	/**
+	* Constructor
+	*/
+	RofsBinary();
+	/**
+	* Constructor
+	* @param sbinary
+	*/
+	RofsBinary( const string& sbinary );
+	/**
+	* Destructor
+	*/
+	~RofsBinary();
+
+	// Members
+
+	string m_sBinary; /** Binary / code segment */
+	vector<Symbol*> vSymbols; /** Collection of symbols */
+};
+
+/**
+* Implements IAddressToLine interface to acquire symbol information
+* using memory addresses from rom/rofs symbol files.
+*/
+class CATRomSymbol : public IAddressToLine
+{
+public:
+	/**
+	* Constructor.
+	*/
+	CATRomSymbol();
+	/**
+	* Destructor.
+	*/
+	virtual ~CATRomSymbol();
+	bool m_bShowProgressMessages; /** "Flag" will we show progress when reading files */
+	/**
+	* Empty functions does nothing returns false always.
+	* @param sString
+	* @param iLong
+	* @return true if successful.
+	*/
+	bool Open( const string& sString, const unsigned long iLong);
+	/**
+	* Set symbol files.
+	* This also checks that files exists and identifies them as rom/rofs.
+	* @param vSymbols
+	* @return bool
+	*/
+	bool SetSymbols( const vector<string>& vSymbols);
+	/**
+	* Get error string. In case of any method failed use this to acquire details on error.
+	* @return error string.
+	*/
+	string GetError( void );
+	/**
+	* Close rom symbol file.
+	* @return true if succesful.
+	*/
+	bool Close( void );
+	/**
+	* Locates symbol and binary name for given address if found in rom.
+	* @param result memory address object.
+	* @return true if successful.
+	*/
+	bool AddressToLine( CATMemoryAddress* result );
+#ifndef MODULE_TEST
+private:
+#endif
+	/**
+	* Represents the symbol files type
+	* (content is different / format )
+	*/
+	enum SYMBOL_FILE_TYPE {
+		SYMBOL_FILE_INVALID = 0, /** not valid */
+		SYMBOL_FILE_ROM, /** rom type */
+		SYMBOL_FILE_ROFS /** rofs type */
+	};
+	/**
+	* Identify symbol file
+	* @param sFile
+	* @return int
+	*/
+	int IdentifySymbolFile( const string& sFile );
+	/**
+	* Locate symbol and binary name for given address if found in rom.
+	* @param result
+	* @return bool
+	*/
+	bool AddressToLineRom( CATMemoryAddress* result );
+	/**
+	* Locate symbol and binary name for given address if found in rofs.
+	* @param result
+	* @return bool
+	*/
+	bool AddressToLineRofs( CATMemoryAddress* result );
+	/**
+	* Reads rom files.
+	* @return bool
+	*/
+	bool ReadRomFiles();
+	/**
+	* Read specified rom file
+	* @param sFile
+	* @return bool
+	*/
+	bool ReadRomFile( const string& sFile );
+	/**
+	* Read rofs files
+	* @return bool
+	*/
+	bool ReadRofsFiles();
+	/**
+	* Read specified rofs file
+	* @param sFile
+	* @return bool
+	*/
+	bool ReadRofsFile( const string& sFile );
+	/**
+	* Parse symbol from a line in rom/rofs file.
+	* @param sLine
+	* @param pSymbol
+	*/
+	void ParseSymbolFromLine( const string& sLine, Symbol* pSymbol );
+#ifndef MODULE_TEST
+private:
+#endif
+
+	// Members
+
+	bool m_bFilesIdentified; /**  Have we identified symbol file(s) */
+	bool m_bSymbolsRead; /** Have we read symbol file(s) */
+	vector<string> m_vRomFiles; /** Rom symbol file(s) */
+	vector<Symbol*> m_vRomCache; /** Cached rom symbols */
+	vector<Symbol*> m_vRomSymbols; /** All rom symbols */
+	unsigned long m_iRomStartAddress; /** Rom start address */
+	unsigned long m_iRomEndAddress; /** Rom end address */
+	vector<string> m_vRofsFiles; /** Rofs symbol file(s) */
+	vector<RofsBinary*> m_vRofsBinaries; /** Rofs binaries */
+	string m_sErrorMessage; /** Error message */
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/iaddresstoline.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Interface definition for locating code lines using memory addresses.
+*
+*/
+#ifndef __IADDRESSTOLINE_H__
+#define __IADDRESSTOLINE_H__
+
+#include "ATCommonDefines.h"
+
+class CATMemoryAddress;
+
+/**
+* Codeline locating interface. Thru this interface CATModule2 locates code lines
+* using different implementations depending on platform.
+*/
+class IAddressToLine
+{
+public:
+	IAddressToLine() {};
+	virtual ~IAddressToLine() {};
+	/**
+	* Open binary.
+	* @sString
+	* @iNumber
+	* @return true if successful.
+	*/
+	virtual bool Open( const string& sString, const unsigned long iLong) = 0;
+	
+	/**
+	* Get error string. In case of any method failed use this to acquire details on error.
+	* @return error string.
+	*/
+	virtual string GetError( void ) = 0;
+
+	/**
+	* Close binary.
+	* @return true if succesful.
+	*/
+	virtual bool Close( void ) = 0;
+
+	/**
+	* Locate code line and file for given address.
+	* @result
+	* @return true if successful.
+	*/
+	virtual bool AddressToLine( CATMemoryAddress* result ) = 0;
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/stdafx.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Include file for standard system include files,
+*                or project specific include files that are used frequently, but
+*                are changed infrequently.
+*  Version     : %version: 1 % 
+*
+*/
+
+
+#pragma once
+
+// MemoryLeak checking function.
+// Note! Do not comming in svn with this flag enabled.
+//#define MEM_LEAK_CHECK
+
+// Addr2line binary used.
+//#define ADDR2LINE
+
+#ifdef MEM_LEAK_CHECK
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#include <tchar.h>
+#include <fstream>   //ifstream,ofstream
+#include <windows.h>
+#include <string>    //string
+#include <vector>    //string
+#include <sstream>   //stringstream
+#include <iostream>  // cout
+#include <map> // map
+#include <time.h>
\ No newline at end of file
Binary file analyzetool/commandlineengine/install/addr2line.exe has changed
Binary file analyzetool/commandlineengine/install/atool.exe has changed
Binary file analyzetool/commandlineengine/install/binutils-2.19.1-src.zip has changed
Binary file analyzetool/commandlineengine/install/xerces-c_2_7.dll has changed
Binary file analyzetool/commandlineengine/lib/xerces-c_2.lib has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATBase.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1299 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATBase.
+*
+*/
+
+
+#include "../inc/CATBase.h"
+#include "../inc/CATParseXML.h"
+
+// -----------------------------------------------------------------------------
+// CATBase::CATBase
+// Constructor.
+// -----------------------------------------------------------------------------
+CATBase::CATBase(void)
+{
+	LOG_FUNC_ENTRY("CATBase::CATBase");
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::~CATBase
+// Destructor.
+// -----------------------------------------------------------------------------
+CATBase::~CATBase(void)
+{
+	LOG_FUNC_ENTRY("CATBase::~CATBase");
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeToLower
+// Converts any uppercase letter to lowercase.
+// -----------------------------------------------------------------------------
+void CATBase::ChangeToLower( string& sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ChangeToLower");
+	int iLength = (int)sInput.size();
+	for( int i = 0 ; i < iLength ; i++ )
+	{
+		sInput[i] = (char)tolower( sInput[i] );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeToUpper
+// Converts any uppercase letter to lowercase.
+// -----------------------------------------------------------------------------
+void CATBase::ChangeToUpper( string& sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ChangeToUpper");
+	int iLength = (int)sInput.size();
+	for( int i = 0 ; i < iLength ; i++ )
+	{
+		sInput[i] = (char)toupper( sInput[i] );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::TrimString
+// Remove spaces and tabulatures from beginning and
+// end of given string.
+// -----------------------------------------------------------------------------
+void CATBase::TrimString( string& sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::TrimString");
+	if( sInput.empty() )
+		return;
+	//Remove spaces and tabulatures from beginning of string
+	while( !sInput.empty() && ( sInput[0] == SPACE_CHAR_VALUE || sInput[0] == TAB_CHAR_VALUE ) )
+	{
+		sInput.erase( 0, 1 );
+	}
+	//Remove spaces and tabulatures from end of string
+	while( !sInput.empty() && ( sInput[sInput.size()-1] == SPACE_CHAR_VALUE || sInput[sInput.size()-1] == TAB_CHAR_VALUE ) )
+	{
+		sInput.erase( sInput.size()-1, 1 );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::SearchFileWithExtension
+// Searches files with given extension from path.
+// -----------------------------------------------------------------------------
+bool CATBase::SearchFileWithExtension( const char* pPathAndExt, bool bPrintErrors, string& sErrorLog )
+{
+	LOG_FUNC_ENTRY("CATBase::SearchFileWithExtension");
+	WIN32_FIND_DATA FindFileData;
+	HANDLE hFind;
+	string sTemp( pPathAndExt );
+
+	//Find file
+	hFind = FindFirstFile( sTemp.c_str(), &FindFileData );
+	if (hFind == INVALID_HANDLE_VALUE)
+	{
+		string sErrorString( "No " );
+		//Get extension
+		string sExt( pPathAndExt );
+		sExt.erase( 0, sExt.find_last_of( "." ) );
+
+		sErrorString.append( sExt );
+		sErrorString.append( " files in directory: " );
+
+		string sWithoutExt( pPathAndExt );
+		sWithoutExt.erase( sWithoutExt.find_last_of( "." )-1, string::npos );
+		sErrorString.append( sWithoutExt );
+
+		if( bPrintErrors )
+		{
+			//string sTemp( pPathAndExt );
+			//printf( "Can not find: %s.\n", pPathAndExt );
+			printf( sErrorString.c_str() );
+		}
+		else
+		{
+			//Add line change if sErrorString not empty
+			if( !sErrorLog.empty() )
+				sErrorString.insert( 0, "\n" );
+			sErrorLog.append( sErrorString );
+		}
+		return false;
+	} 
+	else 
+	{
+		FindClose(hFind);
+		return true;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetPathOrFileName
+// Returns path to file or file name.
+// -----------------------------------------------------------------------------
+string CATBase::GetPathOrFileName( bool bFileName, string sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::GetPathOrFileName");
+	string sRet;
+	size_t iPos = sInput.size();
+
+	sInput = ChangeSlashToBackSlash( sInput );
+
+	//Find character '\' starting from end of string
+	while( iPos > 0 && sInput[iPos] != '\\' )
+	{
+		iPos--;
+	}
+	if( iPos > 0 )
+	{
+		//Return file name
+		if( bFileName )
+		{
+			sInput.erase( 0, iPos+1 );
+			sRet = sInput;
+		}
+		else //Return file path
+		{
+			sInput.erase( iPos+1, string::npos );
+			sRet = sInput;
+		}
+	}
+	else
+	{
+		if( !bFileName )
+			return sRet;
+		sRet = sInput;
+	}
+	return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetFileNameUsingExt
+// Searches files with given extension from path.
+// -----------------------------------------------------------------------------
+string CATBase::GetFileNameUsingExt( const char* pPathAndExt )
+{
+	LOG_FUNC_ENTRY("CATBase::GetFileNameUsingExt");
+	WIN32_FIND_DATA FindFileData;
+	HANDLE hFind;
+	string sRet;
+
+	//Find file
+	hFind = FindFirstFile( pPathAndExt, &FindFileData );
+	if (hFind == INVALID_HANDLE_VALUE)
+	{
+		//if( bPrintErrors )
+		printf( "Can not find: %s.\n", pPathAndExt );
+		return sRet;
+	} 
+	else 
+	{
+		sRet.append( FindFileData.cFileName );
+		FindClose(hFind);
+		return sRet;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetStringUntilNextSpace
+// Function returns string from begin of given string until next space,
+// characters until next space are removed from sInput string.
+// -----------------------------------------------------------------------------
+string CATBase::GetStringUntilNextSpace( string& sInput, bool bEraseFromInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::GetStringUntilNextSpace");
+	string sTemp( sInput );
+	size_t iSize = sTemp.find_first_of(' ');
+	if( iSize != string::npos )
+	{
+		sTemp.resize( iSize );
+		if( bEraseFromInput )
+			sInput.erase( 0, (iSize+1) );
+	}
+	else
+	{
+		if ( bEraseFromInput )
+			sInput.clear();
+	}
+	return sTemp;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeSlashToBackSlash
+// Function changes all BackSlash characters to Slash character from
+// given string.
+// -----------------------------------------------------------------------------
+string CATBase::ChangeSlashToBackSlash( string sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ChangeSlashToBackSlash");
+	for( unsigned int i = 0 ; i < sInput.length() ; i++ )
+	{
+		if( sInput[i] == '/' )
+		{
+			sInput[i] = '\\';
+		}
+	}
+	return sInput;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileExists
+// Check if given file exists.
+// -----------------------------------------------------------------------------
+bool CATBase::FileExists( const char * pFilename )
+{
+	LOG_FUNC_ENTRY("CATBase::FileExists");
+	DWORD dwRet = GetFileAttributes( pFilename );
+	if( dwRet == INVALID_FILE_ATTRIBUTES )
+	{
+		return false;
+	}
+	else
+	{
+		//Is file directory?
+		if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+bool CATBase::IsFileReadOnly( const char* pFilename )
+{
+	LOG_FUNC_ENTRY("CATBase::IsFileReadOnly");
+	DWORD dwRet = GetFileAttributes( pFilename );
+	if( dwRet == INVALID_FILE_ATTRIBUTES )
+		return false;
+	if( dwRet & FILE_ATTRIBUTE_READONLY )
+		return true;
+	return false;
+}
+
+bool CATBase::SetFileReadOnly( const char* pFileName )
+{
+	LOG_FUNC_ENTRY("CATBase::SetFileReadOnly");
+	DWORD dw = GetFileAttributes( pFileName );
+	if( dw == INVALID_FILE_ATTRIBUTES )
+		return false;
+	if( dw & FILE_ATTRIBUTE_READONLY )
+		return true;
+	dw = dw | FILE_ATTRIBUTE_READONLY ;
+	if ( SetFileAttributes( pFileName, dw ) )
+		return true;
+	return false;
+}
+bool CATBase::SetFileWritable( const char* pFileName )
+{
+	LOG_FUNC_ENTRY("CATBase::SetFileWritable");
+	DWORD dw = GetFileAttributes( pFileName );
+	if( dw == INVALID_FILE_ATTRIBUTES )
+		return false;
+	if( ! dw & FILE_ATTRIBUTE_READONLY )
+		return true;
+	dw = dw ^ FILE_ATTRIBUTE_READONLY ;
+	if ( SetFileAttributes( pFileName, dw ) )
+		return true;
+	return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileCopyToPath
+// Copies file to given path
+// -----------------------------------------------------------------------------
+bool CATBase::FileCopyToPath(const string& sFile, const string& sToPath)
+{
+	LOG_FUNC_ENTRY("CATBase::FileCopyToPath");
+	// Display message
+	cout << AT_MSG << "Copy " << sFile << AT_FILE_TO << sToPath << endl;
+	if ( sFile.empty() || sToPath.empty() )
+	{
+		LOG_FUNC_EXIT("CATBase::FileCopyToPath Error, empty parameter");
+		return false;
+	}
+	// Copy using windows api (seems not to work when relavite path ..
+	/*
+	// Full path where to copy
+	string sDestination = sToPath;
+	// Append '\' to string if not exists
+	if ( sDestination.length() > 1 )
+	{
+		const char cLastChar = sDestination[ sDestination.length() -1 ];
+		if ( cLastChar != DASH )
+			sDestination.append("\\");
+	}
+	int iRet = 0;
+	iRet = CopyFile( sFile.c_str(), sDestination.c_str(), false );
+	if ( iRet != 0 )
+	{
+		return false;
+	}
+	*/
+	string sCommand;
+	sCommand.append( "copy /Y \"");
+	sCommand.append( sFile );
+	sCommand.append( "\" \"" );
+	sCommand.append( sToPath );
+	sCommand.append( "\" > nul 2>&1" );
+	LOG_STRING( sCommand );
+	int iRet = 0;
+	iRet = (int)system( sCommand.c_str() );
+	if ( iRet != 0 )
+		return false;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileMoveToPath
+// Copies file to given path
+// -----------------------------------------------------------------------------
+bool CATBase::FileMoveToPath(const string& sFile, const string& sToPath)
+{
+	LOG_FUNC_ENTRY("CATBase::FileMoveToPath");
+	// Display message
+	cout << AT_MSG << "Move " << sFile << AT_FILE_TO << sToPath << endl;
+	if ( sFile.empty() || sToPath.empty() )
+	{
+		LOG_FUNC_EXIT("CATBase::FileMoveToPath Error, empty parameter");
+		return false;
+	}
+	// Move (again windows api function does not support relative path .. in it
+	/*
+	// Get filename from sFile
+	string sFileName = GetPathOrFileName( true, sFile );
+	// Full path where to copy
+	string sDestination = sToPath;
+	// Append '\' to string if not exists
+	if ( sDestination.length() > 1 )
+	{
+		const char cLastChar = sDestination[ sDestination.length() -1 ];
+		if ( cLastChar != DASH )
+			sDestination.append("\\");
+	}
+	int iRet = 0;
+	iRet = MoveFile( sFile.c_str(), sDestination.c_str());
+	if ( iRet != 0 )
+	{
+		return false;
+	}
+	*/
+	string sCommand;
+	sCommand.append( "move /Y \"");
+	sCommand.append( sFile );
+	sCommand.append( "\" \"" );
+	sCommand.append( sToPath );
+	sCommand.append( "\" > nul 2>&1" );
+	LOG_STRING( sCommand );
+	int iRet = 0;
+	iRet = (int)system( sCommand.c_str() );
+	if ( iRet != 0 )
+		return false;
+	return true;
+}
+// -----------------------------------------------------------------------------
+// CATBase::CreateTempPath
+// Creates temporary directory path for given mmp file
+// -----------------------------------------------------------------------------
+string CATBase::CreateTempPath(const string& sMmpFileWithPath)
+{
+	LOG_FUNC_ENTRY("CATBase::CreateTempPath");
+	string sTempPath = GetPathOrFileName( false, sMmpFileWithPath );
+	sTempPath.append( AT_TEMP_DIR );
+	sTempPath.append( "\\" );
+	return sTempPath;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemovePathAndExt
+// Removes extension from file name and returns file name without extension.
+// -----------------------------------------------------------------------------
+string CATBase::RemovePathAndExt( string sFileName, bool bReverseFindExt)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::RemovePathAndExt");
+	string sRet;
+	sFileName = GetPathOrFileName( true, sFileName );
+	if ( bReverseFindExt )
+	{
+		// Remove extension from reverse
+		size_t iPos = sFileName.find_last_of('.');
+		if( iPos != string::npos )
+		{
+			sFileName.resize( sFileName.find_last_of('.') );
+			sRet = sFileName;
+		}
+	}
+	else
+	{
+		// Remove extension finding first .
+		size_t iPos = sFileName.find_first_of('.');
+		if( iPos != string::npos )
+		{
+			sFileName.resize( sFileName.find_first_of('.') );
+			sRet = sFileName;
+		}
+	}
+	return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsTargetTypeSupported
+// Checks from constant array is this target unsupported
+// -----------------------------------------------------------------------------
+bool CATBase::IsTargetTypeSupported(string sTargetType)
+{
+	LOG_FUNC_ENTRY("CATBase::IsTargetTypeSupported");
+	// compare to list
+	int iArraySize = sizeof( UNSUPPORTED_TARGET_TYPES ) / sizeof( string );
+	for ( int i=0 ; i < iArraySize ; i++ )
+	{
+		string sUnsupported = UNSUPPORTED_TARGET_TYPES[i];
+		// lowercase both
+		ChangeToLower(sTargetType);
+		ChangeToLower(sUnsupported);
+		// compare
+		if ( sUnsupported.compare( sTargetType ) == 0 )
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsTargetTypeKernelSide
+// Checks from constant array is this target type kernel side
+// -----------------------------------------------------------------------------
+bool CATBase::IsTargetTypeKernelSide(string sTargetType)
+{
+	LOG_FUNC_ENTRY("CATBase::IsTargetTypeKernelSide");
+	// compare to list
+	int iArraySize = sizeof( KERNEL_SIDE_TARGET_TYPES ) / sizeof( string );
+	for ( int i=0 ; i < iArraySize ; i++ )
+	{
+		string sUnsupported = KERNEL_SIDE_TARGET_TYPES[i];
+		// lowercase both
+		ChangeToLower(sTargetType);
+		ChangeToLower(sUnsupported);
+		// compare
+		if ( sUnsupported.compare( sTargetType ) == 0 )
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+bool CATBase::CheckVariant( const string& sEpocRoot, const string& sVariant )
+{
+	LOG_FUNC_ENTRY("CATBase::CheckVariant");
+	string sFileToCheck;
+	// Add epoc root
+	if( sEpocRoot.size() > 1 )
+		sFileToCheck.append( sEpocRoot );
+	// Add path
+	sFileToCheck.append( VARIANT_DIR ) ;
+	// Add variant
+	sFileToCheck.append( sVariant );
+	// Add extension
+	sFileToCheck.append( VARIANT_FILE_EXTENSION );
+	// check does FileExists
+	return FileExists( sFileToCheck.c_str() );
+}
+bool CATBase::IsDefaultVariant( const string& sEpocRoot )
+{
+	LOG_FUNC_ENTRY("CATBase::IsDefaultVariant");
+	string sFileToCheck;
+	// Add epoc root
+	if( sEpocRoot.size() > 1 )
+		sFileToCheck.append( sEpocRoot );
+	// Add path
+	sFileToCheck.append( VARIANT_DIR ) ;
+	// Add variant
+	sFileToCheck.append( "DEFAULT" );
+	// Add extension
+	sFileToCheck.append( VARIANT_FILE_EXTENSION );
+	// check does FileExists
+	return FileExists( sFileToCheck.c_str() );
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileDelete
+// FileDelete
+// -----------------------------------------------------------------------------
+bool CATBase::FileDelete(const string& sFile, bool bPrint )
+{
+	LOG_FUNC_ENTRY("CATBase::FileDelete");
+	// does file even exists
+	if ( !FileExists( sFile.c_str() ) )
+		return false;
+	// delete file
+	int iRet = _unlink( sFile.c_str() );
+	// if print on display error
+	if ( iRet  && bPrint )
+	{
+		cout << AT_MSG << "Error, deleting file " << sFile
+			<< endl;
+	}
+	// if print on display message
+	else if ( !iRet && bPrint )
+	{
+		cout << AT_MSG << "Delete " << sFile << endl;
+	}
+	// return
+	if ( iRet )
+		return false;
+	return true;
+}
+// -----------------------------------------------------------------------------
+// CATBase::DirDelete
+// Delelete directory
+// -----------------------------------------------------------------------------
+bool CATBase::DirDelete(const string& sDir, bool bPrint )
+{
+	LOG_FUNC_ENTRY("CATBase::DirDelete");
+	if ( sDir.find( AT_TEMP_DIR) == string::npos )
+		return false;
+	
+	if ( sDir.length() < 2 )
+		return false;
+
+	string sDir2;
+	if ( sDir.at(1) != ':' )
+	{
+		char cDir[MAX_LINE_LENGTH];
+		GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+		sDir2.append( cDir );
+		sDir2.append( "\\" );
+		sDir2.append( sDir );
+	}
+	else
+		sDir2.append( sDir );
+
+	// does directory exists
+	DWORD dwRet = GetFileAttributes( sDir2.c_str() );
+	if ( dwRet == INVALID_FILE_ATTRIBUTES )
+		return false;
+	else if ( ! (dwRet & FILE_ATTRIBUTE_DIRECTORY) )
+	{
+		return false;
+	}
+	// Delete dir
+	string sCmd( "rmdir /S /Q " );
+	sCmd.append( sDir2 );
+	sCmd.append( " > nul 2>&1" );
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet && bPrint)
+	{
+		cout << AT_MSG << "Error, deleting directory " << sDir2 << endl;
+	}
+	else if ( !iRet && bPrint )
+	{
+		cout << AT_MSG << "Delete directory " << sDir2 << endl;
+	}
+	if ( iRet )
+		return false;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::DirCreate
+// Create directory
+// -----------------------------------------------------------------------------
+bool CATBase::DirCreate(const string& sDir, bool bPrint )
+{
+	LOG_FUNC_ENTRY("CATBase::DirCreate");
+
+	if ( sDir.length() < 2 )
+		return false;
+
+	string sDir2;
+	if ( sDir.at(1) != ':' )
+	{
+		char cDir[MAX_LINE_LENGTH];
+		GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+		sDir2.append( cDir );
+		sDir2.append( "\\" );
+		sDir2.append( sDir );
+	}
+	else
+		sDir2.append( sDir );
+
+	// does directory exists
+	DWORD dwRet = GetFileAttributes( sDir2.c_str() );
+	if ( dwRet != INVALID_FILE_ATTRIBUTES )
+	{
+		if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+			return false;
+	}
+	// Create dir
+	string sCmd( "mkdir " );
+	sCmd.append( sDir2 );
+	sCmd.append( " > nul 2>&1" );
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet && bPrint)
+	{
+		cout << AT_MSG << "Error, creating directory " << sDir2 << endl;
+	}
+	else if ( !iRet && bPrint )
+	{
+		cout << AT_MSG << "Directory " << sDir2 << " created" << endl;
+	}
+	if ( iRet )
+		return false;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertTCHARtoString
+// Convert TCHAR* to std::string
+// -----------------------------------------------------------------------------
+string CATBase::ConvertTCHARtoString(TCHAR* charArray)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ConvertTCHARtoString");
+	// Loop char array
+	stringstream ss;
+	int iIndex = 0;
+	char c = (char) charArray[iIndex];
+	// until null termination
+	while ( c != '\0' )
+	{
+		ss << c;
+		iIndex++;
+		c = (char) charArray[iIndex];
+	}
+	// return string
+	return ss.str();
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertTCHARtoString
+// Get list of files in directory
+// -----------------------------------------------------------------------------
+vector<string> CATBase::DirList(const string& sDirectory
+								, bool bListDirs, bool bAddPathToFile)
+{
+	LOG_FUNC_ENTRY("CATBase::DirList");
+	// Create string to modify it
+	string sDir = sDirectory;
+	// Add if missing '\' & '*' to the sDirectory
+	if ( sDir.at( sDir.size()-1 ) != '\\' )
+		sDir.append( "\\" );
+	// Path to add to file string if specified
+	string sPath = sDir;
+	// Add * to for windows api to find all files
+	sDir.append( "*" );
+	// convert directory string to LPCSTR
+	LPCSTR dir( sDir.c_str() );
+	// vector to store file list
+	vector<string> vFileList;
+	// Using win32 api to find list of files in directory
+	// file data "container"
+	WIN32_FIND_DATA fileData;
+	// handle to directory
+	HANDLE hFinder = FindFirstFile( dir, &fileData );
+	if ( hFinder == INVALID_HANDLE_VALUE )
+	{
+		// no files found
+		return vFileList;
+	}
+	// loop files add to vector and return
+	while( FindNextFile(hFinder, &fileData ) )
+	{
+		DWORD dw = fileData.dwFileAttributes;
+		// skip if its directory and bListDirs not specified
+		if ( dw & FILE_ATTRIBUTE_DIRECTORY && ! bListDirs)
+			continue;
+		// add files to vector
+		string sFile = ConvertTCHARtoString( fileData.cFileName );
+		// Add given path to file string if specified
+		if ( bAddPathToFile )
+			sFile.insert( 0, sPath );
+		vFileList.push_back( sFile );
+	}
+	// Close file find handler
+	FindClose( hFinder );
+	return vFileList;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ParseRelativePathToString
+// ParseRelative
+// -----------------------------------------------------------------------------
+void CATBase::ParseRelativePathString(string& sPathString)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ParseRelativePathString");
+	string sParsed;
+	// find ..
+	size_t iDots = sPathString.find( ".." );
+	while ( iDots != string::npos )
+	{
+		RemoveRelativePath( sPathString, iDots );
+		iDots = sPathString.find( ".." );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemoveRelativePath
+// Remove relative path from string (using given index)
+// -----------------------------------------------------------------------------
+void CATBase::RemoveRelativePath(string& sString, size_t iDots)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::RemoveRelativePath");
+	// Chck if accidentally given wrong parameter
+	if ( iDots == string::npos 
+		|| iDots < 1 )
+		return;
+	// Parsed string
+	string sParsed;
+	// Find position of last backslash before dots
+	size_t i = sString.rfind("\\", iDots-2 );
+	// Pickup start part (depending is the backslash at last parts first char)
+	if ( sString.at(iDots+2) != '\\' )
+		sParsed = sString.substr( 0, i+1 ) ;
+	else
+		sParsed = sString.substr( 0, i );
+	// Pick up last part
+	sParsed.append( sString.substr( iDots+2, sString.size() ) );
+	sString = sParsed;
+}
+
+// -----------------------------------------------------------------------------
+// Get extension from given string
+// -----------------------------------------------------------------------------
+string CATBase::GetExtension(const string& sString)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::GetExtension");
+	// find last .
+	size_t iDot = sString.find_last_of( "." );
+	// return string after . if found
+	if ( iDot != string::npos )
+		return sString.substr(iDot+1, sString.length()-(iDot+1) );
+	// otherwise return given string
+	return sString;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::DirectoryExists
+// Check if given directory exists.
+// -----------------------------------------------------------------------------
+bool CATBase::DirectoryExists( const char* pDirname )
+{
+	LOG_FUNC_ENTRY("CATBase::DirectoryExists");
+	size_t iLenght = strlen( pDirname );
+	
+	if ( iLenght < 2 )
+		return false;
+
+	string sDir;
+	if ( pDirname[1] != ':' )
+	{
+		char cDir[MAX_LINE_LENGTH];
+		GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+		sDir.append( cDir );
+		sDir.append( "\\" );
+		sDir.append( pDirname );
+	}
+	else
+		sDir.append( pDirname );
+
+	DWORD dwRet = GetFileAttributes( sDir.c_str() );
+	if( dwRet == INVALID_FILE_ATTRIBUTES )
+	{
+		return false;
+	}
+	else
+	{
+		//Is file directory?
+		if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertUnixPathToWin
+// -----------------------------------------------------------------------------
+void CATBase::ConvertUnixPathToWin( string& sPath )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ConvertUnixPathToWin");
+	size_t iSpot = 0;
+	// convert '/' to '\'
+	iSpot = sPath.find( "/" );
+	while( iSpot != string::npos )
+	{
+		sPath.replace(iSpot,1, "\\");
+		iSpot = sPath.find( "/", iSpot+1 );
+	}
+	// convert '\\' to '\'
+	iSpot = sPath.find( "\\\\" );
+	while( iSpot != string::npos )
+	{
+		sPath.replace(iSpot,2,"\\");
+		iSpot = sPath.find( "\\\\" );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemoveAllAfterDotIfTwoDots
+// Removes all after first '.'
+// if given string contains 2 '.' or more
+// -----------------------------------------------------------------------------
+void CATBase::RemoveAllAfterDotIfTwoDots(string& sModName)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::RemoveAllAfterDotIfTwoDots");
+	// did we find variable?
+	size_t found;
+	// Find first '.'
+	found = sModName.find(".");
+	if ( found != string::npos )
+	{
+		// Try find second '.'
+		found = sModName.find(".", found+1);
+		if ( found != string::npos )
+		{
+			// Remove all after first '.'
+			sModName = sModName.substr(0, sModName.find(".")+1 );
+		}
+	}
+}
+// -----------------------------------------------------------------------------
+// CATBase::CreateTemporaryCpp
+// -----------------------------------------------------------------------------
+bool CATBase::CreateTemporaryCpp( const string& sId,
+								 const string& sPath
+								 ,const string& sS60FileName
+								 ,int iLogOption
+								 ,int iIsDebug
+								 ,int iAllocCallStackSize
+								 ,int iFreeCallStackSize )
+{
+	LOG_FUNC_ENTRY("CATBase::CreateTemporaryCpp");
+	// Add slash to path if missing
+	string sTempCpp = sPath;
+	if( sTempCpp.at( sTempCpp.length() - 1 ) != '\\' )
+		sTempCpp.append("\\");
+
+	// append temporary cpp name with id in middle
+	sTempCpp.append( AT_TEMP_CPP_LOWER_START );
+	sTempCpp.append( sId );
+	sTempCpp.append( AT_TEMP_CPP_LOWER_END );
+
+	//Open and truncate temporary cpp
+	ofstream out( sTempCpp.c_str() , ios::trunc );
+	if ( ! out.good() )
+	{
+		out.close();
+		return false;
+	}
+	// Headers
+	out << "#include <e32base.h>";
+	// Is debug
+	out << "\nconst TInt ATTempDebug(" << iIsDebug << ");";
+	// Log option
+	out << "\nconst TInt ATTempLogOption(" << iLogOption << ");";
+	// Alloc call stack
+	out << "\nconst TInt ATTempAllocCallStackSize(" << iAllocCallStackSize << ");";
+	// Free call stack
+	out << "\nconst TInt ATTempFreeCallStackSize(" << iFreeCallStackSize << ");";
+	// Log file name
+	out << "\n_LIT( ATTempLogFileName, \"" << sS60FileName << "\" );";
+	// Version number
+	out << "\n_LIT( ATTempVersion, \"" << ATOOL_COMPATIBILITY_STRING << "\" );";
+	// Variable functions use enumeration values that are defined in memoryhook (customuser.h)
+	// We use constants here so that we don't need to include the header file, wich
+	// might cause problems.
+/* Enumeration copied to comment for notes
+        enum TATOptions
+            {
+            ELogFileName = 1,   
+            EVersion = 2 ,
+            ELogOption = 3,
+            EDebug = 4,
+            EAllocCallStackSize = 5,
+            EFreeCallStackSize = 6
+            };
+*/
+	out << "\nTInt GetInt( const TUint8 aType )";
+	out << "\n{";
+	out << "\nswitch( aType )";
+	out << "\n{";
+	out << "\ncase 4: return ATTempDebug; ";
+	out << "\ncase 3: return ATTempLogOption;";
+	out << "\ncase 5: return ATTempAllocCallStackSize;";
+	out << "\ncase 6: return ATTempFreeCallStackSize;";
+	out << "\ndefault: return KErrArgument;";
+	out << "\n}";
+	out << "\n}";
+	out << "\nTPtrC GetString( const TUint8 aType )";
+	out << "\n{";
+	out << "\nswitch( aType )";
+	out << "\n{";
+	out << "\ncase 1: return ATTempLogFileName();";
+	out << "\ncase 2: return ATTempVersion();";
+	out << "\ndefault: return KNullDesC();";
+	out << "\n}";
+	out << "\n}";
+
+	/** Todo: Old way of separate functions, these here for backup support and to ease testing. */
+	/** Unnessesary in the future, so can be removed then (1.8.2). */
+
+	out << "\n_LIT( KFileName, \"";
+	out << sS60FileName;
+	out << "\" );\n";
+
+	// Hardcoded version number for support.
+	out << "\n/* The AnalyzeTool version number used. */";
+	out << "\n_LIT( KAtoolVersion, \"1.7.5;1.9.1\" );\n";
+
+	out << "\nconst TFileName LogFileName()";
+	out << "\n    {";
+	out << "\n    return TFileName( KFileName() );";
+	out << "\n    }";
+
+	out << "\nTUint32 AllocCallStackSize()";
+	out << "\n    {";
+	out << "\n    return TUint32( ";
+	out << iAllocCallStackSize;
+	out << " );\n";
+	out << "\n    }";
+	
+	out << "\nTUint32 FreeCallStackSize()";
+	out << "\n    {";
+	out << "\n    return TUint32( ";
+	out << iFreeCallStackSize;
+	out << " );\n";
+	out << "\n    }";
+
+	out << "\nconst TFileName AtoolVersion()";
+	out << "\n    {";
+	out << "\n    return TFileName( KAtoolVersion() );";
+	out << "\n    }";
+
+	out << "\nTUint32 LogOption()";
+	out << "\n    {";
+	out << "\n    return TUint32( ";
+	out << iLogOption;
+	out << " );";
+	out << "\n    }";
+	
+	out << "\nTUint32 IsDebug()";
+	out << "\n    {";
+	out << "\n    return TUint32( ";
+	out << iIsDebug;
+	out << " );";
+	out << "\n    }";
+
+	// End of file and close
+	out << "\n\n// End of File\n";
+	out.close();
+	cout << AT_MSG << "Created " << sTempCpp << endl;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsDataFile
+// -----------------------------------------------------------------------------
+bool CATBase::IsDataFile( string sFile )
+{
+	LOG_FUNC_ENTRY("CATBase::IsDataFile");
+	// Check that sFile not empty
+	if ( sFile.empty() || sFile.length() < 1 )
+		return false;
+
+	// Temporary line char array.
+	char cLineFromFile[MAX_LINE_LENGTH];
+	//Open file
+	ifstream in( sFile.c_str() );
+
+	//File open ok?
+	if( !in.good() )
+		return false;
+
+	//Read all lines
+	in.getline( cLineFromFile, MAX_LINE_LENGTH );
+
+	string sLineFromFile( cLineFromFile );
+	in.close();
+	if( sLineFromFile.find( "DATA_FILE_VERSION" ) != string::npos )
+		return true;
+	else
+		return false;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATBase::ParseStringToVector
+// -----------------------------------------------------------------------------
+vector<string> CATBase::ParseStringToVector( const string& sInput, char separator )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::ParseStringToVector");
+	string sString(sInput);
+	// Elements vector
+	vector<string> vStrings;
+	size_t iPos = sString.find( separator );
+	// If can not find it return vector with just one element
+	if ( iPos == string::npos )
+	{
+		// Don't add empty item into vector.
+		if ( sString.size() > 0 )
+			vStrings.push_back( sString );
+		return vStrings;
+	}
+	// Loop elements
+	while( iPos != string::npos )
+	{
+		string sElement = sString.substr(0, iPos);
+		vStrings.push_back( sElement );
+		sString.erase(0, iPos +1 );
+		iPos = sString.find( separator );
+	}
+	// Add last element if any
+	if ( sString.size() > 0 )
+		vStrings.push_back( sString );
+	// Return elements
+	return vStrings;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FilterString
+// Filter string out of unwanted characters. The list of allowed
+// characters is defined in CFILTERSTRING.
+// -----------------------------------------------------------------------------
+string CATBase::FilterString( const string& sString )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::FilterString");
+	string sFiltered;
+	for( size_t i = 0 ; i < sString.length() ; i++ )
+	{
+		const char p = sString.at( i );
+		if ( strchr( CFILTERSTRING, p ) !=  0 )
+			sFiltered.push_back( p );
+	}
+	return sFiltered;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FilterExtraSpaces
+// Replaces multiple continuous spaces with single. Won't leave
+// spaces in start or end of string.
+// -----------------------------------------------------------------------------
+void CATBase::FilterExtraSpaces( string& sString )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::FilterExtraSpaces");
+	string sFiltered;
+	// Loop thru char array.
+	for( size_t i = 0 ; i < sString.length(); i++ )
+	{
+		// Is char space?
+		if ( sString.at( i ) == ' ' )
+		{
+			// Pick up space if filtered does not contain char as last.
+			if ( sFiltered.rbegin() == sFiltered.rend() )
+				sFiltered.push_back( sString.at( i ) );
+			else if ( * ( sFiltered.rbegin() ) != ' ' )
+				sFiltered.push_back( sString.at( i ) );
+		}
+		else
+			sFiltered.push_back( sString.at( i ) );
+	}
+
+	// Remove first and/or last character if it is space.
+	if ( sFiltered.begin() != sFiltered.end() )
+	{
+		if( * ( sFiltered.begin() ) == ' ' )
+			sFiltered.erase( 0, 1 );
+	}
+	if ( sFiltered.rbegin() != sFiltered.rend() )
+	{
+		if( * ( sFiltered.rbegin() ) == ' ' )
+			sFiltered.resize( sFiltered.length()-1 );
+	}
+	sString = sFiltered;
+}
+
+
+bool CATBase::hexToDec( string& sHex, unsigned int& iDec )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+	istringstream ss( sHex );
+	ss.setf( ios::hex, ios::basefield );
+	if( ( ss >> iDec ) )
+		return true;
+	return false;
+}
+
+bool CATBase::hexToDec( string& sHex, int& iDec )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+	istringstream ss( sHex );
+	ss.setf( ios::hex, ios::basefield );
+	if( ( ss >> iDec ) )
+		return true;
+	return false;
+}
+
+bool CATBase::hexToDec( string& sHex, unsigned long& ulDec )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+	istringstream ss( sHex );
+	ss.setf( ios::hex, ios::basefield );
+	if( ( ss >> ulDec ) )
+		return true;
+	return false;
+}
+
+bool CATBase::hexToDec( string& sHex, unsigned long long& ullDec )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+	istringstream ss( sHex );
+	ss.setf( ios::hex, ios::basefield );
+	if( ( ss >> ullDec ) )
+		return true;
+	return false;
+}
+
+/**
+* Used to create array of integer & hex value pairs.
+*/
+struct CHexMap
+{
+	char chr;
+	int value;
+};
+
+// -----------------------------------------------------------------------------
+// CATBase::_httoi
+// -----------------------------------------------------------------------------
+unsigned long CATBase::_httoi(const char *value)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::_httoi");
+	unsigned long l;
+	string s( value );
+	if ( CATBase::hexToDec( s, l ) )
+		return l;
+	return 0;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATBase::NumberToHexString(int)
+// -----------------------------------------------------------------------------
+string CATBase::NumberToHexString( unsigned int i )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::IntToHexString");
+	stringstream ss;
+	ss << "0x" << hex << i;
+	string retval; retval = ss.str().c_str();
+	return retval;
+}
+// -----------------------------------------------------------------------------
+// CATBase::NumberToHexString(long)
+// -----------------------------------------------------------------------------
+string CATBase::NumberToHexString( unsigned long i )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::IntToHexString");
+	stringstream ss;
+	ss << "0x" << hex << i;
+	string retval; retval = ss.str().c_str();
+	return retval;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsHexCharacter
+// -----------------------------------------------------------------------------
+bool CATBase::IsHexCharacter(const TCHAR *value)
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::IsHexCharacter");
+	const int HexMapL = 22;
+	CHexMap HexMap[HexMapL] =
+	{
+	    {'0', 0}, {'1', 1},
+		{'2', 2}, {'3', 3},
+		{'4', 4}, {'5', 5},
+		{'6', 6}, {'7', 7},
+		{'8', 8}, {'9', 9},
+		{'A', 10}, {'B', 11},
+		{'C', 12}, {'D', 13},
+		{'E', 14}, {'F', 15},
+		{'a', 10}, {'b', 11},
+		{'c', 12}, {'d', 13},
+		{'e', 14}, {'f', 15}
+	};
+	bool found = false;
+	for (int i = 0; i < HexMapL; i++)
+	{
+		if(HexMap[i].chr == *value)
+		{
+			found = true;
+			break;
+		}
+	}
+	return found;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsAscii(const char*,const unsigned int)
+// -----------------------------------------------------------------------------
+bool CATBase::IsAscii( const char* pInput, const unsigned int iLength )
+{
+	LOG_LOW_FUNC_ENTRY("CATBase::IsAscii");
+	bool bRet = true;
+	const char* pPoint = pInput;
+	for( unsigned int i = 0 ; i < iLength ; i++)
+	{
+		if(	!__isascii(*pPoint) )
+		{
+			bRet = false;
+			break;
+		}
+		pPoint++;
+	}
+	return bRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetEpocRoot( string& sEpocRoot )
+// -----------------------------------------------------------------------------
+bool CATBase::GetEpocRoot( string& sEpocRoot )
+{
+	LOG_FUNC_ENTRY( "CATBase::GetEpocRoot" );
+	bool bRet = true;
+	//Find EPOCROOT from environment variable
+	char* pEpocRoot = getenv ("EPOCROOT");
+	if( pEpocRoot == NULL )
+	{
+		const char pDevicesPath[] = "C:\\Program Files\\Common Files\\Symbian\\devices.xml";
+		CATParseXML parser;
+		//Find EPOCROOT from devices
+		sEpocRoot = parser.GetEpocRootPathFromXML(pDevicesPath);
+		if( sEpocRoot.empty() )
+		{
+			printf("EPOCROOT not set to environment variables.\n");
+			bRet = false;
+		}
+	}
+	else
+	{
+		sEpocRoot.append( pEpocRoot );
+		LOG_STRING( "EpocRoot :" << sEpocRoot );
+	}
+	//Remove trailing slash
+	if ( sEpocRoot.size() > 1 && sEpocRoot[ sEpocRoot.length()-1 ] == '\\' )
+		sEpocRoot.resize( sEpocRoot.length()-1 );
+	return bRet;
+}
+//End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATDatParser.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class responsible to parse data files
+*
+*/
+
+
+#include "../inc/CATDatParser.h"
+#include "../inc/CATProject.h"
+#include "../inc/CATModule2.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/catromsymbol.h"
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CATDatParser
+// Constructor only for testing!
+// (No module vector defined so no locating codelines / call stacks)
+// -----------------------------------------------------------------------------
+CATDatParser::CATDatParser()
+{
+	LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
+	Construct();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CATDatParser
+// Constructor
+// -----------------------------------------------------------------------------
+CATDatParser::CATDatParser(vector<CATModule2*>* pModules )
+{
+	LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
+	Construct();
+	m_pModules = pModules;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Construct
+// "Real" constructor
+// -----------------------------------------------------------------------------
+void CATDatParser::Construct()
+{
+	LOG_FUNC_ENTRY("CATDatParser::Construct");
+
+	m_iDataVersion = 1; // Default version of data.
+	m_bDllLoadFound = false;
+	m_bProcessStartFound = false;
+	m_bSubtestOnGoing = false;
+
+	m_DataSaver.InitXML();
+	
+	m_eBuildType = -2;
+	m_eProcess_state = not_started;
+	m_eProjectBuildType = -1;
+
+	m_iCurrentProcessId = 0;
+	m_iLeakNumber = 0;
+	m_iLogLevel = 3;
+	m_iOffSet = 0;
+
+	m_iPinPointedLeaks = 0;
+	m_iPinPointedSubTestLeaks = 0;
+	m_iSubtestStartHandleCount = 0;
+	m_iSuccesfullRuns = 0;
+	m_iTotalNumberOfLeaks = 0;
+	m_iTotalRuns = 0;
+
+	m_pRomSymbol = 0;
+	m_pModules = 0;
+
+	m_sCurrentProcessName = "";
+	m_sInputFile = "";
+	m_sInputFileTemp = "";
+	m_sOutputFile = "";
+	m_sProjectPlatform = "";
+	m_vRomSymbolFiles.clear();
+	m_vDllLoadModList.clear();
+	m_vDllLoadModListSubTest.clear();
+	m_vHandleLeaks.clear();
+	m_vMemoryAddress.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::~CATDatParser
+// Destructor
+// -----------------------------------------------------------------------------
+CATDatParser::~CATDatParser()
+{
+	LOG_FUNC_ENTRY("CATDatParser::~CATDatParser");
+
+	if ( m_In.is_open() )
+		m_In.close();
+	// Delete temporary input file if any
+	if ( !m_sInputFileTemp.empty() )
+	{
+		if ( FileExists( m_sInputFileTemp.c_str() ) )
+			FileDelete( m_sInputFileTemp, false );
+	}
+	// Clean memory addresses if any
+	CleanMemoryAddresses();
+	// Delete rom symbol.
+	if ( m_pRomSymbol )
+	{
+        delete m_pRomSymbol;
+		m_pRomSymbol = NULL;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Analyze
+// Analyze given data file
+// -----------------------------------------------------------------------------
+int CATDatParser::Analyze()
+{
+	LOG_FUNC_ENTRY("CATDatParser::Analyze");
+	// Return if input file not set
+	if ( m_sInputFile.empty() )
+		return AT_RETURN_CODE::INVALID_DATA_FILE;
+	// If open close first
+	if ( m_In.is_open() )
+		m_In.close();
+	// Open file
+	m_In.open( m_sInputFile.c_str() );
+	if ( ! m_In.good() )
+		return AT_RETURN_CODE::INVALID_DATA_FILE;
+	try {
+		// If rom symbol file specified.
+		if ( ! m_vRomSymbolFiles.empty() )
+		{
+			// Create new rom symbol file "parser".
+			m_pRomSymbol = new CATRomSymbol();
+			m_pRomSymbol->m_bShowProgressMessages = true;
+			// Set symbol files.
+			if ( ! m_pRomSymbol->SetSymbols( m_vRomSymbolFiles ) )
+			{
+				cout << AT_MSG << "Rom/Rofs symbols error: " << m_pRomSymbol->GetError() << endl;
+				// If file open fails we delete it and will not use it.
+				delete m_pRomSymbol;
+				m_pRomSymbol = NULL;
+				cout << AT_MSG << "Analyze aborted." << endl;
+				return AT_RETURN_CODE::SYMBOL_FILE_ERROR;
+			}
+		}
+		// Return code
+		int iRet = 0;
+		// Clear variables
+		ClearParsingVariables();
+		// If output defined disable printing
+		if ( ! m_sOutputFile.empty() )
+			m_DataSaver.SetPrintFlag( false );
+		// Header
+		Header();
+		// Parsing
+		iRet = Parse();
+		// Footer
+		if ( iRet == AT_RETURN_CODE::OK )
+			Footer();
+		// If output defined save xml
+		if ( ! m_sOutputFile.empty() )
+			m_DataSaver.SaveLinesToFile( m_sOutputFile.c_str(), XML_DATA );
+		// Return
+		return iRet;
+	} catch ( int i )
+	{
+		cout << AT_MSG << "Error, Analyze failed. : " << i << endl;
+		return AT_RETURN_CODE::UNHANDLED_EXCEPTION;
+	}
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::Header
+// Print header of report
+// -----------------------------------------------------------------------------
+void CATDatParser::Header()
+{
+	LOG_FUNC_ENTRY("CATDatParser::Header");
+	// Analyze report header
+	m_DataSaver.AddString( "Atool.exe v." );
+	m_DataSaver.AddString( ATOOL_VERSION );
+	m_DataSaver.AddString( "\n" );
+	m_DataSaver.AddString( "Analyzing memory leaks..." );
+	m_DataSaver.AddLineToLast();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Footer
+// Print footer of report
+// -----------------------------------------------------------------------------
+void CATDatParser::Footer()
+{
+	LOG_FUNC_ENTRY("CATDatParser::Footer");
+	m_DataSaver.AddString( "\nTotal Runs: " );
+	m_DataSaver.AddInteger( m_iTotalRuns );
+	m_DataSaver.AddLineToLast();
+
+	int iFailedRuns = m_iTotalRuns - m_iSuccesfullRuns;
+	m_DataSaver.AddString( "Failed Runs: " );
+	m_DataSaver.AddInteger( iFailedRuns );
+	m_DataSaver.AddLineToLast();
+
+	char cTemp[128];
+	string sResult( itoa( m_iTotalRuns, cTemp, 10 ) );
+	sResult.append( ";" );
+	sResult.append( itoa( iFailedRuns, cTemp, 10 ) );
+	sResult.append( ";" );
+
+	m_DataSaver.SaveXML( sResult, RESULT );
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ClearParsingVariables
+// Clear/Reset all member variables related to parsing data file
+// -----------------------------------------------------------------------------
+void CATDatParser::ClearParsingVariables()
+{
+	LOG_FUNC_ENTRY("CATDatParser::ClearParsingVariables");
+	// Clear variables related to analyze
+	m_eProcess_state = not_started;
+	m_bProcessStartFound = false;
+	m_bDllLoadFound = false;
+	m_iTotalNumberOfLeaks = 0;
+	m_iPinPointedLeaks = 0;
+	m_iLeakNumber = 0;
+	m_iTotalRuns = 0;
+	m_iSuccesfullRuns = 0;
+	m_bSubtestOnGoing = false;
+	m_iSubtestStartHandleCount = 0;
+	CleanMemoryAddresses();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Parse
+// Parses data file. Note! header and footer of the report are done in 
+// separate functions.
+// -----------------------------------------------------------------------------
+int CATDatParser::Parse()
+{
+	LOG_FUNC_ENTRY("CATDatParser::Parse");
+	// Read all lines
+	char cLine[MAX_LINE_LENGTH];
+	do
+	{
+		string sLine;
+		try {
+			m_In.getline( cLine, MAX_LINE_LENGTH );
+			sLine = cLine ;
+		} catch(...)
+		{
+			LOG_STRING( AT_MSG << "Unexpected error, reading data file." );
+			continue;
+		}
+		if( sLine.find( LABEL_DATA_FILE_VERSION ) != string::npos )
+		{
+			// Check data file version
+			if(  sLine.find( AT_DATA_FILE_VERSION ) == string::npos )
+			{
+				return AT_RETURN_CODE::WRONG_DATA_FILE_VERSION;
+			}
+		}
+		else if( sLine.find( LABEL_PROCESS_START ) != string::npos )
+		{
+			if ( ! ParseProcessStart( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_DLL_LOAD ) != string::npos )
+		{
+			if ( ! ParseDllLoad( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_DLL_UNLOAD ) != string::npos )
+		{
+			if ( ! ParseDllUnload( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_MEM_LEAK ) != string::npos)
+		{
+			if ( ! ParseMemLeak( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_PROCESS_END ) != string::npos )
+		{
+			if ( ! ParseProcessEnd( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_ERROR_OCCURED ) != string::npos )
+		{
+			if ( ! ParseErrorOccured( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_HANDLE_LEAK ) != string::npos )
+		{
+			if ( ! ParseHandleLeak( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_TEST_START ) != string::npos )
+		{
+			if ( ! ParseTestStart( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_TEST_END ) != string::npos )
+		{
+			if ( ! ParseTestEnd( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+		else if( sLine.find( LABEL_LOGGING_CANCELLED ) != string::npos )
+		{
+			if ( ! ParseLoggingCancelled( sLine ) )
+				return AT_RETURN_CODE::ANALYZE_ERROR;
+		}
+	}
+	while( m_In.good() );
+	// Message of failed run if process start was last line in data.
+	if ( m_eProcess_state == ongoing )
+	{
+		m_DataSaver.AddString( "Test run failed.\n" );
+		m_DataSaver.AddLineToLast();
+	}
+	return AT_RETURN_CODE::OK;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseProcessStart
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseProcessStart( string& sLine)
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseProcessStart");
+	if ( m_eProcess_state == ongoing )
+	{
+		m_DataSaver.AddString( "Test run failed.\n" );
+		m_DataSaver.AddLineToLast();
+	}
+	m_eProcess_state = ongoing;
+	m_bProcessStartFound = true;
+
+	// Clear handle leaks
+	m_vHandleLeaks.clear();
+	// Increment runs
+	m_iTotalRuns++;
+	// Clean leak count
+	m_iTotalNumberOfLeaks = 0;
+	// Clean pin pointed leaks count.
+	m_iPinPointedLeaks = 0;
+	// Clean leak number
+	m_iLeakNumber = 0;
+
+	// Clean loaded mods
+	m_vDllLoadModList.clear();
+	m_vDllLoadModListSubTest.clear();
+
+	// Skip text PROCESS_START
+	GetStringUntilNextSpace( sLine );
+	// Get process name
+	m_sCurrentProcessName = GetStringUntilNextSpace( sLine );
+	// Get Pid
+	string sPid = GetStringUntilNextSpace( sLine );
+	m_iCurrentProcessId = _httoi( sPid.c_str() );
+
+	// Header for process tart
+	m_DataSaver.AddString( "\n--------------------------------\n" );
+	m_DataSaver.AddString( "Test Run start (" );
+	m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
+	m_DataSaver.AddString( "): " );
+
+	// Get start time
+	string sTime = GetStringUntilNextSpace( sLine );
+	sTime = ConvertTimeToLocalTime( sTime );
+	m_DataSaver.AddString( sTime.c_str() );
+
+	// Create data for xml
+	string sData( sTime );
+	sData.append( ";" );
+	
+	// Build mode UDEB/UREL.
+	string sBuildType = GetStringUntilNextSpace( sLine );
+
+	m_DataSaver.AddString( " Build target: " );
+	if( sBuildType.compare( "0" ) == 0 )
+	{
+		m_eBuildType = CATProject::UREL;
+	}
+	else if( sBuildType.compare( "1" ) == 0 )
+	{
+		m_eBuildType = CATProject::UDEB;
+	}
+	m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
+
+	// Version.
+	string sVersion = GetStringUntilNextSpace( sLine );
+	unsigned int iVer = 0;
+	if ( hexToDec( sVersion, iVer ) && iVer != 0 )
+		m_iDataVersion = iVer;
+
+	// End line in data.
+	m_DataSaver.AddLineToLast();
+	
+	// xml
+	sData.append( CATProject::GetBuildTypeString( m_eBuildType ) );
+	sData.append( ";" );
+	sData.append( m_sCurrentProcessName );
+	m_DataSaver.SaveXML( sData, RUN );
+
+	// If projects platform defined check that it is same in data. (future feature).
+	if ( ! m_sProjectPlatform.empty() )
+	{
+		// If platform info is added to data file do check here.
+	}
+	// If projects build type defined check that it is same in data.
+	if ( m_eProjectBuildType != -1 )
+	{
+		if ( m_eBuildType != m_eProjectBuildType )
+		{
+			string sError(AT_MSG);
+			sError.append( "Error, analyzed data has build type of " );
+			sError.append( CATProject::GetBuildTypeString( m_eBuildType ) );
+			sError.append( " and project has build type " );
+			sError.append( CATProject::GetBuildTypeString( m_eProjectBuildType ) );
+			sError.append( ". Pinpointed code lines are not valid." );
+			m_DataSaver.AddString( sError.c_str(), false );
+			m_DataSaver.AddLineToLast();
+		}
+	}
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseProcessEnd
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseProcessEnd( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseProcessEnd");
+	GetStringUntilNextSpace( sLine );
+
+	// Get process id
+	string sProcessID = GetStringUntilNextSpace( sLine );
+	unsigned long iProcessID = _httoi( sProcessID.c_str() );
+
+	// Get time
+	string sTime = GetStringUntilNextSpace( sLine );
+
+	// Convert leak time
+	sTime = ConvertTimeToLocalTime( sTime );
+
+	// Process started?
+	if( iProcessID == m_iCurrentProcessId )
+	{
+		m_iSuccesfullRuns++;
+		m_DataSaver.AddLineToLast();
+		m_DataSaver.AddString( "Test Run end (" );
+		m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
+		m_DataSaver.AddString( "): " );
+		m_DataSaver.AddString( sTime.c_str() );
+		m_DataSaver.AddLineToLast();
+		m_DataSaver.AddString( "Build target: " );
+		m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
+		m_DataSaver.AddLineToLast();
+
+		m_eProcess_state = stopped;
+		// Number of leaks
+		if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+		{
+			if ( m_iPinPointedLeaks > 0 )
+			{
+				m_DataSaver.AddInteger( m_iPinPointedLeaks );
+				m_DataSaver.AddString( " number of pinpointed memory leak(s)." );
+				m_DataSaver.AddLineToLast();
+			}
+			m_DataSaver.AddInteger( m_iLeakNumber );
+			m_DataSaver.AddString( " total number of memory leak(s)." );
+			m_DataSaver.AddLineToLast();
+		}
+		else
+		{
+			m_DataSaver.AddInteger( m_iTotalNumberOfLeaks );
+			m_DataSaver.AddString( " memory leak(s) found." );
+			m_DataSaver.AddLineToLast();
+		}
+		
+		// xml
+		char cTemp[128];
+		m_DataSaver.SaveXML( itoa( m_iTotalNumberOfLeaks, cTemp, 10 ) , MEM_LEAKS );
+
+		// Print all modules which have leaks
+		for( size_t i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+		{
+			if( m_vDllLoadModList.at(i).iLeaks > 0 )
+			{
+				m_DataSaver.AddInteger( m_vDllLoadModList.at(i).iLeaks );
+				m_DataSaver.AddString( " memory leak(s) in module: " );
+				m_DataSaver.AddString( m_vDllLoadModList.at(i).sModuleName.c_str() );
+				m_DataSaver.AddLineToLast();
+
+				// xml
+				string sModuleNameAndLeaks( m_vDllLoadModList[i].sModuleName );
+				sModuleNameAndLeaks.append(";");
+				sModuleNameAndLeaks.append( itoa( m_vDllLoadModList[i].iLeaks, cTemp, 10 ) );
+				m_DataSaver.SaveXML( sModuleNameAndLeaks , MEM_LEAK_MODULE );
+			}
+		}
+		
+		if ( m_vHandleLeaks.size() > 0 )
+		{
+			// We have handle leaks
+			bool bHandLeaksFound = false;
+			int iTotalNrOfLeaks = 0;
+			// Print handle leaks
+			for( size_t i = 0 ; i < m_vHandleLeaks.size() ; i++ )
+			{
+				string sTempHandleLeak( m_vHandleLeaks[i] );
+				// Name.
+				string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) );
+				// Count.
+				string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) );
+				unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() );
+				iTotalNrOfLeaks += iNrOfLeaks;
+				if( iNrOfLeaks )
+				{
+					if( !bHandLeaksFound )
+					{
+						m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS );
+					}
+					bHandLeaksFound = true;
+					m_DataSaver.AddInteger( iNrOfLeaks );
+					// Just print out how many leaks found.
+					// Because its always unknown.
+					m_DataSaver.AddString( " handle leak(s) found." );
+					m_DataSaver.AddLineToLast();
+
+					// xml
+					string sXMLInfo( sHandleLeakModule );
+					sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks );
+					m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE );
+				}
+			}
+			// Update number if handle leaks
+			m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS );
+			if( !bHandLeaksFound )
+			{
+				//m_DataSaver.AddLineToLast();
+				m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+				m_DataSaver.AddLineToLast();
+			}
+		}
+		else
+		{
+			// No handle leaks
+			m_DataSaver.AddLineToLast();
+			m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+			m_DataSaver.AddLineToLast();
+		}
+
+		// Process end to xml
+		m_DataSaver.SaveXML( sTime, RUN_END );
+		// Reset current process
+		m_iCurrentProcessId = 0;
+	}
+	
+	// If no dll load or process start found
+	if ( ! m_bProcessStartFound || !m_bDllLoadFound )
+	{
+		m_DataSaver.AddLineToLast();
+		m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA );
+		m_DataSaver.AddLineToLast();
+	}
+	
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseDllLoad
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseDllLoad( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad");
+	//DLL_LOAD <DLL name> <Time stamp> <Memory start address> <Memory end address>
+	m_bDllLoadFound = true;
+	DLL_LOAD_INFO structDllInfo;
+	structDllInfo.iStartAddress = 0;
+	structDllInfo.iEndAddress = 0;
+	structDllInfo.iLeaks = 0;
+
+	// Skip "DLL_LOAD "
+	GetStringUntilNextSpace( sLine );
+
+	// Get module name
+	structDllInfo.sModuleName = GetStringUntilNextSpace( sLine );
+	ChangeToLower( structDllInfo.sModuleName );
+
+	// Create module from this if project platform emulator
+	if ( _stricmp( "winscw", m_sProjectPlatform.c_str() ) == 0 )
+		CreateWinscwModule( structDllInfo.sModuleName );
+
+	if ( m_iDataVersion >= AT_DLL_TIMESTAMP_DATA_VERSION )
+	{
+		// Pickup module loading time.
+		string sLoadTime = GetStringUntilNextSpace( sLine );
+		unsigned long long ull;
+		if ( hexToDec( sLoadTime, ull ) )
+			structDllInfo.iLoadTime = ull;
+	}
+
+	// Get dll start memory string address from line
+	// Convert string address to real memory address
+	structDllInfo.iStartAddress = 
+		_httoi( GetStringUntilNextSpace( sLine ).c_str() );
+
+	// Get dll end memory string address from line
+	// Convert string address to real memory address
+	structDllInfo.iEndAddress = 
+		_httoi( 
+		GetStringUntilNextSpace( sLine ).c_str() );
+
+	// Is module already loaded, if not add it to list.
+	bool bFound = false;
+	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModList.begin();
+		it != m_vDllLoadModList.end() ; it++ )
+	{
+		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
+		{
+			bFound = true;
+			break;
+		}
+	}
+	if( ! bFound )
+		m_vDllLoadModList.push_back( structDllInfo );
+
+	// Sub test module list.
+	bFound = false;
+	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModListSubTest.begin();
+		it != m_vDllLoadModListSubTest.end() ; it++ )
+	{
+		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
+		{
+			bFound = true;
+			break;
+		}
+	}
+	if( ! bFound )
+		m_vDllLoadModListSubTest.push_back( structDllInfo );
+
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseDllUnload
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseDllUnload( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseDllUnload");
+
+	// Ignore unloads on older version because no timestamps.
+	if ( m_iDataVersion < AT_DLL_TIMESTAMP_DATA_VERSION )
+	{
+		return true;
+	}
+
+	// Skip "DLL_UNLOAD "
+	GetStringUntilNextSpace( sLine );
+
+	// Get module name
+	string sModuleName = GetStringUntilNextSpace( sLine );
+	ChangeToLower( sModuleName );
+
+	// Unload time
+	unsigned long long ull;
+	string sUnload = GetStringUntilNextSpace( sLine );
+	if ( ! hexToDec( sUnload, ull ) )
+		return true;
+
+	// Set module unload time.
+	vector<DLL_LOAD_INFO>::iterator it;
+	for( it = m_vDllLoadModList.begin() ; it != m_vDllLoadModList.end() ; it++ )
+	{
+		if ( sModuleName.compare( it->sModuleName ) == 0 )
+		{
+			(*it).iUnloadTime = ull;
+			break;
+		}
+	}
+	for( it = m_vDllLoadModListSubTest.begin() ; it != m_vDllLoadModListSubTest.end() ; it++ )
+	{
+		if ( sModuleName.compare( it->sModuleName ) == 0 )
+		{
+			(*it).iUnloadTime = ull;
+			break;
+		}
+	}
+	return true;
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseLoggingCancelled
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseLoggingCancelled( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseLoggingCancelled");
+	// Skip text "LOGGING_CANCELLED"
+	GetStringUntilNextSpace( sLine );
+
+	// Get time
+	string sTime( GetStringUntilNextSpace( sLine ) );
+	sTime = ConvertTimeToLocalTime( sTime );
+	m_DataSaver.AddString( "Logging Cancelled." );
+	m_DataSaver.AddLineToLast();
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseHandleLeak
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseHandleLeak( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseHandleLeak");
+	// Skip text "HANDLE_LEAK"
+	GetStringUntilNextSpace( sLine );
+	m_vHandleLeaks.push_back( sLine );
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseTestStart
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseTestStart( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseTestStart");
+	m_bSubtestOnGoing = true;
+	m_iLeakNumber = 0;
+	m_iPinPointedSubTestLeaks = 0;
+
+	// Reset subtest leaked modules list
+	for( size_t i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
+	{
+		m_vDllLoadModListSubTest.at(i).iLeaks = 0;
+	}
+
+	// Skip text "TEST_START"
+	GetStringUntilNextSpace( sLine );
+	// Time
+	string sTime( GetStringUntilNextSpace( sLine ) );
+	sTime = ConvertTimeToLocalTime( sTime );
+	// Name
+	string sSubTestName( GetStringUntilNextSpace( sLine ) );				
+	m_DataSaver.AddLineToLast();
+
+	// Get handle count in subtest start
+	string sSubTestStartHandleCount( GetStringUntilNextSpace( sLine ) );
+	m_iSubtestStartHandleCount = atoi( sSubTestStartHandleCount.c_str() );
+
+	// Add start to report
+	m_DataSaver.AddString( "\nSub test (" );
+	m_DataSaver.AddString( sSubTestName.c_str() );
+	m_DataSaver.AddString( ") start: " );
+	m_DataSaver.AddString( sTime.c_str() );
+
+	// m_DataSaver.AddLineToLast();
+
+	// Add start to xml
+	string sResult( sSubTestName );
+	sResult.append( ";" );
+	sResult.append( sTime );
+	sResult.append( ";" );
+	m_DataSaver.SaveXML( sResult, TEST_START );
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseTestEnd
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseTestEnd( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseTestEnd");
+	// Skip text "TEST_END"
+	GetStringUntilNextSpace( sLine );
+
+	// Time
+	string sTime( GetStringUntilNextSpace( sLine ) );
+	sTime = ConvertTimeToLocalTime( sTime );
+
+	// Name
+	string sSubTestName( GetStringUntilNextSpace( sLine ) );
+	m_DataSaver.AddLineToLast();
+
+	// Add test end info to report
+	m_DataSaver.AddString( "Sub test (" );
+	m_DataSaver.AddString( sSubTestName.c_str() );
+	m_DataSaver.AddString( ") end: " );
+	m_DataSaver.AddString( sTime.c_str() );
+	m_DataSaver.AddLineToLast();
+
+	// Leak count to report in subtest
+	if( m_iLeakNumber > 0 )
+	{
+		if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+		{
+			m_DataSaver.AddInteger( m_iPinPointedSubTestLeaks );
+			m_DataSaver.AddString( " number of pinpointed memory leaks." );
+			m_DataSaver.AddLineToLast();
+			m_DataSaver.AddInteger( m_iLeakNumber );
+			m_DataSaver.AddString( " memory leaks found." );
+		}
+		else
+		{
+			m_DataSaver.AddInteger( m_iLeakNumber );
+			m_DataSaver.AddString( " memory leaks found." );
+		}
+	}
+	else
+	{
+		m_DataSaver.AddString( "No memory leaks found." );
+	}
+	m_DataSaver.AddLineToLast();
+
+	// Use sTime to store info to xml
+	sTime.append(";");
+	char cTemp[128];
+	// Print all modules whitch have leaks
+	for( unsigned int i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
+	{
+		if( m_vDllLoadModListSubTest.at(i).iLeaks > 0 )
+		{
+			// Normal report
+			m_DataSaver.AddInteger( m_vDllLoadModListSubTest[i].iLeaks );
+			m_DataSaver.AddString( " memory leaks in module: " );
+			m_DataSaver.AddString( m_vDllLoadModListSubTest.at(i).sModuleName.c_str() );
+			m_DataSaver.AddLineToLast();
+			// xml
+			string sModuleNameAndLeaks( m_vDllLoadModListSubTest.at(i).sModuleName );
+			sModuleNameAndLeaks.append(";");
+			sModuleNameAndLeaks.append( itoa( m_vDllLoadModListSubTest.at(i).iLeaks, cTemp, 10 ) );
+			m_DataSaver.SaveXML( sModuleNameAndLeaks , SUBTEST_MEM_LEAK_MODULE );
+		}
+	}
+	// Handle count
+	int iEndHandleCount = atoi( GetStringUntilNextSpace( sLine ).c_str() );
+	// Is there handle leaks in subtest?
+	if( iEndHandleCount > m_iSubtestStartHandleCount )
+	{
+		// Print normal report
+		m_DataSaver.AddInteger( iEndHandleCount - m_iSubtestStartHandleCount );
+		m_DataSaver.AddString( " handle leaks in subtest: " );
+		m_DataSaver.AddString( sSubTestName.c_str() );
+		m_DataSaver.AddString( "." );
+		m_DataSaver.AddLineToLast();
+
+		// Print handle leaks to XML
+		string sNrOfHandleLeaks( itoa( iEndHandleCount - m_iSubtestStartHandleCount, cTemp, 10 ) );
+		sNrOfHandleLeaks.append( ";" );
+		m_DataSaver.SaveXML( sNrOfHandleLeaks, SUBTEST_HANDLE_LEAKS );
+	}
+	else
+	{
+		// No handle leaks
+		m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+		m_DataSaver.AddLineToLast();
+	}
+	// Save xml
+	m_DataSaver.SaveXML( sTime, TEST_END );
+	// Back to normal leaks
+	m_bSubtestOnGoing = false;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseErrorOccured
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseErrorOccured( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseErrorOccured");
+	string sTime,sError;
+
+	// Skip text "ERROR_OCCURED:"
+	GetStringUntilNextSpace( sLine );
+
+	// Get error
+	sError = GetStringUntilNextSpace( sLine );
+	// Get and convert error time
+	sTime = GetStringUntilNextSpace( sLine );
+	sTime = ConvertTimeToLocalTime( sTime );
+
+	// Print error line
+	m_DataSaver.AddLineToLast();
+	m_DataSaver.AddString( "Error occured on: " );
+	m_DataSaver.AddString( sTime.c_str() );
+	m_DataSaver.AddString( ". " );
+	m_DataSaver.AddString( "Symbian error code: " );
+	m_DataSaver.AddString( sError.c_str() );
+	m_DataSaver.AddString( "." );
+	m_DataSaver.AddLineToLast();
+
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseMemLeak
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseMemLeak( string& sLine )
+{
+	LOG_FUNC_ENTRY("CATDatParser::ParseMemLeak");
+	// Increment leak count
+	if ( ! m_bSubtestOnGoing )
+		m_iTotalNumberOfLeaks++;
+
+	// Increase leak number
+	m_iLeakNumber++;
+
+	// Leak data variables
+	string sModuleName;
+	string sLeakSize;
+	string sTime;
+	unsigned long long iTime = 0;
+	string sLeakAddress;
+	
+	// Skip text "MEM_LEAK"
+	GetStringUntilNextSpace( sLine );
+	// Get leak address
+	sLeakAddress = GetStringUntilNextSpace( sLine );
+	// Get time
+	sTime = GetStringUntilNextSpace( sLine );
+	// Convert time to decimal
+	hexToDec( sTime, iTime );
+	// Get memory reserve size
+	sLeakSize = GetStringUntilNextSpace( sLine );
+	// Convert leak time
+	sTime = ConvertTimeToLocalTime( sTime );
+
+	// Loop thru call stack and put memory addresses in vector
+	CleanMemoryAddresses(); // Clean memory address vector
+	CATMemoryAddress* pMemAddr = 0;
+	vector<string> vStrings = ParseStringToVector( sLine, ' ' );
+	for( size_t i = 0; i < vStrings.size() ; i++ )
+	{
+		pMemAddr = new CATMemoryAddress( vStrings.at(i), m_iOffSet );
+		// Set address time
+		pMemAddr->SetTime( iTime );
+		// Set address module name
+		if ( pMemAddr->FindSetModuleName( &m_vDllLoadModList ) )
+		{
+			// Increment leaks in module once
+			if ( sModuleName.empty() )
+			{
+				if ( m_bSubtestOnGoing )
+					m_vDllLoadModListSubTest.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
+				else
+					m_vDllLoadModList.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
+				// Set leak's module where it was located.
+				sModuleName = pMemAddr->GetModuleName();
+			}
+		}
+		// Add it to vector
+		m_vMemoryAddress.push_back( pMemAddr );
+	}
+	// If logging level is 0 Skip printing / locating code lines for call stack items.
+	if ( m_iLogLevel == 0 )
+		return true;
+	if ( m_pModules && vStrings.size() > 0 )
+	{
+		// Have we successfully located code line for memory address
+		bool bSuccesfullAddressToLine = false;
+		for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
+		{
+			int iIndexInDll = m_vMemoryAddress.at( x )->GetDllLoadInfoIndex();
+			if ( iIndexInDll != -1 )
+			{
+				// Dll module name from data file
+				string sDllName = m_vDllLoadModList.at( iIndexInDll ).sModuleName;
+				// Find module from project. These are read from makefiles.
+				for ( size_t y = 0; y < m_pModules->size() ; y++ )
+				{
+					// Module name from project data (makefiles)
+					string sModuleName = m_pModules->at( y )->GetBinaryName();
+					// If we find module from project ones, use it to located code line for memory address
+					// Note! dll names can be pretty messy i.e. DLL_LOAD 10281fc6.dll{000a0000}[10281fc6] 81d57b88 81e60a90
+					if ( sDllName.find( sModuleName ) != string::npos )
+					{
+						m_pModules->at( y )->AddressToLine( m_vMemoryAddress.at( x ) );
+						if ( ! bSuccesfullAddressToLine )
+						{
+							int iPPState = m_vMemoryAddress.at( x )->GetAddressToLineState();
+							if ( iPPState == CATMemoryAddress::EXACT || iPPState == CATMemoryAddress::FUNCTION )
+							{
+								bSuccesfullAddressToLine = true;
+								if ( m_bSubtestOnGoing )
+									m_iPinPointedSubTestLeaks++;
+								else
+									m_iPinPointedLeaks++;
+							}
+						}
+					}
+				}
+			}
+		}
+		// If rom/rofs specified we use it to try get binary and function names
+		// for addresses currently out of process range.
+		if ( m_pRomSymbol )
+		{
+			for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
+			{
+				if ( m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS
+					|| m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_RANGE )
+				{
+					m_pRomSymbol->AddressToLine( m_vMemoryAddress.at(x) );
+				}
+			}
+		}
+	}
+	// Print leak
+	PrintMemLeak( sTime, sLeakSize, sLeakAddress, sModuleName);
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::PrintMemLeak
+// -----------------------------------------------------------------------------
+void CATDatParser::PrintMemLeak(const string& sTime,
+							   const string& sLeakSize,
+							   const string& sLeakAddr,
+							   const string& sModuleName)
+{
+	LOG_FUNC_ENTRY("CATDatParser::PrintMemLeak");
+	// Print header data of leak
+	m_DataSaver.AddString("\nMemory leak ");
+	m_DataSaver.AddInteger( m_iLeakNumber, true);
+
+	// Leak size
+	m_DataSaver.AddString( " (" );
+	m_DataSaver.AddInteger( _httoi( sLeakSize.c_str() ), true );
+	m_DataSaver.AddString( " bytes) " );
+
+	// Leak address
+	m_DataSaver.AddString("(0x");
+	m_DataSaver.AddString( sLeakAddr.c_str(), true );
+	m_DataSaver.AddString( ") " );
+
+	// Time
+	m_DataSaver.AddString( sTime.c_str(), true );
+	m_DataSaver.AddString( " " );
+	
+	// Module name
+	m_DataSaver.AddString( sModuleName.c_str(), true );
+	m_DataSaver.SaveCarbideDataHeader();
+	
+	// Add header line
+	m_DataSaver.AddLineToLast();
+
+	// Print the call stack items
+	for( size_t i = 0 ; i < m_vMemoryAddress.size() ; i++ )
+	{
+		// On log levels 1 & 2 we only print located code lines.
+		#ifndef ADDR2LINE
+		if( 
+			( m_iLogLevel == 1 || m_iLogLevel == 2 )
+			&&
+			( m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT
+			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::FUNCTION )
+			)
+		{
+			// Skips to next
+			continue;
+		}
+		#endif
+		#ifdef ADDR2LINE
+		if( ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT )
+		{
+			// Skips to next
+			continue;
+		}
+		#endif
+		else if ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS )
+		{
+			// Is memory address out of modules range
+			string sTemp;
+			sTemp.append( m_vMemoryAddress.at(i)->GetAddressString() );
+			sTemp.append( " Address out of process memory.");
+			m_DataSaver.AddString( sTemp.c_str(), true );
+			m_DataSaver.AddLineToLast();
+			continue;
+		}
+		
+		// Print memory address
+		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetAddressString().c_str(), true );
+
+		// Space (only for console output)
+		m_DataSaver.AddString( " " );
+
+		m_DataSaver.AddCarbideData( 
+			NumberToHexString( m_vMemoryAddress.at(i)->GetOffSetFromModuleStart() ) );
+
+		// Module name
+		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetModuleName().c_str(), true );
+
+		// Print call stack memory address details depending on state of memory address
+		switch( m_vMemoryAddress.at(i)->GetAddressToLineState() )
+		{
+			// Address outside of known processes
+		case CATMemoryAddress::OUT_OF_PROCESS:
+			m_DataSaver.AddLineToLast();
+			break;
+			// Address located outside of known modules symbols
+		case CATMemoryAddress::OUT_OF_RANGE:
+			m_DataSaver.AddString( " " );
+			m_DataSaver.AddString( "???", true );
+			m_DataSaver.AddLineToLast();
+			break;
+		// Symbol state is currently used when using rom symbol file.
+		// From it we get module name & function name.
+		case CATMemoryAddress::SYMBOL:
+			m_DataSaver.AddString( " " );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+			if ( ! m_vMemoryAddress.at( i )->GetFileName().empty() )
+			{
+				m_DataSaver.AddString( " (" );
+				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+				m_DataSaver.AddString( ")" );
+			}
+			m_DataSaver.AddLineToLast();
+			break;
+		// Lst & Map implementation
+		#ifndef ADDR2LINE
+		case CATMemoryAddress::FUNCTION:
+		case CATMemoryAddress::EXACT:
+			m_DataSaver.AddString( " " );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+			// Small difference displaying details depending on build urel/udeb
+			if ( m_eBuildType == CATProject::UREL )
+			{
+				// UREL
+				// Set build info to data saver
+				m_DataSaver.SetBuild( false );
+				// urel = functionname: linenumber (filename)
+				m_DataSaver.AddString( ": " );
+				if (  m_vMemoryAddress.at(i)->GetFunctionLineNumber() != -1 )
+					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
+				else if (  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+				m_DataSaver.AddString( " (" );
+				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+				m_DataSaver.AddString( ")" );
+				m_DataSaver.AddLineToLast();
+			}
+			else
+			{
+				// UDEB
+				// udeb = functionname: (filename:linenumber)
+				m_DataSaver.AddString( " (" );
+				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+				m_DataSaver.AddString( ":" );
+				if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+				else
+					m_DataSaver.AddString( "???", true );
+				m_DataSaver.AddString( ")" );
+				m_DataSaver.AddLineToLast();
+			}
+			break;
+		#endif
+		// addr2line implementation (new).
+		#ifdef ADDR2LINE
+		case CATMemoryAddress::FUNCTION:
+			m_DataSaver.AddString( " " );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+			m_DataSaver.AddString( " (" );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+			m_DataSaver.AddString( ":" );
+			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
+			else
+				m_DataSaver.AddString( "???", true );
+			m_DataSaver.AddString( ")" );
+			m_DataSaver.AddLineToLast();
+			break;
+		case CATMemoryAddress::EXACT:
+			m_DataSaver.AddString( " " );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+			m_DataSaver.AddString( " (" );
+			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+			m_DataSaver.AddString( ":" );
+			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+			else
+				m_DataSaver.AddString( "???", true );
+			m_DataSaver.AddString( ")" );
+			m_DataSaver.AddLineToLast();
+			break;
+		#endif
+		} // End switch
+		// On logging level 1 we only print one located code line
+		#ifndef ADDR2LINE
+		if ( m_iLogLevel == 1 && ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT ||
+			m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::FUNCTION ) )
+			break;
+		#endif
+		#ifdef ADDR2LINE
+		if ( m_iLogLevel == 1 && m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT )
+			break;
+		#endif
+	} // End call stack items loop
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetInputFile
+// -----------------------------------------------------------------------------
+void CATDatParser::SetInputFile(const string& sInputFile)
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetInputFile");
+	m_sInputFile = sInputFile;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetOutputFile
+// -----------------------------------------------------------------------------
+void CATDatParser::SetOutputFile(const string& sOutpuFile)
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetOutputFile");
+	m_sOutputFile = sOutpuFile;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetRomSymbolFiles
+// -----------------------------------------------------------------------------
+void CATDatParser::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetRomSymbolFiles");
+	m_vRomSymbolFiles = vRomSymbolFiles;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetLogLevel
+// -----------------------------------------------------------------------------
+void CATDatParser::SetLogLevel(int iLogLevel)
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetLogLevel");
+	m_iLogLevel = iLogLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::GetLogLevel
+// -----------------------------------------------------------------------------
+int CATDatParser::GetLogLevel() const
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::GetLogLevel");
+	return m_iLogLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CleanMemoryAddresses
+// -----------------------------------------------------------------------------
+void CATDatParser::CleanMemoryAddresses()
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::CleanMemoryAddresses");
+	// Cleanup memory addressses.
+	for( vector<CATMemoryAddress*>::iterator it = m_vMemoryAddress.begin(); it != m_vMemoryAddress.end(); it++ )
+	{
+		delete *it;
+	}
+	m_vMemoryAddress.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ConvertTimeToLocalTime
+// -----------------------------------------------------------------------------
+string CATDatParser::ConvertTimeToLocalTime( string sInputTime )
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::ConvertTimeToLocalTime");
+	//Is process end abnormal?
+	if( sInputTime.compare( LABEL_ABNORMAL ) == 0 )
+	{
+		return string( AT_ANALYZE_ABNORMAL_EXIT );
+	}
+	else
+	// Check that input time is at least 32-bit
+	if( sInputTime.length() <= 8 )
+	{
+		sInputTime.clear();
+		return sInputTime;
+	}
+
+	string sTemp = sInputTime;
+	const char* pTemp = sTemp.c_str();
+
+	// Are all characters hex
+	for( unsigned int i = 0 ; i < sTemp.size() ; i++ )
+	{
+		if( !IsHexCharacter( (pTemp + i) ) )
+		{
+			return sInputTime;
+		}
+	}
+	
+	// Get LSB bits
+	string sLsb;
+	sLsb.append( sInputTime.substr( sInputTime.length()-8, sInputTime.length() ) );
+	unsigned int iLsbTime = (unsigned int)_httoi( sLsb.c_str() );
+
+	// Get MSB bits
+    string sMsb;
+	sMsb.append( sInputTime.substr( 0, sInputTime.length()-8 ) );
+	unsigned int iMsbTime = (unsigned int)_httoi( sMsb.c_str() );
+
+	// Get time in microsecods
+	long long sdf = iMsbTime * 0x100000000 + iLsbTime;
+
+	// Get original time (starting at year 1970 )
+	long long llOrigTime = sdf;
+
+	// Get seconds
+	sdf = ( sdf )/1000000;
+		
+	// Check that sdf contains some time value
+	if( sdf <= 0)
+	{
+		// Error in time calculation
+		// Return empty string
+		sInputTime.clear();
+		return sInputTime;
+	}
+
+	// Original time after year 1970 in seconds
+	long long llOrignTimeInSeconds = sdf;
+	
+	// Calculate new time which does not include millisecods
+	long long llDiffTime = (llOrignTimeInSeconds * 1000000);
+
+	// Calculate time difference in milliseconds
+	int llDiffTimeInMilliSecods = (int)( llOrigTime - llDiffTime )/1000;
+	
+	// Convert difference time to char
+	char cDiffInMilliSeconds[20];
+    _itoa( llDiffTimeInMilliSecods, cDiffInMilliSeconds, 10 );
+
+	// Time info structure
+	struct tm *timeinfo;
+
+	// Get local time
+	timeinfo = localtime ( (time_t*) &sdf );
+
+	// Create string and append memory leak time to it
+	string sTime;
+	sTime.append( asctime( timeinfo ) );
+
+	// Remove last char of locale time string which is \n
+	sTime.resize( (int)sTime.length()-1 );
+	
+	// Get last space index
+	int iLastSpace = (int)sTime.find_last_of(" ");
+
+	// If last space index is valid
+	if( iLastSpace <= (int)sTime.length() && iLastSpace > 0)
+	{
+		string sTempTime;
+		// Append first part of original time string
+		sTempTime.append( sTime.substr( 0, iLastSpace ) );
+		
+		// Append millisecods
+		sTempTime.append( "." );
+		sTempTime.append( cDiffInMilliSeconds );
+
+		// Append the rest of the original time string part
+		sTempTime.append( sTime.substr( iLastSpace, sTime.length()));
+
+		// Clear original and append new time string which includes millisecods
+		sTime.clear();
+		sTime.append( sTempTime );
+	}
+
+	// Return memory leak time
+	return sTime.c_str();
+}
+
+bool CATDatParser::CreateWinscwModule( const string& sBinaryName )
+{
+	LOG_FUNC_ENTRY( "CATDatParser::CreateWinscwModule" );
+	// Is module already created?
+	for( vector<CATModule2*>::iterator it = m_pModules->begin(); it != m_pModules->end(); it++ )
+	{
+		if ( _stricmp( sBinaryName.c_str(), (*it)->GetBinaryName().c_str() ) == 0 )
+			return true;
+	}
+	// No create new one and set its values.
+	CATModule2* mod = new CATModule2();
+	mod->SetTarget( RemovePathAndExt( sBinaryName, true ) );
+	mod->SetRequestedTargetExt( GetExtension( sBinaryName ) );
+	mod->SetReleasePath( string( "\\epoc32\\release" ) );
+	if ( m_eBuildType == CATProject::UDEB )
+		mod->SetFullVariantPath( string( "winscw\\udeb" ) );
+	else
+		mod->SetFullVariantPath( string( "winscw\\urel" ) );
+	mod->SetVariantPlatform( string( "winscw" ) );
+	m_pModules->push_back( mod );
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingAddress
+// Function finds module using given address.
+// -----------------------------------------------------------------------------
+int CATDatParser::FindModuleUsingAddress( unsigned long iAddress ) const
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingAddress");
+	int iRet = -1;
+	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+	{
+		// Is address between start and end address?
+		if( iAddress > m_vDllLoadModList[i].iStartAddress && iAddress < m_vDllLoadModList[i].iEndAddress )
+		{
+			iRet = i;
+			break;
+		}	
+	}
+	return iRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingPID
+// Function finds module using module id.
+// -----------------------------------------------------------------------------
+/*
+int CATDatParser::FindModuleUsingPID( unsigned long iPID ) const
+{
+	LOG_FUNC_ENTRY("CATDatParser::FindModuleUsingPID");
+
+	int iRet = -1;
+
+	// Change module name characters to lowercase
+	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+	{
+		if( m_vDllLoadModList[i].iPID == iPID )
+		{
+			iRet = i;
+			break;
+		}	
+	}
+	return iRet;
+}
+*/
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingName
+// Function finds module using module name.
+// -----------------------------------------------------------------------------
+int CATDatParser::FindModuleUsingName( const char* pModName )
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingName");
+
+	// Mod name empty?
+	if( pModName == NULL || *pModName == 0 )
+		return -1;
+
+	int iRet = -1;
+	string sModName( pModName );
+	// Change module name characters to lowercase
+	ChangeToLower( sModName );
+	// Remove variant marks (dots)
+	RemoveAllAfterDotIfTwoDots( sModName);
+	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+	{
+		string sTemp( m_vDllLoadModList[i].sModuleName );
+		ChangeToLower( sTemp );
+		// Remove variant marks (dots)
+		RemoveAllAfterDotIfTwoDots( sTemp );
+		if( sTemp.find( sModName ) != string::npos )
+		{
+			iRet = i;
+			break;
+		}	
+	}
+	return iRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetPrintFlag
+// -----------------------------------------------------------------------------
+void CATDatParser::SetPringFlag( bool bPrintFlag )
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetPringFlag");
+	m_DataSaver.SetPrintFlag( bPrintFlag );
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::SetOffSet
+// -----------------------------------------------------------------------------
+void CATDatParser::SetOffSet( int iOffSet )
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetOffSet");
+	m_iOffSet = iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::GetOffSet
+// -----------------------------------------------------------------------------
+int CATDatParser::GetOffSet( ) const
+{
+	LOG_LOW_FUNC_ENTRY("CATDatParser::GetOffSet");
+	return m_iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// Set project platform.
+// -----------------------------------------------------------------------------
+void CATDatParser::SetProjectPlatform( const string& sPlatform )
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetProjectPlatform");
+	m_sProjectPlatform = sPlatform;
+
+	// Check that platform not empty before determing platform from it.
+	if ( sPlatform.empty() )
+		return;
+
+	// Set functions offset in mapfiles correct (depending on platform).
+	if ( _stricmp( sPlatform.c_str(), "armv5" ) == 0 )
+	{
+		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5;
+	}
+	else if ( _stricmp( sPlatform.c_str(), "winscw" ) == 0 )
+	{
+		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW;
+	}
+	else if ( _stricmp( sPlatform.c_str(), "gcce" ) == 0 )
+	{
+		m_iOffSet = FUNCTIONS_OFFSET_IN_GCCE;
+	}
+	else
+	{
+		LOG_STRING( AT_MSG << "Error, cannot set function's offset in map file, invalid platform: " << sPlatform );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// Set projects build type. Use enumeration defined in CATProject.
+// -----------------------------------------------------------------------------
+void CATDatParser::SetProjectBuildType( int eBuildType )
+{
+	LOG_FUNC_ENTRY("CATDatParser::SetProjectBuildType");
+	m_eProjectBuildType = eBuildType;
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATDataSaver.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,873 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATDataSaver.
+*
+*/
+
+
+#include "../inc/catdatasaver.h"
+
+#include <xercesc/util/OutOfMemoryException.hpp>
+
+#if defined(XERCES_NEW_IOSTREAMS)
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+// Line feed char sequence used in XML report
+wchar_t AT_XML_LINEFEEDS[3] = L"\r\n";
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::CATDataSaver
+// Constructor.
+// -----------------------------------------------------------------------------
+CATDataSaver::CATDataSaver( void )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::CATDataSaver");
+	m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
+	m_bPrintImmediately = true;
+	m_bXMLInitOk = false;
+	m_bUdebBuild = true;
+
+	m_iRunNumber = 1;
+
+	m_pDomDoc = NULL;
+	m_pRootElem = NULL;
+	m_Serializer = NULL;
+	m_pCurrentLeakElem = NULL;
+	m_pRunElement = NULL;
+	m_pMemoryLeaks = NULL;
+	m_pHandleLeaks = NULL;
+	m_pCurrentSubTestElem = NULL;
+	m_pSubtestMemoryLeaks = NULL;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::~CATDataSaver
+// Destructor.
+// -----------------------------------------------------------------------------
+CATDataSaver::~CATDataSaver(void)
+{
+	LOG_FUNC_ENTRY("CATDataSaver::~CATDataSaver");
+	if( m_bXMLInitOk )
+	{
+		if( m_Serializer )
+			delete m_Serializer;
+
+		m_pDomDoc->release();
+		xercesc::XMLPlatformUtils::Terminate();
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveLinesToFile
+// Gets logging level.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveLinesToFile( const char* pFileName, int iDataToSave )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SaveLinesToFile");
+
+	// Nothing to print?
+	if( m_vLines.empty() )
+	{
+		printf( "No output data." );
+		return;
+	}
+	if( iDataToSave != XML_DATA )
+	{
+		ofstream out( pFileName );
+
+		if( !out.good() )
+		{
+			printf( "Can not open file: %s\n", pFileName );
+			return;
+		}
+		switch( iDataToSave )
+		{
+			case TEXT_DATA:
+				for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
+				{
+					out << m_vLines[i].c_str();
+				}
+			break;
+		}
+		out.close();
+	}
+	else
+	{
+		if( m_bXMLInitOk )
+		{
+			xercesc::XMLFormatTarget* myFormTarget = NULL;
+			try
+			{
+				// Create format
+				myFormTarget = new xercesc::LocalFileFormatTarget( pFileName );
+				
+				// Set line-feeds to dom writer
+				m_Serializer->setNewLine( AT_XML_LINEFEEDS );
+				
+				// Set human-readable property. Note! Api already changed in >2.7
+				// so this will cause error/problems if linked to newer library.
+				m_Serializer->setFeature( xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true );
+				
+				// Write document
+				m_Serializer->writeNode(myFormTarget, *m_pDomDoc);
+			}
+			catch(...)
+			{
+				printf( "Can not save output file: %s.", pFileName );
+			}
+			if( myFormTarget )
+				delete myFormTarget; //lint !e118
+		}
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::PrintLinesToScreen
+// Prints all saved lines to screen.
+// -----------------------------------------------------------------------------
+void CATDataSaver::PrintLinesToScreen( void )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::PrintLinesToScreen");
+	// Nothing to print?
+	if( m_vLines.empty() )
+	{
+		printf( "No output data." );
+		return;
+	}
+	for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
+	{
+		printf( m_vLines[i].c_str() );	
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddLineToFirst
+// Adds saved line to first in database.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddLineToFirst( void )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToFirst");
+	m_sLine.append( "\n" );
+	m_vLines.insert( m_vLines.begin(), m_sLine );
+	m_sLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddLineToLast
+// Adds saved line to last in database.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddLineToLast()
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToLast");
+	m_sLine.append( "\n" );
+	
+	string sTempDataLine;
+
+	m_vLines.push_back( m_sLine );
+
+	SaveXML( m_sCarbideDataLine, ITEM );
+
+	if( m_bPrintImmediately )
+	{
+		printf( m_sLine.c_str() );
+	}
+
+	m_sCarbideDataLine.clear();
+	m_sLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddString
+// Adds string to current line.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddString( const char* pData, bool bSaveCarbideData )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddString");
+	m_sLine.append( pData );
+
+	if( bSaveCarbideData )
+	{
+		m_sCarbideDataLine.append( pData );
+		m_sCarbideDataLine.append(";");
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddInteger
+// Converts integer to string and adds it to current line.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddInteger( int iValue, bool bSaveCarbideData )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddInteger");
+	char cTemp[128];
+	string sValue( itoa( iValue, cTemp, 10 ) );
+	m_sLine.append( sValue );
+
+	if( bSaveCarbideData )
+	{
+		m_sCarbideDataLine.append( sValue );
+		m_sCarbideDataLine.append(";");
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetLoggingLevel
+// Sets logging level.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetLoggingLevel( int iLoggingLevel )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SetLoggingLevel");
+	// Check that new logging level is valid 
+	// Acceptable values are between MIN_LOGGING_LEVEL and 
+    // MAX_LOGGING_LEVEL including them
+	if( iLoggingLevel >= MIN_LOGGING_LEVEL && iLoggingLevel <= MAX_LOGGING_LEVEL )
+	{
+		m_iLoggingLevel = iLoggingLevel;
+	}
+	else
+	{
+		// New logging level value is invalid => set default logging level
+		m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::GetLoggingLevel
+// Gets logging level.
+// -----------------------------------------------------------------------------
+int CATDataSaver::GetLoggingLevel( void )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::GetLoggingLevel");
+	return m_iLoggingLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetPrintFlag
+// Sets print immediately flag.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetPrintFlag( bool bPrintImmediately )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SetPrintFlag");
+	m_bPrintImmediately = bPrintImmediately;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveCarbideDataHeader
+// Sets data header for Carbide data.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveCarbideDataHeader( void )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SaveCarbideDataHeader");
+	SaveXML( m_sCarbideDataLine, LEAK );
+	m_sCarbideDataLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::InitXML
+// Initializes xerces xml parser.
+// -----------------------------------------------------------------------------
+bool CATDataSaver::InitXML( void )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::InitXML");
+	try 
+	{
+		xercesc::XMLPlatformUtils::Initialize();
+	}
+	catch ( ... )//(const XMLException& toCatch) 
+	{
+		// Do your failure processing here
+		printf("XML initialization failed.\n");
+		return false;
+	}
+	// Error code.
+	int errorCode = 0;
+	// getDomIMplementation returns null if source has none.
+	xercesc::DOMImplementation* impl = xercesc::DOMImplementationRegistry::getDOMImplementation(L"Core");
+	if (impl != NULL)
+    {
+		// Create new DOMWriter.
+		m_Serializer = ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
+		// New document.
+        try
+        {
+			m_pDomDoc = impl->createDocument(
+                        0,                    // Root element namespace URI.
+                        L"results",         // Root element name
+                        0);                   // Document type object (DTD).
+
+            m_pRootElem = m_pDomDoc->getDocumentElement();
+        }
+        catch (const xercesc::OutOfMemoryException&)
+        {
+            XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
+            errorCode = 5;
+        }
+        catch (const xercesc::DOMException& e)
+        {
+            XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
+            errorCode = 2;
+        }
+        catch (...)
+        {
+            XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
+            errorCode = 3;
+        }
+    }  // (inpl != NULL)
+    else
+    {
+        XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
+        errorCode = 4;
+    }
+	if( !errorCode )
+	{
+		m_bXMLInitOk = true;
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::WCharToChar
+// Converts wchar_t* -> char*.
+// -----------------------------------------------------------------------------
+void CATDataSaver::WCharToChar( string& sInput, const WCHAR* Source )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::WCharToChar");
+	if( !Source )
+		return;
+    int i = 0;
+
+    while( Source[i] != '\0' )
+    {
+		char c = (CHAR)Source[i];
+		sInput.append( &c, 1 );
+        ++i;
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::CharToWChar
+// Converts char* -> wchar_t*.
+// -----------------------------------------------------------------------------
+LPWSTR CATDataSaver::CharToWChar( const char* str )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::CharToWChar");
+    LPWSTR out = NULL;
+    if( str != NULL )
+    {
+        int in_len = (int)strlen( str );
+        int out_len = MultiByteToWideChar(CP_ACP, 0, str, in_len, NULL, 0) + 2;
+        out = new WCHAR[out_len];
+
+        if (out)
+        {
+            memset(out, 0x00, sizeof(WCHAR)*out_len);
+            MultiByteToWideChar(CP_ACP, 0, str, in_len, out, in_len);
+        }
+    }
+    return out;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveXML
+// Writes data to xml tree.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveXML( string sInput, int iElementType )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SaveXML");
+	// Variables ok?
+	if( sInput.empty() || m_pDomDoc == NULL )
+	{
+		return;
+	}
+	try
+	{
+		switch( iElementType )
+		{
+			case RESULT:
+			{
+				// Print number of runs
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				m_pRootElem->setAttribute( L"runs", (const LPWSTR)wTemp );
+
+				// Print failed runs
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pRootElem->setAttribute( L"failed", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case RUN:
+			{
+				if( m_pRootElem == NULL )
+					return;
+				xercesc::DOMElement* runElem = m_pDomDoc->createElement( L"run" );
+				m_pRootElem->appendChild( runElem );
+
+				// Reset handle leaks.
+				m_pHandleLeaks = NULL;
+
+				// Print start time
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				runElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
+				runElem->setAttribute( L"end_time", NULL );
+				if( wTemp )
+					delete[] wTemp;
+
+				// Print build target
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				wTemp = CharToWChar( sTemp.c_str() );
+				runElem->setAttribute( L"build_target", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+
+				// Print process name
+				wTemp = CharToWChar( sInput.c_str() );
+				runElem->setAttribute( L"process_name", (const LPWSTR)wTemp );
+
+				m_pRunElement = runElem;
+
+				char cTemp[128];
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( itoa( m_iRunNumber, cTemp, 10 ) );
+				runElem->setAttribute( L"id", (const LPWSTR)wTemp );
+				m_iRunNumber++;
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case LEAK:
+			{
+				m_pCurrentLeakElem = m_pDomDoc->createElement( L"leak" );
+
+
+				if( m_pCurrentLeakElem == NULL || m_pRunElement == NULL )
+					return;
+
+				// Sub test?
+				if( m_pCurrentSubTestElem )
+					m_pCurrentSubTestElem->appendChild( m_pCurrentLeakElem );
+				else
+					m_pRunElement->appendChild( m_pCurrentLeakElem );
+
+				// Print leak ID
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentLeakElem->setAttribute( L"id", (const LPWSTR)wTemp );
+
+				// Print leak size
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentLeakElem->setAttribute( L"size", (const LPWSTR)wTemp );
+
+				// Print leak address
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentLeakElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
+
+				// Print leak time
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentLeakElem->setAttribute( L"time", (const LPWSTR)wTemp );
+
+				// Print leak module
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentLeakElem->setAttribute( L"module", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case ITEM:
+			{
+				xercesc::DOMNode* callstackNode = NULL;
+
+				xercesc::DOMElement* callstackElem = NULL;
+
+				if( m_pCurrentLeakElem  == NULL )
+					return;
+
+				// Print module name
+				if( !m_pCurrentLeakElem->hasChildNodes() )
+				{
+					callstackElem = m_pDomDoc->createElement( L"callstack" );
+					m_pCurrentLeakElem->appendChild( callstackElem );
+					callstackNode = callstackElem;
+				}
+				else
+				{
+					callstackNode = m_pCurrentLeakElem->getFirstChild();
+				}
+
+				// Add callstack item
+				xercesc::DOMElement* itemElem = m_pDomDoc->createElement( L"item" );
+				callstackNode->appendChild( itemElem );
+
+				// Print memory address name
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+
+				itemElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
+
+				// Print calculated memory address
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+
+				itemElem->setAttribute( L"calc_addr", (const LPWSTR)wTemp );
+
+				// Print module name
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+
+				itemElem->setAttribute( L"module", (const LPWSTR)wTemp );
+
+				// Print function name
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+
+				itemElem->setAttribute( L"function", (const LPWSTR)wTemp );
+
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+
+				// Print function line from urel build
+				if( !m_bUdebBuild )
+				{
+					if( wTemp )
+						delete[] wTemp;
+					wTemp = CharToWChar( sTemp.c_str() );
+					itemElem->setAttribute( L"function_line", (const LPWSTR)wTemp );
+					sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				}
+
+				// Print file name
+				if( wTemp )
+					delete[] wTemp;
+				// Erase if path found from sTemp.
+				if ( sTemp.rfind( "/" ) != string::npos )
+				{
+					sTemp.erase(0, sTemp.rfind( "/" )+1 );
+				}
+				if ( sTemp.rfind( "\\" ) != string::npos )
+				{
+					sTemp.erase(0, sTemp.rfind( "\\" )+1 );
+				}
+				wTemp = CharToWChar( sTemp.c_str() );
+
+				itemElem->setAttribute( L"file", (const LPWSTR)wTemp );
+
+				// Print line of file
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+
+				if( m_bUdebBuild )
+					itemElem->setAttribute( L"line", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case RUN_END:
+			{
+				if( m_pRunElement == NULL )
+					return;
+				const LPWSTR wTemp = CharToWChar( sInput.c_str() );
+				m_pRunElement->setAttribute( L"end_time", wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case ERROR_IN_RUN:
+			{
+				if( m_pRunElement == NULL )
+					return;
+				// Add error item
+				xercesc::DOMElement* errorElem = m_pDomDoc->createElement( L"error" );
+				m_pRunElement->appendChild( errorElem );
+
+				// Print error code
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				errorElem->setAttribute( L"code", (const LPWSTR)wTemp );
+
+				// Print error time
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				if( wTemp )
+					delete[] wTemp;
+				wTemp = CharToWChar( sTemp.c_str() );
+				errorElem->setAttribute( L"time", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case MEM_LEAKS:
+			{
+				if( m_pRunElement == NULL )
+					return;
+				xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
+				m_pRunElement->appendChild( memoryLeaksElement );
+				m_pMemoryLeaks = memoryLeaksElement;
+
+				// Print number of leaks
+				LPWSTR wTemp = CharToWChar( sInput.c_str() );
+				memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case MEM_LEAK_MODULE:
+			{
+				if( m_pMemoryLeaks == NULL )
+					return;
+				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+				m_pMemoryLeaks->appendChild( moduleElement );
+
+				// Print module name
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+
+				if( wTemp )
+					delete[] wTemp;
+				// Print number of memory leaks
+				wTemp = CharToWChar( sInput.c_str() );
+				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case HANDLE_LEAKS:
+			{
+				if( m_pRunElement == NULL )
+					return;
+				if( m_pHandleLeaks )
+				{
+					// Update number of leaks
+					LPWSTR wTemp = CharToWChar( sInput.c_str() );
+					m_pHandleLeaks->setAttribute( L"count", (const LPWSTR)wTemp );
+					if( wTemp )
+						delete[] wTemp;
+				}
+				else
+				{
+					xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
+					m_pRunElement->appendChild( handleLeaksElement );
+					m_pHandleLeaks = handleLeaksElement;
+
+					// Print number of leaks
+					LPWSTR wTemp = CharToWChar( sInput.c_str() );
+					handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+					if( wTemp )
+						delete[] wTemp;
+				}
+			}
+			break;
+			case HANDLE_LEAK_MODULE:
+			{
+				if( m_pHandleLeaks == NULL )
+					return;
+				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+				m_pHandleLeaks->appendChild( moduleElement );
+
+				// Print module name
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+
+				// Print number of memory leaks
+				wTemp = CharToWChar( sInput.c_str() );
+				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+			}
+			break;
+			case TEST_START:
+			{
+				m_pCurrentSubTestElem = m_pDomDoc->createElement( L"subtest" );
+
+				if( m_pCurrentSubTestElem == NULL || m_pRunElement == NULL )
+					return;
+
+				m_pRunElement->appendChild( m_pCurrentSubTestElem );
+
+				// Print sub test name
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentSubTestElem->setAttribute( L"name", (const LPWSTR)wTemp );
+				if( wTemp )
+				{
+					delete[] wTemp;
+					wTemp = NULL;
+				}
+
+				// Print sub test time
+				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentSubTestElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+				break;
+			}
+			case TEST_END:
+			{
+				if( m_pCurrentSubTestElem == NULL )
+					return;
+				// Print end time
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				m_pCurrentSubTestElem->setAttribute( L"end_time", (const LPWSTR)wTemp );
+				m_pCurrentSubTestElem = NULL;
+				if( wTemp )
+					delete[] wTemp;
+				break;
+			}
+			case SUBTEST_MEM_LEAKS:
+			{
+				if( m_pCurrentSubTestElem == NULL )
+					return;
+				xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
+				m_pCurrentSubTestElem->appendChild( memoryLeaksElement );
+				m_pSubtestMemoryLeaks = memoryLeaksElement;
+
+				// Print number of leaks
+				LPWSTR wTemp = CharToWChar( sInput.c_str() );
+				memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+				break;
+			}
+			case SUBTEST_MEM_LEAK_MODULE:
+			{
+				if( m_pSubtestMemoryLeaks == NULL )
+					return;
+				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+				m_pSubtestMemoryLeaks->appendChild( moduleElement );
+
+				// Print module name
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+
+				if( wTemp )
+					delete[] wTemp;
+				// Print number of memory leaks
+				wTemp = CharToWChar( sInput.c_str() );
+				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+				break;
+			}
+			case SUBTEST_HANDLE_LEAKS:
+			{
+				if( m_pCurrentSubTestElem == NULL )
+					return;
+				xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
+				m_pCurrentSubTestElem->appendChild( handleLeaksElement );
+
+				//Print number of handle leaks
+				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+				handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+				if( wTemp )
+					delete[] wTemp;
+				break;
+			}
+			default:
+			break;
+		}
+	}
+	catch( ... )
+	{
+		printf( "Error when writing data to XML file." );
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::GetStringUntilNextGivenChar
+// Function returns string from begin of given string until next given char,
+// characters until given char are removed from sInput string.
+// -----------------------------------------------------------------------------
+string CATDataSaver::GetStringUntilNextGivenChar( string& sInput, char cCharacter )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::GetStringUntilNextGivenChar");
+	string sRet;
+	size_t iPos = sInput.find( cCharacter );
+	if( sInput.size() > 1 && iPos != string::npos )
+	{
+		sRet = sInput.substr( 0, iPos );
+		sInput.erase( 0, (iPos + 1) );
+	}
+	return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetBuild
+// Function sets build target info.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetBuild( bool bUdebBuild )
+{
+	LOG_FUNC_ENTRY("CATDataSaver::SetBuild");
+	m_bUdebBuild = bUdebBuild;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddCarbideData
+// Function adds string to Carbide data.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddCarbideData( const string& sInput )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddCarbideData");
+	m_sCarbideDataLine.append( sInput );
+	m_sCarbideDataLine.append(";");
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::IntegerToString
+// Converts integer to string.
+// -----------------------------------------------------------------------------
+string CATDataSaver::IntegerToString( int iValueToConvert )
+{
+	LOG_LOW_FUNC_ENTRY("CATDataSaver::IntegerToString");
+	char cTemp[128];
+	string sValue( itoa( iValueToConvert, cTemp, 10 ) );
+	return sValue;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATMemoryAddress.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,307 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a memory address and its details.
+*
+*/
+
+
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/CATBase.h"
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::CATMemoryAddress
+// Constructor
+// -----------------------------------------------------------------------------
+CATMemoryAddress::CATMemoryAddress(string& sAddress, unsigned long iOffSet)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::CATMemoryAddress");
+	m_sAddress = sAddress;
+	m_sFileName = "";
+	m_sFunctionName = "";
+	m_sModuleName = "";
+	m_iAddress = CATBase::_httoi( sAddress.c_str() );
+	m_iDllLoadinfoIndex = -1;
+	m_iModuleStartAddress = 0;
+	m_iOffSetFromModuleStart = 0;
+	m_iExactLineNumber = -1;
+	m_iFunctionLineNumber = -1;
+	m_ePinPointState = OUT_OF_PROCESS;
+	m_iOffSet = iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::~CATMemoryAddress
+// Destructor.
+// -----------------------------------------------------------------------------
+CATMemoryAddress::~CATMemoryAddress()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::~CATMemoryAddress");
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::FindSetModuleName
+// Find which binary this address belongs to.
+// Sets also the offsetfrommodulestart.
+// -----------------------------------------------------------------------------
+bool CATMemoryAddress::FindSetModuleName(vector<DLL_LOAD_INFO>* vDlls)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::FindSetModuleName");
+	vector<DLL_LOAD_INFO>::iterator it;
+	for (  it = vDlls->begin() ;
+		it != vDlls->end(); it++ )
+	{
+		// Is modules load time defined?
+		if ( (*it).iLoadTime > 0 )
+		{
+			// Check that load time is earlier or same as allocation
+			if ( m_iTime >= (*it).iLoadTime
+				&& m_iAddress >= (*it).iStartAddress 
+				&& m_iAddress < (*it).iEndAddress )
+			{
+				// Module is loaded until process end.
+				if ( (*it).iUnloadTime == 0 )
+					break;
+				// Check is allocation done before module was unloaded.
+				else if ( (*it).iUnloadTime >= m_iTime )
+					break;
+			}
+		}
+		// Module has no time defined use only code segments.
+		else
+		{
+			if ( m_iAddress >= (*it).iStartAddress 
+				&& m_iAddress < (*it).iEndAddress )
+				break;
+		}
+	}
+
+	// Did we not find module where address is?
+	if ( it == vDlls->end() )
+		return false;
+
+	m_ePinPointState = OUT_OF_RANGE;
+	m_sModuleName = (*it).sModuleName;
+	m_iModuleStartAddress = (*it).iStartAddress;
+	m_iOffSetFromModuleStart = m_iAddress - m_iModuleStartAddress;
+	m_iOffSetFromModuleStart += m_iOffSet;
+	m_iDllLoadinfoIndex = distance( vDlls->begin(), it ) ;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetModuleStartAddress
+// Set start address of the binary in which address resides.
+// Note, this also sets the offset from start value.
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetModuleStartAddress(unsigned long iAddress)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetModuleStartAddress");
+	m_iModuleStartAddress = iAddress;
+	m_iOffSetFromModuleStart = m_iAddress - m_iModuleStartAddress;
+	m_iOffSetFromModuleStart += m_iOffSet;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetOffSetFromModuleStart
+// Note return value includes the set offset.
+// So this value is not binary start - address.
+// Instead it is.
+// memory address - binary start address + offset
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetOffSetFromModuleStart()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetOffSetFromModuleStart");
+	return m_iOffSetFromModuleStart;
+}
+
+int CATMemoryAddress::GetDllLoadInfoIndex()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetDllLoadInfo");
+	return m_iDllLoadinfoIndex;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetTime
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetTime( unsigned long long& ullTime )
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetTime");
+	m_iTime = ullTime;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetTIme
+// -----------------------------------------------------------------------------
+unsigned long long CATMemoryAddress::GetTime()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetTime");
+	return m_iTime;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddress
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddress(string& sAddress)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddress");
+	m_sAddress = sAddress;
+	m_iAddress = CATBase::_httoi( sAddress.c_str() );
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddressString
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetAddressString()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddressString");
+	return m_sAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddress
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddress(unsigned long iAddress)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddress");
+	m_iAddress = iAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddress
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetAddress()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddress");
+	return m_iAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetModuleName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetModuleName(string& sModuleName)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetModuleName");
+	m_sModuleName = sModuleName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetModuleName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetModuleName()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetModuleName");
+	return m_sModuleName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddressToLineState
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddressToLineState( ADDRESS_TO_LINE_STATE eState )
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddressToLineState");
+	m_ePinPointState = eState;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddressToLineState
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetAddressToLineState()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddressToLineState");
+	return m_ePinPointState;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFileName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFileName(string& sFileName)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFileName");
+	m_sFileName = sFileName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFileName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetFileName()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFileName");
+	return m_sFileName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFunctionName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFunctionName(string& sFunctionName)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFunctionName");
+	m_sFunctionName = sFunctionName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFunctionName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetFunctionName()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFunctionName");
+	return m_sFunctionName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFunctionLineNumber
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFunctionLineNumber(int iFunctionLineNumber)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFunctionLineNumber");
+	m_iFunctionLineNumber = iFunctionLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFunctionLineNumber
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetFunctionLineNumber()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFunctionLineNumber");
+	return m_iFunctionLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetExactLineNumber
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetExactLineNumber(int iExactLineNumber)
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetExactLineNumber");
+	m_iExactLineNumber = iExactLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetExactLineNumber
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetExactLineNumber()
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetExactLineNumber");
+	return m_iExactLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetModuleStartAddress
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetModuleStartAddress() const
+{
+	LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetModuleStartAddress");
+	return m_iModuleStartAddress;
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATMmp.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,396 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class responsible of handling mmp files.
+*
+*/
+
+
+#include "../inc/CATMmp.h"
+
+CATMmp::CATMmp()
+{
+	LOG_FUNC_ENTRY("CATMmp::CATMmp");
+}
+
+CATMmp::~CATMmp()
+{
+	LOG_FUNC_ENTRY("CATMmp::~CATMmp");
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::IsMmpEdited
+// Checks is the file edited by AT
+// -----------------------------------------------------------------------------
+bool CATMmp::IsMmpEdited( bool bBackup)
+{
+	LOG_FUNC_ENTRY("CATMmp::IsMmpEdited");
+	// Stream to read file
+	ifstream in;
+	// Temp char array to read line
+	char cTemp[MAX_LINE_LENGTH];
+	// Open file
+	if ( bBackup )
+		in.open( CreateMmpBackupPath().c_str() );
+	else
+		in.open( m_sMmpFile.c_str() );
+	// Is file open ok
+	if( ! in.good() )
+	{
+		cout << AT_MSG << "Error, can not open file "
+			<< m_sMmpFile << endl;
+		in.close();
+		return false;
+	}
+	// Search edit start line
+	bool bEdited=false;
+	const char* cFind = MMPFILECHANGES[0].c_str();
+	while( ! bEdited && in.good() )
+	{
+		// Get line
+		in.getline( cTemp, MAX_LINE_LENGTH );
+		// Compare to first line in changes
+		if ( strstr( cTemp, cFind) )
+		{
+			bEdited = true;
+			// Stop looking any further
+			break;
+		}
+	}
+	// Close file and return result
+	in.close();
+	return bEdited;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::EditMmpFile
+// Makes AnalyzeTool changes to given mmp file
+// -----------------------------------------------------------------------------
+bool CATMmp::EditMmpFile(const string& sTargetType, const string& sId)
+{
+	LOG_FUNC_ENTRY("CATMmp::EditMmpFile");
+
+	if ( ! RemoveWriteProtections() )
+		return false;
+
+	// Stream where to add changes
+	ofstream out;
+
+	// Open mmp file for editing (append changes to the end)
+	out.open( m_sMmpFile.c_str(), ios::out | ios::app );
+
+	// File open ok?
+	if( !out.good() )
+	{
+		cout << AT_MSG << "Error, can not open file "
+			<< m_sMmpFile;
+		out.close();
+		return false;
+	}
+	
+	// Write lines to mmp file
+	if ( sTargetType.compare( "dll" ) == 0 || sTargetType.compare( "lib" ) == 0 )
+	{
+		// DLL changes
+		int size = sizeof( MMPFILECHANGES_DLL ) / sizeof( string );
+		for( int i = 0; i < size; i++ )
+		{
+			out << endl << MMPFILECHANGES_DLL[i];
+		}
+		out << endl;
+	}
+	else
+	{
+		// Other than DLL changes
+		int size = sizeof( MMPFILECHANGES ) / sizeof( string );
+		for( int i = 0; i < size; i++ )
+		{
+			// After second line of changes add also source statement
+			out << endl << MMPFILECHANGES[i];
+			if ( i == 1 )
+			{
+				out << endl
+					<< "SOURCE            "
+					<< AT_TEMP_CPP_LOWER_START
+					<< sId
+					<< AT_TEMP_CPP_LOWER_END;
+			}
+		}
+		out << endl;
+	}
+	// Close stream
+	out.close();
+
+	cout << AT_MSG << "Mmp file : " << m_sMmpFile << " edited." << endl;
+
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::BackupMmpFile
+// Backups the mmp file to path/atool_temp/filename.mmp.tmp
+// Calling this function results always to 
+// - none edited mmp
+// - none edited backup
+// - If mmp is write protected. Create writable copy from it. Backup the write
+// procted one.
+// -----------------------------------------------------------------------------
+bool CATMmp::BackupMmpFile( )
+{
+	LOG_FUNC_ENTRY("CATMmp::BackupMmpFile");
+
+	if ( ! RemoveWriteProtections() )
+		return false;
+
+	// Backup path+filename
+	string sBackup = CreateMmpBackupPath();
+
+	// Backup mmp.
+	if ( CopyFile( m_sMmpFile.c_str() , sBackup.c_str(), false ) == 0 )
+	{
+		// Log and return false if failed to copy file
+		LOG_STRING( "error copyfile " << m_sMmpFile << " to " << sBackup );
+		return false;
+	}
+
+	// If backup now edited remove changes from it.
+	if ( IsMmpEdited( true ) )
+	{
+		if ( ! RemoveMmpFileChanges( true ) )
+			return false;
+	}
+
+	return true;
+}
+// -----------------------------------------------------------------------------
+// CATMmp::RestoreMmpFile
+// Restores the mmp file from backup
+// -----------------------------------------------------------------------------
+bool CATMmp::RestoreMmpFile()
+{
+	LOG_FUNC_ENTRY("CATMmp::RestoreMmpFile");
+	
+	if ( ! RemoveWriteProtections() )
+		return false;
+
+	if ( CopyFile( CreateMmpBackupPath().c_str() , m_sMmpFile.c_str(), false ) == 0 )
+	{
+		// Log and return false if failed to copy file
+		LOG_STRING("error copyfile " << CreateMmpBackupPath() << " to " << m_sMmpFile );
+		return false;
+	}
+	else
+		cout << AT_MSG << "Mmp file : " << m_sMmpFile << " restored." << endl;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::RemoveMmpFileChanges
+// Removes AT changes from given mmp file
+// -----------------------------------------------------------------------------
+bool CATMmp::RemoveMmpFileChanges(bool bBackup)
+{
+	LOG_FUNC_ENTRY("CATMmp::RemoveMmpFileChanges");
+	
+	if ( ! RemoveWriteProtections() )
+		return false;
+
+	// File reading stream
+	ifstream in;
+	// Vector to hold file data
+	vector<string> vLines;
+	// Open file
+	if ( bBackup )
+		in.open( CreateMmpBackupPath().c_str(), ios::in );
+	else
+		in.open( m_sMmpFile.c_str(), ios::in );
+	// Check file open ok
+	if ( ! in.good() )
+	{
+		cout << AT_MSG << "Error, opening file";
+		if ( bBackup )
+			cout << CreateMmpBackupPath();
+		else
+			cout << m_sMmpFile;
+		cout << endl;
+		return false;
+	}
+	// Read file to temporary stream except AT changes
+	char cLine[MAX_LINE_LENGTH];
+	// Boolean to know read or not
+	bool bRead = true;
+	// Integer to confirm that AT changes were succefully found and
+	// not read even if they are found multiple times
+	int iSuccessfull = 0;
+	// Number of 'lines' in mmp changes
+	int iChangesSize = sizeof( MMPFILECHANGES ) / sizeof( string );
+	// First mmp changes line
+	string sFirstLine = MMPFILECHANGES[0];
+	// Last mmp changes line
+	string sLastLine = MMPFILECHANGES[iChangesSize-1];
+	while( in.good() )
+	{
+		in.getline( cLine, MAX_LINE_LENGTH );
+		// Check start of AT changes
+		if( strstr( cLine, sFirstLine.c_str() ) != 0 )
+		{
+			// Remove last linefeed
+			vector<string>::iterator it = vLines.end();
+			it--;
+			if ( it->size() == 0 ) 
+				vLines.erase( vLines.end()-1, vLines.end() );
+			// Stop reading
+			bRead = false;
+			iSuccessfull+=3;
+		}
+		// Read lines outside AT changes
+		if ( bRead )
+		{
+			// Gather all other lines except the AT edits
+			vLines.push_back( string(cLine) );
+		}
+		// Check end of AT changes
+		if( strstr( cLine, sLastLine.c_str() ) != 0 )
+		{
+			// Get empty line
+			in.getline( cLine, MAX_LINE_LENGTH );
+			// Continue reading
+			bRead = true;
+			iSuccessfull-=1;
+		}
+	}
+	// Close reading file stream
+	in.close();
+	// To check all went ok iSuccesfull%2 = 0
+	if ( iSuccessfull%2 != 0 && iSuccessfull >= 2 )
+	{
+		cout << AT_MSG << "Error, removing mmp changes from ";
+		if ( bBackup )
+			cout << CreateMmpBackupPath();
+		else
+			cout << m_sMmpFile;
+		cout << endl;
+		return false;
+	}
+	// Overwrite current mmp file
+	ofstream out;
+	// Open file (truncates old data)
+	if ( bBackup )
+		out.open( CreateMmpBackupPath().c_str(), ios::trunc );
+	else
+		out.open( m_sMmpFile.c_str(), ios::trunc );
+	// Is open ok
+	if( ! out.good() )
+	{
+		cout << AT_MSG << "Error, opening file ";
+		if ( bBackup )
+			cout << CreateMmpBackupPath();
+		else
+			cout << m_sMmpFile;
+		cout << endl;
+	}
+	// Write lines to file
+	for( vector<string>::iterator it = vLines.begin() ; it != vLines.end() ; it++ )
+	{
+		out << *it << endl;
+	}
+	// Close
+	out.close();
+	// Return true
+	return true;
+}
+// -----------------------------------------------------------------------------
+// CATMmp::VerifyAndRecover
+// Wont change mmp if it is not edited
+// Replaces mmp file using backup if it exists and it is
+// not edited otherwise removes changes from mmp file.
+// -----------------------------------------------------------------------------
+bool CATMmp::VerifyAndRecover()
+{
+	LOG_FUNC_ENTRY("CATMmp::VerifyAndRecover");
+	// Is it edited
+	if ( IsMmpEdited() )
+	{
+		string sBackup = CreateMmpBackupPath();
+		if ( FileExists( sBackup.c_str() ) )
+		{
+			// Is backup edited
+			if ( ! IsMmpEdited( true ) )
+			{
+				// Replace original with backup
+				return RestoreMmpFile();
+			}
+		}
+		// Remove changes from original
+		return RemoveMmpFileChanges();
+	}
+	// Non edited original
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::CreateMmpBackupPath
+// Creates string containing full path to backup mmp file
+// -----------------------------------------------------------------------------
+string CATMmp::CreateMmpBackupPath()
+{
+	LOG_FUNC_ENTRY("CATMmp::CreateMmpBackupPath");
+	// backup path+filename
+	string sBackup;
+	sBackup.append( GetPathOrFileName( false, m_sMmpFile ) );
+	sBackup.append( AT_TEMP_DIR );
+	sBackup.append( "\\" );
+	// Add mmp file name to it and .tmp
+	sBackup.append( GetPathOrFileName( true, m_sMmpFile ) );
+	// Add .tmp
+	sBackup.append( ".tmp" );
+	// Return it
+	return sBackup;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::RemoveWriteProtections
+// Removes write protection of mmp file and backup if exists.
+// -----------------------------------------------------------------------------
+bool CATMmp::RemoveWriteProtections()
+{
+	LOG_LOW_FUNC_ENTRY("CATMmp::RemoveWriteProtections");
+
+	// Backup path+filename
+	string sBackup = CreateMmpBackupPath();
+
+	// Check is mmp read-only
+	if ( IsFileReadOnly( m_sMmpFile.c_str() ) )
+	{
+		if( ! SetFileWritable( m_sMmpFile.c_str() ) )
+		{
+			LOG_STRING( "error setting mmp file writable" << m_sMmpFile );
+			return false;
+		}
+	}
+
+	// Check is there a backup if is remove any write protection from it.
+	if ( FileExists( sBackup.c_str() ) )
+	{
+		if ( IsFileReadOnly( sBackup.c_str() ) )
+		{
+			if( ! SetFileWritable( sBackup.c_str() ) )
+			{
+				LOG_STRING( "error setting mmp file writable" << sBackup );
+				return false;
+			}
+		}
+	}
+	return true;
+}
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATModule2.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1634 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a module in project (sbs2)
+*
+*/
+
+
+#include "../inc/CATModule2.h"
+#include "../inc/CATProject.h"
+#include "../inc/CATDatParser.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/catdbghelper.h"
+#include "../inc/cataddr2line.h"
+
+CATModule2::CATModule2(void)
+{
+	LOG_FUNC_ENTRY("CATModule2::CATModule2");
+	m_bAddressToLineInitialized = false;
+	m_pAddressToLine = 0;
+	m_sErrors = "";
+	m_sMakeFile = "";
+	m_eBuildSystem = CATProject::SBS_V1;
+	m_sCompileInfoText = "";
+}
+
+CATModule2::~CATModule2(void)
+{
+	LOG_FUNC_ENTRY("CATModule2::~CATModule2");
+	if ( m_pAddressToLine )
+		m_pAddressToLine->Close();
+	delete m_pAddressToLine;
+}
+
+bool CATModule2::AddressToLine( CATMemoryAddress* pMemoryAddress )
+{
+	LOG_FUNC_ENTRY("CATModule2::AddressToLine");
+	if ( _stricmp( m_sVariantPlatform.c_str(), "winscw" ) == 0 )
+	{
+		return AddressToLineWinscw( pMemoryAddress );
+	}
+	else if ( _stricmp( m_sVariantPlatform.c_str(), "armv5" ) == 0 )
+	{
+		// addr2line exe.
+		#ifdef ADDR2LINE
+		return AddressToLineAddr2lineExe( pMemoryAddress );
+		#endif
+		// lst and map files.
+		#ifndef ADDR2LINE
+		return AddressToLineArmv5( pMemoryAddress );
+		#endif
+	}
+	else if ( _stricmp( m_sVariantPlatform.c_str(), "gcce" ) == 0 )
+	{
+		return AddressToLineAddr2lineExe( pMemoryAddress );
+	}
+	return false;
+}
+
+bool CATModule2::AddressToLineWinscw( CATMemoryAddress* pMemoryAddress )
+{
+	LOG_FUNC_ENTRY("CATModule2::AddressToLineWinscw( CATMemoryAddress* pMemoryAddress )");
+	if ( m_pAddressToLine == 0 && ! m_bAddressToLineInitialized )
+	{
+		// Use debug helper to locate codelines on winscw platform.
+		m_pAddressToLine = new CATDbgHelper();
+
+		// Create full path to binary which we open using CATDbgHelper.
+		string sFullPathToBinary = GetBinaryFile();
+
+		// If opening of binary not succesfull set return value to false.
+		if ( ! m_pAddressToLine->Open( sFullPathToBinary, pMemoryAddress->GetModuleStartAddress() ) )
+		{
+			LOG_STRING("Error, m_pAddressToLine->Open()");
+			return false;
+		}
+		m_bAddressToLineInitialized = true;
+	}
+	// Check pointer before calling.
+	if ( m_pAddressToLine == 0 )
+		return false;
+	m_pAddressToLine->AddressToLine( pMemoryAddress );
+	return true;
+}
+
+bool CATModule2::AddressToLineArmv5( CATMemoryAddress* pMemoryAddress )
+{
+	LOG_FUNC_ENTRY("CATModule2::AddressToLine( CATMemoryAddress* pMemoryAddress )");
+	if ( ! m_bAddressToLineInitialized )
+		return false;
+	// Find from map file
+	int iMapIndex = GetSymbolIndexUsingAddress( pMemoryAddress->GetOffSetFromModuleStart() );
+	if ( iMapIndex == -1 )
+	{
+		pMemoryAddress->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE );
+		return true;
+	}
+	// Set symbol name
+	string sSymbolName = m_vMapFileFuncList.at( iMapIndex ).sFunctionName;
+
+	// Remove (... from symbol name
+	string sSymbolNameRefined( sSymbolName );
+	size_t iPos = sSymbolNameRefined.find( "(" );
+	if ( iPos != string::npos )
+		sSymbolNameRefined.resize( iPos );
+
+	// Set symbol name as function name for memory address
+	pMemoryAddress->SetFunctionName( sSymbolNameRefined );
+
+	// Set state to symbol
+	pMemoryAddress->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+	
+	// Offset from function start addr
+	int iOffSetFromFuncStart = pMemoryAddress->GetOffSetFromModuleStart()
+		- m_vMapFileFuncList.at( iMapIndex ).iAddress;
+
+	// Find from lst list
+	int iLstIndex = GetLineInFileIndexUsingSymbolName( sSymbolName );
+	if ( iLstIndex == -1 )
+		return true;
+
+	// Set pinpointing
+	int iFuncLineNumber = m_vLineInFile.at( iLstIndex ).iLine;
+	string sFileName = m_vLineInFile.at( iLstIndex ).sFileName;
+	string sLstFileName = m_vLineInFile.at( iLstIndex ).sLstName;
+
+	pMemoryAddress->SetFunctionLineNumber( iFuncLineNumber );
+	pMemoryAddress->SetFileName( sFileName );
+	
+	pMemoryAddress->SetAddressToLineState( CATMemoryAddress::FUNCTION );
+
+	// In urel mode don't get exact code line
+	if ( ! IsUDEB() )
+		return true;
+
+	// Next calculate the code line inside function
+	int iExactLineNumber = FindLeakCodeLine( sLstFileName, iFuncLineNumber, iOffSetFromFuncStart );
+	pMemoryAddress->SetExactLineNumber( iExactLineNumber );
+
+	// State is now exact
+	pMemoryAddress->SetAddressToLineState( CATMemoryAddress::EXACT );
+	return true;
+}
+
+bool CATModule2::AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress )
+{
+	LOG_FUNC_ENTRY("CATModule2::AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress )");
+	if ( m_pAddressToLine == 0 && ! m_bAddressToLineInitialized )
+	{
+		// Use addr2line.exe to locate codelines on armv5 and gcce platform.
+		m_pAddressToLine = new CATAddr2line();
+
+		// Create full path to binary .sym file which we open using addr2line.exe.
+		string sFullPathToBinary = GetBinaryFile();
+
+		// If opening of binary not succesfull set return value to false.
+		if ( ! m_pAddressToLine->Open( sFullPathToBinary, pMemoryAddress->GetModuleStartAddress() ) )
+		{
+			LOG_STRING("Error, m_pAddressToLine->Open()");
+			return false;
+		}
+		m_bAddressToLineInitialized = true;
+	}
+	// Check pointer before calling.
+	if ( m_pAddressToLine == 0 )
+		return false;
+
+	m_pAddressToLine->AddressToLine( pMemoryAddress );
+	return true;
+}
+
+// Find symbol of given address
+int CATModule2::GetSymbolIndexUsingAddress( unsigned long iAddress ) const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetSymbolIndexUsingAddress");
+	for( size_t i = 0; i < m_vMapFileFuncList.size(); i++ )
+	{
+		unsigned long iStart = m_vMapFileFuncList.at( i ).iAddress;
+		unsigned long iEnd = ( m_vMapFileFuncList.at( i ).iAddress
+			+ m_vMapFileFuncList.at( i ).iFuncLength );
+
+		if ( iAddress >= iStart && iAddress < iEnd )
+			return (int) i;
+	}
+	return -1;
+}
+
+// Find index of function line in file vector of given symbolname
+int CATModule2::GetLineInFileIndexUsingSymbolName( const string& sSymbolName ) const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetLineInFileIndexUsingSymbolName");
+	for( size_t i = 0; i < m_vLineInFile.size(); i++ )
+	{
+		string sLineInFileName = m_vLineInFile.at( i ).sFunction;
+		if( sLineInFileName.find( sSymbolName ) != string::npos )
+		{
+			return (int) i;
+		}
+	}
+	return -1;
+}
+
+
+// Check does modules symbol file(s) exist.
+bool CATModule2::SymbolFileExist( void )
+{
+	LOG_FUNC_ENTRY("CATModule2::SymbolFileExist");
+	string sFullPathToSym = GetSymbolFile();
+	if ( !FileExists( sFullPathToSym.c_str() ) )
+	{
+		// Add missing symbol file to error string.
+		m_sErrors.append( "Missing symbol file: " );
+		m_sErrors.append( sFullPathToSym );
+		m_sErrors.append( "\n" );
+		return false;
+	}
+	return true;
+}
+
+// Check does modules map file(s) exists.
+bool CATModule2::MapFileExist( void )
+{
+	LOG_FUNC_ENTRY("CATModule2::MapFileExist");
+	string sFullPathToMap = GetMapFile();
+	if ( !FileExists( sFullPathToMap.c_str() ) )
+	{
+		// Add missing symbol file to error string.
+		m_sErrors.append( "Missing map file: " );
+		m_sErrors.append( sFullPathToMap );
+		m_sErrors.append( "\n" );
+		return false;
+	}
+	return true;
+}
+
+//Check does modules binary file(s) exist.
+bool CATModule2::BinaryFileExist( void )
+{
+	LOG_FUNC_ENTRY("CATModule2::BinaryFileExist");
+	string sFullPathToBinary = GetBinaryFile();
+	if ( ! FileExists( sFullPathToBinary.c_str() ) )
+	{
+		// Add missing binary to error string.
+		m_sErrors.append( "Missing binary file: " );
+		m_sErrors.append( sFullPathToBinary );
+		m_sErrors.append( "\n" );
+		return false;
+	}
+	return true;
+}
+
+void CATModule2::AddSource(const string &sSourceFile, const string& sLstFile)
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::AddSource");
+	// Parse sources which are separated by spaces
+	if( sSourceFile.length() < 1  || sLstFile.length() < 1 )
+		return;
+
+	// Skip if its temporary cpp.
+	if ( sSourceFile.find( AT_TEMP_CPP_LOWER_START) != string::npos )
+		return;
+
+	// Source structure
+	SOURCE sNew;
+	sNew.sCpp =  sSourceFile;
+	sNew.sLst = sLstFile;
+
+	// Verify paths.
+	ConvertUnixPathToWin( sNew.sCpp );
+	ConvertUnixPathToWin( sNew.sLst );
+
+	// Lower case them.
+	ChangeToLower( sNew.sCpp );
+	ChangeToLower( sNew.sLst );
+
+	// Add it
+	m_vSources.push_back( sNew );
+}
+
+void CATModule2::AddSources(string& sSource)
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::AddSources");
+	// Parse sources which are separated by spaces
+	if( sSource.length() < 1 )
+		return;
+	// Source structure
+	SOURCE sNew;
+	size_t iSpot = string::npos;
+	iSpot = sSource.find( " " );
+	while( iSpot != string::npos )
+	{
+		// Pickup source
+		sNew.sCpp = sSource.substr(0, iSpot);
+		// Convert path from Unix to Win
+		ConvertUnixPathToWin( sNew.sCpp );
+		// Lowercase it
+		ChangeToLower( sNew.sCpp );
+		// If its temp skip this
+		if ( sNew.sCpp.find( AT_TEMP_CPP_LOWER_START ) == string::npos )
+		{
+			// Get corresponding lst file for source
+			sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+			m_vSources.push_back( sNew );
+			// Remove it from sSource
+			sSource.erase(0,iSpot+1);
+			// Find new one
+		}
+		iSpot = sSource.find( " " );
+	}
+	// Pickup last or only one source
+	sNew.sCpp = sSource;
+	// Convert path from unix to win
+	ConvertUnixPathToWin( sNew.sCpp );
+	// Lowercase it
+	ChangeToLower( sNew.sCpp );
+	// Lst name
+	sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+	if ( sNew.sCpp.find( AT_TEMP_CPP_LOWER_START ) == string::npos )
+	{
+		// Get corresponding lst file for source
+		sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+		m_vSources.push_back( sNew );
+	}
+}
+bool CATModule2::CreateTempCpp(const string& sS60FileName
+									, int eLoggingMode
+									, int eBuildType
+									, int iAllocCallStackSize
+									, int iFreeCallStackSize )
+{
+	LOG_FUNC_ENTRY("CATModule2::CreateTemporaryCpp");
+	// S60 filename
+	m_sS60FileName = sS60FileName;
+	// Make s60 filename target.type.dat if its empty and logging mode is file
+	if ( eLoggingMode == CATProject::FILE
+		&& m_sS60FileName.empty() )
+	{
+		m_sS60FileName = m_sTarget;
+		m_sS60FileName.append(".");
+		m_sS60FileName.append( m_sTargetType );
+		m_sS60FileName.append(".dat");
+	}
+	return CreateTemporaryCpp( GetUniqueId(), m_sTempPath,
+		m_sS60FileName, eLoggingMode, eBuildType, iAllocCallStackSize, iFreeCallStackSize );
+}
+
+bool CATModule2::ModifyMmp()
+{
+	LOG_FUNC_ENTRY("CATModule2::ModifyMmp");
+	// Create backup
+	if ( ! m_Mmp.BackupMmpFile() )
+		return false;
+	// Hook
+	return m_Mmp.EditMmpFile( m_sTargetType, GetUniqueId() );
+}
+
+bool CATModule2::RestoreMmp()
+{
+	LOG_FUNC_ENTRY("CATModule2::RestoreMmp");
+	// Restore mmp from backup
+	return m_Mmp.RestoreMmpFile();
+}
+
+bool CATModule2::VerifyAndRecoverMmp()
+{
+	LOG_FUNC_ENTRY("CATModule2::VerifyAndRecoverMmp");
+	// Verify mmp
+	return m_Mmp.VerifyAndRecover();
+}
+
+// ----------------------------------------------------------------------------
+// Releasables Handling methos
+// ----------------------------------------------------------------------------
+bool CATModule2::CopyReleasables()
+{
+	LOG_FUNC_ENTRY("CATModule2::CopyReleasables");
+	bool bRet = true;
+	if ( ! CopyLstFilesToTemp() )
+		bRet = false;
+	if ( ! CopyMapFileToTemp() )
+		bRet = false;
+	return bRet;
+}
+
+bool CATModule2::CopyLstFilesToDir( const string& sDir )
+{
+	LOG_FUNC_ENTRY("CATModule2::CopyLstFilesToDir");
+	bool bRet = true;
+	// Copy lst files to given directory.
+	vector<SOURCE>::const_iterator source;
+	for( source = m_vSources.begin(); source != m_vSources.end() ; source++ )
+	{
+		if ( ! FileCopyToPath( source->sLst, sDir ) )
+		{
+			if ( !FileExists( source->sLst.c_str() ) )
+			{
+				m_sErrors.append( "Missing listing file: " );
+				m_sErrors.append( source->sLst );
+				m_sErrors.append( "\n" );
+			}
+			if ( !DirectoryExists( sDir.c_str() ) )
+			{
+				m_sErrors.append( "Missing folder: " );
+				m_sErrors.append( sDir );
+				m_sErrors.append( "\n" );
+			}
+			bRet = false;
+		}
+	}
+	// Return.
+	return bRet;
+}
+
+bool CATModule2::CopyLstFilesToTemp()
+{
+	LOG_FUNC_ENTRY("CATModule2::CopyLstFilesToTemp");
+	// Return boolean
+	bool bRet = true;
+	// Move all lst files except tmp cpp
+	vector<SOURCE>::iterator it = m_vSources.begin();
+	while ( it != m_vSources.end() )
+	{
+		if ( !FileCopyToPath( it->sLst, m_sTempPath ) )
+		{
+			if ( !FileExists( it->sLst.c_str() ) )
+			{
+				m_sErrors.append( "Missing listing file: " );
+				m_sErrors.append( it->sLst );
+				m_sErrors.append( "\n" );
+			}
+			if ( !DirectoryExists( m_sTempPath.c_str() ) )
+			{
+				m_sErrors.append( "Missing folder: " );
+				m_sErrors.append( m_sTempPath );
+				m_sErrors.append( "\n" );
+			}
+			bRet = false;
+		}
+		it++;
+	}
+	return bRet;
+}
+
+bool CATModule2::DeleteLstFilesFromSrc( void )
+{
+	LOG_FUNC_ENTRY("CATModule2::DeleteLstFilesFromSrc");
+	vector<SOURCE>::iterator it = m_vSources.begin();
+	bool bRet = true;
+	// Delete lst files
+	while ( it != m_vSources.end() )
+	{
+		if ( ! FileDelete( it->sLst, true ) )
+			bRet = false;
+		it++;
+	}
+	return bRet;
+}
+
+bool CATModule2::CopyMapFileToTemp()
+{
+	LOG_FUNC_ENTRY("CATModule2::CopyMapFileToTemp");
+	// Return boolean
+	bool bRet = true;
+	// Map File to copy
+	string sMapFile = GetMapFile();
+	if ( !FileCopyToPath( sMapFile, m_sTempPath ) )
+	{
+		bRet = false;
+		if ( !FileExists( sMapFile.c_str() ) )
+		{
+			// Add missing map file to error string.
+			m_sErrors.append( "Missing map file: " );
+			m_sErrors.append( sMapFile );
+			m_sErrors.append( "\n" );
+		}
+		if ( !DirectoryExists( m_sTempPath.c_str() ) )
+		{
+			// Add missing temporary folder
+			m_sErrors.append( "Missing folder: " );
+			m_sErrors.append( m_sTempPath );
+			m_sErrors.append( "\n" );
+		}
+	}
+	return bRet;
+}
+
+bool CATModule2::CleanTemporaryDir()
+{
+	LOG_FUNC_ENTRY("CATModule2::CleanTemporaryDir");
+	bool bRet = true;
+	// Verify mmp
+	if ( ! m_Mmp.VerifyAndRecover() )
+		bRet = false;
+	// Clean temporary dir
+	vector<string> vFileList = DirList( m_sTempPath, false , true );
+	vector<string>::iterator it = vFileList.begin();
+	// Size of constant table
+	int iCount = sizeof( TEMP_EXTENSION_NO_DELETE ) / sizeof( string );
+	while ( it != vFileList.end() )
+	{
+		// Get extension and compare it to list
+		bool bDelete = true;
+		string sExtension = GetExtension( *it );
+		ChangeToLower( sExtension );
+		for ( int i = 0 ; i < iCount ; i++ )
+		{
+			if( sExtension.compare( TEMP_EXTENSION_NO_DELETE[i] ) == 0 )
+			{
+				bDelete = false;
+				break;
+			}
+		}
+		if ( bDelete )
+		{
+			// Delete file
+			if ( ! FileDelete( *it, true ) )
+				bRet = false;
+		}
+		// Increment
+		it++;
+	}
+	return bRet;
+}
+
+bool CATModule2::DeleteTemporaryDir()
+{
+	LOG_FUNC_ENTRY("CATModule2::DeleteTemporaryDir");
+	bool bRet = true;
+	// Verify mmp
+	if ( ! m_Mmp.VerifyAndRecover() )
+		bRet = false;
+	// Delete temp dir
+	if ( !DirDelete( m_sTempPath, true ) )
+		bRet = false;
+	return bRet;
+}
+
+bool CATModule2::IsUDEB() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::IsUDEB");
+	// Determine from variant is this udeb
+	if ( m_sVariantType.find( "udeb" ) != string::npos )
+		return true;
+	return false;
+}
+// ----------------------------------------------------------------------------
+// Private AddressToLine related methods
+// ----------------------------------------------------------------------------
+bool CATModule2::InitializeAddressToLine()
+{
+	LOG_FUNC_ENTRY("CATModule2::InitializeAddressToLine");
+	bool bRet = true;
+	// Read in different way depending on platform
+	if ( m_sVariantPlatform.compare("armv5") == 0 )
+	{
+		// Add static library lst files to source vector,
+		// before reading them.
+		vector<string> vFiles = DirList( AT_TEMP_LST_DIR, false, true );
+		for(vector<string>::iterator it = vFiles.begin() ; it != vFiles.end() ; it ++ )
+		{
+			SOURCE source;
+			source.bStatic = true;
+			source.sLst = *it;
+			source.sCpp = *it;
+			source.sCpp = CATBase::RemovePathAndExt( source.sCpp, false );
+			source.sCpp.append( ".cpp" );
+			m_vSources.push_back( source );
+		}
+
+		if ( ! ReadListingFilesArmv5() )
+			bRet = false;
+		if ( ! ReadMapFileArmv5() )
+			bRet = false;
+
+		if ( bRet )
+			m_bAddressToLineInitialized = true;
+	}
+	return bRet;
+}
+
+
+bool CATModule2::ReadListingFilesArmv5()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadListingFilesArmv5");
+	char cTemp[MAX_LINE_LENGTH];
+	vector<SOURCE>::iterator viFileIter = m_vSources.begin();
+	int iNumberOfLstFiles = (int)m_vSources.size();
+	vector<string> vTempLines;
+	string sFileName;
+
+	// Open all .lst files
+	while( iNumberOfLstFiles > 0 )
+	{
+		// Make .lst file name
+		sFileName.clear();
+	
+		// If lst file is not from static library make path to modules temporary directory.
+		if ( viFileIter->bStatic != true )
+		{
+			// Remove path
+			if( viFileIter->sLst.find("\\") != string::npos )
+				sFileName.append(
+				viFileIter->sLst.substr( viFileIter->sLst.find_last_of( "\\" ) + 1
+				, viFileIter->sLst.size() ) );
+			else
+				sFileName.append( viFileIter->sLst );
+
+			// Add temporary dir
+			sFileName.insert( 0, m_sTempPath );
+		}
+		else
+		{
+			// Lst from static library don't change path.
+			sFileName = viFileIter->sLst;
+		}
+		// Open lst file
+		ifstream in( sFileName.c_str() );
+
+		// If file can not be opened, try to open next file
+		if( !in.good() )
+		{
+			viFileIter++;
+			iNumberOfLstFiles--;
+			continue;
+		}
+
+		string sTemp;
+		// Clear temporary lines
+		vTempLines.clear();
+		// Add all lines to temp list
+		do
+		{
+			in.getline( cTemp, MAX_LINE_LENGTH );
+			sTemp.clear();
+			sTemp.append( cTemp );
+			vTempLines.push_back( sTemp );
+		}
+		while( in.good() );
+
+		LINE_IN_FILE structLineInFile;
+		
+		bool bFindENDP = false;
+		vector<string>::iterator viLinesIter = vTempLines.begin();
+
+		// Loop throw all lines in .lst file
+		while( viLinesIter != vTempLines.end() )
+		{
+			// Find ";;;"
+			if( !bFindENDP && strstr(viLinesIter->c_str(), ";;;") != NULL )
+			{
+				bFindENDP = true;
+
+				vector<string>::iterator viLineTempIter = viLinesIter;
+
+				// Find top line of function definition
+				while( viLineTempIter->size() > 0 )
+				{
+					viLineTempIter--;
+				}
+				viLineTempIter++;
+				structLineInFile.sFunction.clear();
+				structLineInFile.sFunction.append( viLineTempIter->c_str() );
+
+				viLinesIter++;
+				// Get Line
+				sTemp.clear();
+				sTemp.append( viLinesIter->c_str() );
+				sTemp.erase(0,3);
+				size_t iSize = sTemp.find_first_of(' ');
+				if( iSize != string::npos )
+					sTemp.resize(iSize);
+				structLineInFile.iLine = atoi( sTemp.c_str() );
+
+				structLineInFile.sFileName.clear();
+				structLineInFile.sFileName.append( viFileIter->sCpp.c_str() );
+				structLineInFile.sLstName = sFileName;
+				m_vLineInFile.push_back( structLineInFile );
+			}
+			else if( strstr(viLinesIter->c_str(), "ENDP") != NULL )
+				bFindENDP = false;
+			viLinesIter++;
+		}
+		viFileIter++;
+		iNumberOfLstFiles--;
+	}
+	if( m_vLineInFile.size() > 0 )
+		return true;
+	return false;
+}
+
+bool CATModule2::ReadMapFileArmv5()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadMapFileArmv5");
+	// Map file name
+	string sMapFileName	= GetMapFile();
+	// Remove path
+	if ( sMapFileName.find("\\") != string::npos )
+		sMapFileName.erase(0, sMapFileName.find_last_of('\\')+1 );
+	// Add temp path
+	sMapFileName.insert(0, m_sTempPath );
+
+	// Open .map file
+	ifstream in( sMapFileName.c_str() );
+	
+	// File open ok?
+	if( ! in.good() )
+	{
+		in.close();
+		return false;
+	}
+	char cTemp[MAX_LINE_LENGTH];
+	bool bFirstFuncFound = false;
+	// Get all lines where is "Thumb"
+	do
+	{
+		// Load one line from .map file
+		in.getline( cTemp, MAX_LINE_LENGTH );
+		// Find _E32Startup
+		if( !bFirstFuncFound && ( strstr( cTemp, "_E32Startup" ) != NULL) )
+		{
+			bFirstFuncFound = true;
+		}
+		else if( !bFirstFuncFound && ( strstr( cTemp, "_E32Dll" ) != NULL) )
+		{
+			bFirstFuncFound = true;
+		}
+		else if( !bFirstFuncFound )
+			// Skip if _E32Startup not found
+			continue;
+
+		if( strstr( cTemp, "Thumb Code" ) != NULL || strstr( cTemp, "ARM Code" ) != NULL)
+		{
+			MAP_FUNC_INFO structMapFileLineInfo;
+			structMapFileLineInfo.sWholeLine.append( cTemp );
+
+			// Get memory string address from line
+			char* pStart = strstr( cTemp, "0x" );
+			// Check did strstr return null.
+			if( pStart == NULL )
+				continue;
+			char* pTemp = pStart;
+			char TempString[MAX_LINE_LENGTH];
+			TempString[0] = 0;
+			size_t iLength = 0;
+			while( *pTemp != ' ' )
+			{
+				TempString[iLength] = *pTemp;
+				pTemp++;
+				iLength++;
+			}
+			TempString[iLength] = 0;
+
+			structMapFileLineInfo.iAddress = CATDatParser::_httoi( TempString );
+
+			pTemp = cTemp;
+			TempString[0] = 0;
+			
+			// Get function name
+
+			// Skip spaces
+			while( *pTemp == ' ' )
+			{
+				pTemp++;
+			}
+			iLength = 0;
+			// Find end of function name
+			string sTemp( pTemp );
+
+			// Location of character ')'
+			iLength = sTemp.find_first_of(')');
+
+			// Location of character ' '
+			size_t iLength2 = sTemp.find_first_of(' ');
+			
+			// If ')' character is the last char and
+			// character ' ' is closer than ')' use location of ' '
+			if( ( iLength + 1 ) == sTemp.length() && iLength2 < iLength )
+				iLength = iLength2 - 1;
+			
+			if( iLength != string::npos )
+				sTemp.resize( (iLength + 1) );
+
+			structMapFileLineInfo.sFunctionName.append( sTemp.c_str() );
+
+			bool bARM = false;
+			// Find function length
+			pStart = strstr( cTemp, "Thumb Code" );
+			if( pStart == NULL )
+			{
+				pStart = strstr( cTemp, "ARM Code" );
+				bARM = true;
+			}
+			if( pStart != NULL )
+			{
+				if( bARM )
+					pStart += 8;
+				else
+					pStart += 10;
+				while(*pStart == ' ')
+				{
+					pStart++;
+				}
+				sTemp.clear();
+				sTemp.append( pStart );
+				size_t iSize = sTemp.find_first_of(' ');
+				if( iSize != string::npos )
+					sTemp.resize( iSize );
+			}
+
+			structMapFileLineInfo.iFuncLength = atoi( sTemp.c_str() );
+			if( bFirstFuncFound && structMapFileLineInfo.iFuncLength > 0 )
+				// Save to list
+				m_vMapFileFuncList.push_back( structMapFileLineInfo );
+		}
+	}
+	while( in.good() );
+	in.close();
+	return true;
+}
+
+int CATModule2::FindLeakCodeLine( string& sFileName, int iLine, unsigned long iFromFuncAddress ) const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::FindLeakCodeLine");
+	if ( sFileName.empty() )
+		return -1;
+	char cLineFromFile[MAX_LINE_LENGTH];
+	vector<string> vTempLines;
+	string sTemp;
+	char* pTemp = NULL;
+	char* pTempEnd = NULL;
+	int iFoundLine = -1;
+	int iRet = -1;
+	
+	// Open lst file
+	ifstream in( sFileName.c_str() );
+
+	bool bLineFound = false;
+	bool bFirstAddressInFuncFound = false;
+	unsigned long iFirstAddressInFunc = 0;
+	while( in.good() )
+	{
+		in.getline( cLineFromFile, MAX_LINE_LENGTH );
+
+		if( bLineFound )
+		{
+			vTempLines.push_back( cLineFromFile );
+			// Is first character digit
+			if( isdigit( cLineFromFile[0] ) )
+			{
+				if( !bFirstAddressInFuncFound )
+				{
+					bFirstAddressInFuncFound = true;
+					sTemp.clear();
+					sTemp.append( cLineFromFile );
+					// Get value until next space
+					sTemp.resize( sTemp.find_first_of(' ') );
+
+					iFirstAddressInFunc = CATDatParser::_httoi( sTemp.c_str() );
+
+					// Return function start line if margin 0
+					if( iFromFuncAddress == 0 )
+					{
+						iRet = iLine;
+						return iRet;
+					}
+				}
+				else
+				{
+					// Find correct line using iFromFuncAddress variable
+					sTemp.clear();
+					sTemp.append( cLineFromFile );
+					// Get value until next space
+					sTemp.resize( sTemp.find_first_of(' ') );
+
+					unsigned long iValue = CATDatParser::_httoi( sTemp.c_str() );
+
+					if( ( iValue - iFirstAddressInFunc ) >= iFromFuncAddress )
+					{
+						// If there is data in function, code line can not be found
+						if( strstr( cLineFromFile , "DCB" ) != NULL )
+						{
+							iRet = -1;
+							return iRet;
+						}
+						pTemp = strstr( cLineFromFile, ";" );
+						// Get line number
+						bool bStringNumber = true;
+						if( pTemp != NULL )
+						{
+							string sTempLine( pTemp + 1 );
+							// Are all characters numbers?
+							for( unsigned int i = 0 ; i < sTempLine .size() ; i++ )
+							{
+								if( !isdigit(sTempLine[i]) )
+								{
+									bStringNumber = false;
+									break;
+								}
+							}
+						}
+						else
+							bStringNumber = false;
+						if( bStringNumber )
+						{
+							pTemp++;
+							// Get line number
+							iRet = atoi( pTemp );
+						}
+						else
+						{
+							vector<string>::iterator sTempIter = vTempLines.end();
+
+							sTempIter--;
+
+							// Find last code line
+							while( sTempIter != vTempLines.begin() )
+							{
+								if( strstr( sTempIter->c_str() , "DCB" ) != NULL )
+								{
+									iRet = -1;
+									return iRet;
+								}
+								if( strstr( sTempIter->c_str() , ";;;" ) == NULL )
+									sTempIter--;
+								else
+									break;
+							}
+							if(sTempIter == vTempLines.begin() && strstr( sTempIter->c_str() , ";;;" ) == NULL)
+							{
+								iRet = -1;
+								return iRet;
+							}
+							sTempIter->erase( 0, 3 );
+							sTempIter->resize( sTempIter->find(' ') );
+
+							// Leak line
+							iRet = atoi( sTempIter->c_str() );
+						}
+						return iRet;
+					}
+				}
+			}
+		}
+		else // Line in file not found
+		{
+			// Find line of function
+			if( strstr( cLineFromFile, ";;;" ) != NULL )
+			{
+				pTemp = &cLineFromFile[0];
+				// Skip characters ";;;"
+				pTemp += 3;
+				pTempEnd = pTemp;
+				// Find end of line number
+				while( *pTempEnd != ' ' )
+				{
+					pTempEnd++;
+				}
+				*pTempEnd = 0;
+				iFoundLine = atoi( pTemp );
+				*pTempEnd = ' ';
+				if( iLine == iFoundLine )
+				{
+					bLineFound = true;
+				}
+			}
+		}
+	}
+	return iRet;
+}
+
+bool CATModule2::IsMakeSuccessfull()
+{
+	LOG_FUNC_ENTRY("CATModule2::IsMakeSuccessfull");
+	m_sErrors.clear();
+
+	string sSearch;
+	bool bMakeSuccess = true;
+	
+	// Lst files checked only with armv5 platform.
+	if ( IsPlatformArmv5() )
+	{
+		sSearch.append( m_sTempPath );
+		sSearch.append( "*.lst" );
+		if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+			bMakeSuccess = false;
+		
+		// Map
+		sSearch.clear();
+		sSearch.append( m_sTempPath );
+		sSearch.append( "*.map" );
+		if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+			bMakeSuccess = false;
+	}
+
+	// .tmp
+	sSearch.clear();
+	sSearch.append( m_sTempPath );
+	sSearch.append( "*.tmp" );
+	if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+		bMakeSuccess = false;
+
+	return bMakeSuccess;
+}
+
+bool CATModule2::CreateBuildCompleteFile()
+{
+	LOG_FUNC_ENTRY("CATModule2::CreateBuildCompleteFile");
+	// Don't create file if temp path not set cause might be anywhere
+	if ( m_sTempPath.empty() )
+		return false;
+	// Create empty file indicating this module is build
+	string sFile = m_sTempPath;
+	if( sFile.at( sFile.length() - 1 ) != '\\' )
+		sFile.append("\\");
+	sFile.append( "BuildComplete" );
+	ofstream out( sFile.c_str() );
+	out << m_sVariantPlatform << endl;
+	out << m_sVariantType << endl;
+	out.close();
+	return true;
+}
+
+bool CATModule2::ReadMakeFileFromTemp()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadMakeFileFromTemp");
+	// Set makefile to point to temporary directory.
+	string sMakeFile = m_sTempPath;
+	sMakeFile.append( RemovePathAndExt( m_Mmp.m_sMmpFile, true ) );
+	sMakeFile.append( "." );
+	sMakeFile.append( AT_LEVEL_2_MAKEFILE_EXT );
+	m_sMakeFile = sMakeFile;
+	return ReadMakeFilePrivate();
+}
+
+bool CATModule2::ReadMakeFile()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadMakeFile");
+	// Read makefile
+	if ( ReadMakeFilePrivate() )
+	{
+		// Copy makefile to temporary directory.
+		string sMakeFile = m_sTempPath;
+		sMakeFile.append( RemovePathAndExt( m_Mmp.m_sMmpFile, true ) );
+		sMakeFile.append( "." );
+		sMakeFile.append( AT_LEVEL_2_MAKEFILE_EXT );
+		FileCopyToPath( m_sMakeFile, sMakeFile );
+		return true;
+	}
+	return false;
+}
+
+bool CATModule2::ReadMakeFilePrivate()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadMakeFilePrivate");
+
+	if ( m_sMakeFile.empty() )
+		return false;
+
+	LOG_STRING( "using makefile :" << m_sMakeFile );
+
+	// Stream object to read files
+	ifstream in;
+	// Char array to read line from file
+	char cLine[MAX_LINE_LENGTH];
+	// String to use as buffer from file
+	string sLine;
+	// Open file
+	in.open( m_sMakeFile.c_str(), ios_base::in );
+	// Check that its open
+	if ( ! in.good() )
+	{
+		// Cannot open file
+		cout << AT_MSG << "Error, can not open file: " << m_sMakeFile << endl;
+		return false;
+	}
+	// Check is it wrapper makefile (starts with "%:")
+	in.getline( cLine, MAX_LINE_LENGTH );
+	if ( cLine[0] == '%' && cLine[1] == ':' )
+	{
+		LOG_STRING("Found wrapper makefile");
+		in.close();
+		// Use ".default" makefile
+		string sDefaultMakeFile = m_sMakeFile.substr( 0, m_sMakeFile.find_last_of( "." ) );
+		sDefaultMakeFile.append( ".DEFAULT" );
+		LOG_STRING( "using makefile :" << m_sMakeFile );
+		// Does default exists. If not we need to run "wrapper make"
+		if ( ! FileExists( sDefaultMakeFile.c_str() ) )
+		{
+			// Run the wrapper make to create "real" makefile
+			string sMakeFileCmd;
+			sMakeFileCmd.append("make -f \"");
+			sMakeFileCmd.append( m_sMakeFile );
+			sMakeFileCmd.append( "\"" );
+			LOG_STRING( "using makefile :" << m_sMakeFile );
+			cout << AT_MSG_SYSTEM_CALL << sMakeFileCmd << endl;
+			int iRet = (int)system( sMakeFileCmd.c_str() );
+			if ( iRet )
+			{
+				cout << MAKE_ERROR;
+				return false;
+			}
+		}
+		m_sMakeFile = sDefaultMakeFile;
+		// Open new file
+		in.open( m_sMakeFile.c_str(), ios_base::in );
+		// Check that it's open
+		if ( ! in.good() )
+		{
+			// Cannot open file
+			cout << AT_MSG << "Error, can not open makefile: " << m_sMakeFile << endl;
+			return false;
+		}
+	}
+	in.seekg( ios_base::beg );
+
+	// Number of lines to read at max for basic module information.
+	int iReadLineCount = 20;
+	// Extension from target line. to be compared with targettype.
+	string sTargetExtension;
+	// Read line at a time. Loop until we find it or eof
+	do {
+		// Read line from file to array
+		in.getline( cLine, MAX_LINE_LENGTH );
+		iReadLineCount--;
+
+		sLine.clear();
+		// Put that to string
+		sLine.append( cLine );
+		// Search target
+		if ( sLine.find( MAKEFILE_TARGET_STRING ) != string::npos )
+		{
+			// Found it. Now remove other than type from line
+			sLine.erase( 0, strlen( MAKEFILE_TARGET_STRING ) );
+			ChangeToLower( sLine );
+			sTargetExtension.clear();
+			sTargetExtension = GetExtension( sLine );
+			m_sTarget = RemovePathAndExt( sLine, true);
+			LOG_STRING("found target: " << sLine );
+		}
+		// Search targettype
+		else if ( sLine.find( MAKEFILE_TARGETTYPE_STRING ) != string::npos )
+		{
+			// Found it. Now remove other than type from line
+			sLine.erase( 0, strlen( MAKEFILE_TARGETTYPE_STRING ) );
+			ChangeToLower( sLine );
+			m_sTargetType = sLine;
+			LOG_STRING("found target type: " << m_sTargetType );
+		}
+		else if ( sLine.find( MAKEFILE_BASIC_TARGETTYPE_STRING ) != string::npos )
+		{
+			sLine.erase( 0, strlen( MAKEFILE_BASIC_TARGETTYPE_STRING ) );
+			ChangeToLower( sLine );
+			m_sRequestedTargetExt = sLine;
+			// Compare with the extension in target line if not same use target lines if its "valid".
+			if ( m_sRequestedTargetExt.compare( sTargetExtension ) != 0  && sTargetExtension.size() > 0 )
+				m_sRequestedTargetExt = sTargetExtension;
+			LOG_STRING("found requested target extension: " << m_sTargetType );		
+		}
+		// Feature variant details
+		else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_NAME ) != string::npos )
+		{
+			sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_NAME ) );
+			m_sFeatureVariantName = sLine;
+			LOG_STRING("found feature variant name: " << sLine );
+		}
+		else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_UREL_LABEL ) != string::npos )
+		{
+			sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_UREL_LABEL ) );
+			LOG_STRING("found feature variant urel label: " << sLine );
+			if ( sLine.compare("INVARIANT") != 0 )
+				m_sFeatureVariantURELLabel = sLine;
+		}
+		else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_UDEB_LABEL ) != string::npos )
+		{
+			sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_UDEB_LABEL ) );
+			LOG_STRING("found feature variant udeb label: " << sLine );
+			if ( sLine.compare("INVARIANT") != 0 )
+				m_sFeatureVariantUDEBLabel = sLine;
+		}
+	} while( in.good() && iReadLineCount > 0 );
+
+	// Search compile definitions
+	// CWDEFS CCDEFS ARMCCDEFS
+	do
+	{
+		in.getline( cLine, MAX_LINE_LENGTH );
+		sLine.clear();
+		sLine.append( cLine );
+		if ( sLine.substr( 0 , 6 ).compare( string("CWDEFS") ) == 0 
+			|| sLine.substr( 0 , 6 ).compare( string("CCDEFS") ) == 0 )
+		{
+			sLine.erase( 0, 8 );
+			m_sCompileDefinitions = sLine;
+			break;
+		}
+		else if( sLine.substr( 0 , 9 ).compare( string("ARMCCDEFS") ) == 0  )
+		{
+			sLine.erase( 0, 11 );
+			m_sCompileDefinitions = sLine;
+			break;
+		}
+	} while( in.good() );
+	// Move reading back to start if we could not find compile flags.
+	in.seekg( ios_base::beg );
+
+	// Search listing information (modules source files).
+	int iFindItem = 1; //1 = Source, 2 = LISTINGUDEB/UREL, 3 = lst file
+	string sCdefs;
+	string sSource;
+	string sLst;
+	do
+	{
+		in.getline( cLine, MAX_LINE_LENGTH );
+		sLine.clear();
+		sLine.append( cLine );
+
+		switch( iFindItem )
+		{
+			case 1:
+				if( sLine.find( "# Source " ) != string::npos )
+				{
+					iFindItem = 2;
+					// Remove text "# Source "
+					sLine.erase( 0, 9 );
+					sSource = sLine;
+				}
+			break;
+			case 2:
+				if( IsUDEB() )
+				{
+					if( sLine.find( "LISTINGUDEB" ) != string::npos )
+					{
+						iFindItem = 3;
+					}
+				}
+				else
+				{
+					if( sLine.find( "LISTINGUREL" ) != string::npos )
+					{
+						iFindItem = 3;
+					}
+				}
+			break;
+			case 3:
+				if( sLine.find( "perl -S ecopyfile.pl" ) != string::npos )
+				{
+					// Save lst file to list
+					sLine.erase( 0, ( sLine.find_first_of( "\\" ) ) );
+					// remove last char if '"'
+					if ( sLine.at( sLine.size()-1 ) == '"' )
+						sLine.erase( sLine.size()-1, sLine.size() );
+					sLst = sLine;
+					AddSource( sSource, sLst );
+					iFindItem = 1;
+					sSource.clear(); sLst.clear();
+					
+				}
+			break;
+		}
+	}
+	while( in.good() );
+	// close and return
+	in.close();
+	return true;
+}
+
+// ----------------------------------------------------------------------------
+// Get & Sets
+// ----------------------------------------------------------------------------
+string CATModule2::GetErrors() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetErrors");
+	return m_sErrors;
+}
+
+string CATModule2::GetS60FileName() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetS60FileName");
+	if ( m_sS60FileName.empty() )
+	{
+		string sGeneratedDatName = m_sTarget;
+		sGeneratedDatName.append(".");
+		sGeneratedDatName.append( m_sTargetType );
+		sGeneratedDatName.append(".dat");
+		return sGeneratedDatName;
+	}
+	return m_sS60FileName;
+}
+
+string CATModule2::GetLstNameOfSource(string sSource) const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetLstNameOfSource");
+	// Find . before xtension
+	size_t iSpot = sSource.find_last_of( "." );
+	// Get sub string to there
+	string sLst = sSource.substr(0, iSpot+1);
+	if ( m_sVariantPlatform.compare( "winscw" ) != 0 )
+	{
+		// Add variant platform (i.e. armv5)
+		sLst.append( m_sVariantPlatform );
+		sLst.append( "." );
+		// Add variant type (i.e. build type liek urel)
+		sLst.append( m_sVariantType );
+		sLst.append( "." );
+		// Add target binary name
+		sLst.append( m_sTarget );
+		sLst.append( "." );
+		// Add target requested binary extension
+		sLst.append( m_sRequestedTargetExt );
+		sLst.append( "." );
+		// Add lst extension
+		sLst.append( "lst" );
+	}
+	else
+	{
+		sLst.append( "WINSCW.lst" );
+	}
+	return sLst;
+}
+
+bool CATModule2::IsPlatformArmv5() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::IsPlatformArmv5");
+	if ( _stricmp( m_sVariantPlatform.c_str(), "armv5" ) == 0 )
+		return true;
+	return false;
+}
+
+string CATModule2::GetMapFile() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetMapFile");
+	// Map file with path using variables
+	string sMapFile( m_sReleasePath );
+	if ( ! sMapFile.empty() )
+		sMapFile.append( "\\" );
+	sMapFile.append( m_sFullVariantPath );
+	if ( ! m_sFullVariantPath.empty() )
+		sMapFile.append( "\\" );
+	sMapFile.append( m_sTarget );
+	sMapFile.append( "." );
+	// Possible feature variant. Note debug might not be defined
+	// when release has got one.
+	if ( IsUDEB() && !m_sFeatureVariantUDEBLabel.empty() )
+	{
+		sMapFile.append( m_sFeatureVariantUDEBLabel );
+		sMapFile.append( "." );
+	}
+
+	if ( !IsUDEB() && !m_sFeatureVariantURELLabel.empty() )
+	{
+		sMapFile.append( m_sFeatureVariantURELLabel );
+		sMapFile.append( "." );
+	}
+	sMapFile.append( m_sRequestedTargetExt );
+	sMapFile.append( ".map" );
+	return sMapFile;
+}
+
+string CATModule2::GetSymbolFile() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetSymbolFile");
+	// Symbol file with path using variables
+	string sSymbolFile( m_sReleasePath );
+	sSymbolFile.append( "\\" );
+	sSymbolFile.append( m_sFullVariantPath );
+	sSymbolFile.append( "\\" );
+	sSymbolFile.append( m_sTarget );
+	sSymbolFile.append( "." );
+	// Possible feature variant.
+	if ( ! m_sFeatureVariantUDEBLabel.empty() || ! m_sFeatureVariantURELLabel.empty() )
+	{
+		if ( IsUDEB() )
+			sSymbolFile.append( m_sFeatureVariantUDEBLabel );
+		else
+			sSymbolFile.append( m_sFeatureVariantURELLabel );
+		sSymbolFile.append( "." );
+	}
+	
+	if ( m_eBuildSystem == CATProject::SBS_V1 )
+	{
+		sSymbolFile.append( "sym" );
+		return sSymbolFile;
+	}
+	sSymbolFile.append( m_sRequestedTargetExt );
+	sSymbolFile.append( ".sym" );
+	return sSymbolFile;
+}
+
+string CATModule2::GetBinaryFile() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetBinaryFile");
+	// Binary file with path using variables
+	string sBinaryFile( m_sReleasePath );
+	if ( ! sBinaryFile.empty() )
+		sBinaryFile.append( "\\" );
+	sBinaryFile.append( m_sFullVariantPath );
+	if ( ! m_sFullVariantPath.empty() )
+		sBinaryFile.append( "\\" );
+	sBinaryFile.append( m_sTarget );
+	sBinaryFile.append( "." );
+	// Possible feature variant.
+	if ( ! m_sFeatureVariantUDEBLabel.empty() || ! m_sFeatureVariantURELLabel.empty() )
+	{
+		if ( IsUDEB() )
+			sBinaryFile.append( m_sFeatureVariantUDEBLabel );
+		else
+			sBinaryFile.append( m_sFeatureVariantURELLabel );
+		sBinaryFile.append( "." );
+	}
+	sBinaryFile.append( m_sRequestedTargetExt );
+	return sBinaryFile;
+}
+
+bool CATModule2::SetMmpFile(const string& sMmpFile)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetMmpFile");
+	// Set mmp file
+	m_Mmp.m_sMmpFile = sMmpFile;
+	// Change to lower
+	ChangeToLower( m_Mmp.m_sMmpFile );
+	// Convert
+	ConvertUnixPathToWin( m_Mmp.m_sMmpFile );
+	// Set the temporary path.
+	m_sTempPath.clear();
+	m_sTempPath = CreateTempPath( m_Mmp.m_sMmpFile );
+	return true;
+}
+
+bool CATModule2::CreateTemporaryDirectory()
+{
+	LOG_FUNC_ENTRY("CATModule2::CreateTemporaryDirectory");
+	if ( m_sTempPath.empty() )
+	{
+		LOG_STRING("Temporary path is not set.");
+		return false;
+	}
+	// Create temp dir if not exists
+	if ( ! DirectoryExists( m_sTempPath.c_str() ) )
+	{
+		if ( !CreateDirectory( m_sTempPath.c_str(), NULL ) )
+		{
+			cout << AT_MSG << "Error, can not create directory: "
+				<< m_sTempPath << endl;
+			return false;
+		}
+		cout << AT_MSG << "Directory created: " << m_sTempPath << endl;
+	}
+	return true;
+}
+
+void CATModule2::SetMakeFile( const string& sMakeFile )
+{
+	LOG_FUNC_ENTRY("CATModule2::SetMakeFile");
+	m_sMakeFile = sMakeFile;
+}
+string CATModule2::GetMakeFile() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetMakeFile");
+	return m_sMakeFile;
+}
+string CATModule2::GetMmpFile() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetMmpFile");
+	return m_Mmp.m_sMmpFile;
+}
+string CATModule2::GetTempPath() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetTempPath");
+	return m_sTempPath;
+}
+void CATModule2::SetTarget(const string& sTarget)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetTarget");
+	m_sTarget = sTarget;
+	ChangeToLower( m_sTarget );
+}
+string CATModule2::GetTarget() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetTarget");
+	return m_sTarget;
+}
+string CATModule2::GetBinaryName() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetBinaryName");
+	string sBinaryName;
+	sBinaryName.append( m_sTarget );
+	sBinaryName.append( "." );
+	sBinaryName.append( m_sRequestedTargetExt );
+	return sBinaryName;
+}
+
+void CATModule2::SetTargetType(const string& sTargetType)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetTargetType");
+	m_sTargetType = sTargetType;
+	ChangeToLower( m_sTargetType );
+}
+string CATModule2::GetTargetType() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetTargetType");
+	return m_sTargetType;
+}
+void CATModule2::SetRequestedTargetExt( const string& sRequestedTargetExt )
+{
+	LOG_FUNC_ENTRY("CATModule2::SetRequestedTargetExt");
+	m_sRequestedTargetExt = sRequestedTargetExt;
+	ChangeToLower( m_sRequestedTargetExt );
+}
+
+string CATModule2::GetRequestedTargetExt() const
+{
+	LOG_LOW_FUNC_ENTRY("CATmodule2::GetRequestedTargetExt");
+	return m_sRequestedTargetExt;
+}
+
+void CATModule2::SetVariantPlatform(const string& sVariantPlatform)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetVariantPlatform");
+	m_sVariantPlatform = sVariantPlatform;
+	ChangeToLower( m_sVariantPlatform );
+}
+string CATModule2::GetVariantPlatform() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetVariantPlatform");
+	return m_sVariantPlatform;
+}
+void CATModule2::SetVariantType(const string& sVariantType)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetVariantType");
+	m_sVariantType = sVariantType;
+	ChangeToLower( m_sVariantType );
+}
+string CATModule2::GetVariantType() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetVariantType");
+	return m_sVariantType;
+}
+void CATModule2::SetFeatureVariant(const string& sFeatureVariant)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetFeatureVariant");
+	m_sFeatureVariant = sFeatureVariant;
+	ChangeToLower( m_sFeatureVariant );
+}
+string CATModule2::GetFeatureVariant() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetFeatureVariant");
+	return m_sFeatureVariant;
+}
+void CATModule2::SetFeatureVariantName(const string& sFeatureVariantName)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetFeatureVariantName");
+	m_sFeatureVariantName = sFeatureVariantName;
+	ChangeToLower( m_sFeatureVariantName );
+}
+string CATModule2::GetFeatureVariantName() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetFeatureVariantName");
+	return m_sFeatureVariantName;
+}
+void CATModule2::SetReleasePath(const string& sReleasePath)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetReleasePath");
+	m_sReleasePath = sReleasePath;
+	ChangeToLower( m_sReleasePath );
+	ConvertUnixPathToWin( m_sReleasePath );
+
+}
+string CATModule2::GetReleasePath() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetReleasePath");
+	return m_sReleasePath;
+}
+void CATModule2::SetFullVariantPath(const string& sFullVariantPath)
+{
+	LOG_FUNC_ENTRY("CATModule2::SetFullVariantPath");
+	m_sFullVariantPath = sFullVariantPath;
+	ChangeToLower( m_sFullVariantPath );
+	ConvertUnixPathToWin( m_sFullVariantPath );
+}
+string CATModule2::GetFullVariantPath() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetFullVariantPath");
+	return m_sFullVariantPath;
+}
+string CATModule2::GetUniqueId() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetUniqueId");
+	return FilterString( m_sTarget );
+}
+void CATModule2::SetBuildSystem( int eBuildSystem )
+{
+	LOG_FUNC_ENTRY("CATModule2::SetBuildSystem");
+	m_eBuildSystem = eBuildSystem;
+}
+
+int CATModule2::GetBuildSystem() const
+{
+	LOG_LOW_FUNC_ENTRY("CATModule2::GetBuildSystem");
+	return m_eBuildSystem;
+}
+
+void CATModule2::SetCompileDefinitions( const string& sCompileDefinitions )
+{
+	LOG_LOW_FUNC_ENTRY( "CATModule2::SetCompileDefinitions" );
+	m_sCompileDefinitions = sCompileDefinitions;
+}
+
+string CATModule2::GetCompileDefinitions() const
+{
+	LOG_LOW_FUNC_ENTRY( "CATModule2::GetCompileDefinitions" );
+	return m_sCompileDefinitions;
+}
+
+void CATModule2::SetCompileInfoText( string sCompileInfoText )
+{
+	LOG_LOW_FUNC_ENTRY( "CATModule2::SetCompileInfoText" );
+	m_sCompileInfoText = sCompileInfoText;
+}
+string CATModule2::GetCompileInfoText() const
+{
+	LOG_LOW_FUNC_ENTRY( "CATModule2::GetCompileInfoText" );
+	return m_sCompileInfoText;
+}
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATParseTraceFile.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,585 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATParseTraceFile.
+*
+*/
+
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/catdatasaver.h"
+#include "../inc/CATDatParser.h"
+
+#include <time.h>
+
+#define MAIN_ID "PCSS"
+#define ALLOC_ID "ALLOC" // < V.1.6 allocation.
+#define ALLOCH_ID "ALLOCH" // Header of multi message allocation.
+#define ALLOCF_ID "ALLOCF" // Fragment of multi message allocation.
+#define FREE_ID "FREE"
+#define FREEH_ID "FREEH" // Header of multi message free.
+#define FREEF_ID "FREEF" // Fragment of multi message free.
+#define HANDLE_LEAK_ID "HANDLE_LEAK"
+
+const string ERROR_OCCURED = "ERROR_OCCURED"; // Error messages.
+const string INCORRECT_ATOOL_VERSION = "INCORRECT_ATOOL_VERSION";
+/**
+* Invalid characters in trace file line content.
+* These will be filtered out before actuall parsing of line.
+10 = LF
+13 = CR
+124 = |
+*/
+const char cINVALID_TRACE_FILE_CHARS[] = { 10, 13, 124 };
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::CATParseTraceFile
+// Constructor.
+// -----------------------------------------------------------------------------
+CATParseTraceFile::CATParseTraceFile()
+{
+	LOG_FUNC_ENTRY("CATParseTraceFile::CATParseTraceFile");
+	m_DataSaver.SetPrintFlag( false );
+}
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::StartParse
+// Main function to start trace parsing.
+// -----------------------------------------------------------------------------
+bool CATParseTraceFile::StartParse( const char* pFileName, const char* pOutputFileName )
+{
+	LOG_FUNC_ENTRY("CATParseTraceFile::StartParse");
+
+	// Return value, will be changed to true if process start found.
+	bool bRet = false;
+
+	// Check pointers
+	if ( pFileName == NULL  )
+		return bRet;
+
+	if( pOutputFileName == NULL )
+		return bRet;
+
+	if ( ! FileExists( pFileName ) )
+	{
+		cout << AT_MSG << "Error, input file \""
+			<< pFileName
+			<< "\" does not exist." << endl;
+		return bRet;
+	}
+
+	// Open data file
+	ifstream in( pFileName );
+
+	// Check file opened ok
+	if ( !in.good() )
+		return false;
+
+	// Get stream size
+	size_t streamPos = in.tellg();
+	in.seekg( 0, ios::end);
+	size_t streamEnd = in.tellg();
+	in.seekg( 0, ios::beg);
+
+	//Origianl characters (not filtered).
+	char cOriginalLineFromFile[MAX_LINE_LENGTH];
+
+	vector<CProcessData> vProcessList;
+	int iProcessIDinList = -1;
+
+	bool bFileVersionSaved = false;
+	// Read lines
+	while( streamPos < streamEnd )
+	{
+		// Get one line. Don't use stream flags to determinate end of file
+		// it can be found too early because trace can contain "anything".
+		in.getline( cOriginalLineFromFile, MAX_LINE_LENGTH );
+		
+		// Refresh position
+		streamPos = in.tellg();
+
+		// Check has bad bit flag raised. (i.e. device problems reading data)
+		if( in.bad() )
+		{
+			cout << AT_MSG << "Integrity error reading the trace file, reading aborted." << endl;
+			return false;
+		}
+		//Filtered characters.
+		char cLineFromFile[MAX_LINE_LENGTH];
+		char* pFiltered = cLineFromFile;
+
+		//Loop thru all characters in original line.
+		for( size_t i = 0 ; cOriginalLineFromFile[i] != 0 ; i++ )
+		{
+			//If character in line is not in invalid character array append it
+			//to filtered line.
+			if ( strchr( cINVALID_TRACE_FILE_CHARS, cOriginalLineFromFile[i] ) == 0 )
+					*pFiltered++ =  cOriginalLineFromFile[i];
+		}
+		*pFiltered++ = 0; //Add null termination to filtered line.
+
+		if( !bFileVersionSaved && *cLineFromFile != 0 )
+		{
+			bFileVersionSaved = true;
+			m_DataSaver.AddString( AT_DATA_FILE_VERSION );
+			m_DataSaver.AddLineToLast();
+		}
+
+		// Is there main ID?
+		if( strstr( cLineFromFile, MAIN_ID ) != NULL )
+		{
+			string sRestOfLine( cLineFromFile );
+			string sTemp;
+
+			// Delete all characters before main ID
+			sRestOfLine.erase( 0, sRestOfLine.find( MAIN_ID ) );
+
+			// Get main ID
+			sTemp = GetStringUntilNextSpace( sRestOfLine );
+
+			// Is there more data in line?
+			if( sRestOfLine.empty() )
+			{
+				continue;
+			}
+
+			// Get next argument
+			sTemp = GetStringUntilNextSpace( sRestOfLine );
+			// This might be process id or error message
+			if ( sTemp.compare( ERROR_OCCURED ) == 0 )
+			{
+				// Api mismatch between s60 side and atool.exe
+				if ( sRestOfLine.find( INCORRECT_ATOOL_VERSION ) != string::npos )
+				{
+					cout << "Test run failed because version conflict between device binaries\nand the atool.exe version used to build the application." << endl;
+					size_t pS = sRestOfLine.find_first_of('[');
+					size_t pE =  sRestOfLine.find_first_of(']');
+					size_t pSL = sRestOfLine.find_last_of('[');
+					size_t pEL = sRestOfLine.find_last_of(']');
+					if ( pS != string::npos && pE != string::npos && pSL != string::npos && pEL != string::npos )
+					{
+						string deviceVer = sRestOfLine.substr( pS+1, pE-pS-1 );
+						string atoolVer = sRestOfLine.substr( pSL+1, pEL-pSL-1 );
+						cout << "\tdevice: " << deviceVer << endl 
+							<<  "\tatool.exe: " << atoolVer << endl;
+					}
+				}
+				else
+					cout << sRestOfLine << endl;
+				continue;
+			}
+			unsigned long iProcessID = _httoi( sTemp.c_str() );
+
+			iProcessIDinList = -1;
+			// Find process from list
+			for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
+			{
+				if( vProcessList[i].iProcessID == iProcessID )
+				{
+					iProcessIDinList = i;
+					break;
+				}
+			}
+			// Is Process ID found from list?
+			if( iProcessIDinList == -1 )
+			{
+				CProcessData ProcessData;
+				ProcessData.bProcessOnGoing = false;
+				ProcessData.iProcessID = iProcessID;
+				vProcessList.push_back( ProcessData );
+				iProcessIDinList = (int)vProcessList.size() - 1;
+			}
+
+			// Remove spaces from end of line
+			while( sRestOfLine[sRestOfLine.size()-1] == ' ' )
+			{
+				sRestOfLine.resize( sRestOfLine.size()-1 );
+			}
+
+			string sWholeTempLine( sRestOfLine );
+
+			// Get command
+			sTemp = GetStringUntilNextSpace( sRestOfLine );
+
+			// Use c style string for easy comparisong of command.
+			const char* pCommand = sTemp.c_str();		
+
+			// Process start.
+			if( ! _stricmp( pCommand, LABEL_PROCESS_START ) )
+			{
+				bRet = true; // Set return value true we found start.
+				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+				vProcessList[iProcessIDinList].bProcessOnGoing = true;
+				continue;
+			}
+
+			// Check is process ongoing if not skip other tags.
+			if( vProcessList[iProcessIDinList].bProcessOnGoing == false )
+				continue;
+
+			// "Old style" allocation (< v.1.6)
+			if( ! _stricmp( pCommand, ALLOC_ID ) )
+			{
+				// Add alloc
+				vProcessList[iProcessIDinList].Alloc( sRestOfLine );
+
+				// Subtests running?
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->bRunning )
+					{
+						// Save alloc also to sub test
+						viSubTestIter->Alloc( sRestOfLine );
+					}
+					viSubTestIter++;
+				}
+			}
+			else if ( ! _stricmp( pCommand, ALLOCH_ID ) )
+			{
+				// Add alloc
+				vProcessList[iProcessIDinList].AllocH( sRestOfLine );
+
+				// Subtests running?
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->bRunning )
+					{
+						// Save alloc also to sub test
+						viSubTestIter->AllocH( sRestOfLine );
+					}
+					viSubTestIter++;
+				}
+			}
+			// Allocation fragment (call stack).
+			else if ( ! _stricmp( pCommand, ALLOCF_ID ) )
+			{
+				// Add alloc fragment
+				vProcessList[iProcessIDinList].AllocF( sRestOfLine );
+				
+				// Subtests running?
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->bRunning )
+					{
+						// Save alloc fragment also to sub test
+						viSubTestIter->AllocF( sRestOfLine );
+					}
+					viSubTestIter++;
+				}
+			}
+			// Command free
+			else if( ! _stricmp( pCommand, FREE_ID ) )
+			{
+				// Send free
+				vProcessList[iProcessIDinList].Free( sRestOfLine );
+
+				// Subtests running?
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->bRunning )
+					{
+						// Send free to subtest
+						viSubTestIter->Free( sRestOfLine );
+					}
+					viSubTestIter++;
+				}
+			}
+			// Header free.
+			else if( ! _stricmp( pCommand, FREEH_ID ) )
+			{
+				// Send free
+				vProcessList[iProcessIDinList].FreeH( sRestOfLine );
+
+				// Subtests running?
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->bRunning )
+					{
+						// Send free to subtest
+						viSubTestIter->FreeH( sRestOfLine );
+					}
+					viSubTestIter++;
+				}
+			
+			}
+			else if( ! _stricmp( pCommand, FREEF_ID ) )
+			{
+				// Not used currently.
+			}
+			// Command process end
+			else if( ! _stricmp( pCommand, LABEL_PROCESS_END ) )
+			{
+				// Set process has ended.
+				vProcessList[iProcessIDinList].bProcessOnGoing = false;
+
+				// Save leaks
+				vector<string> vLeaks;
+				vector<string>::iterator viLeaks;
+				vProcessList[iProcessIDinList].GetLeakList( vLeaks );
+				for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
+				{
+					sTemp.clear();
+					sTemp.append( LABEL_MEM_LEAK );
+					sTemp.append( " " );
+					sTemp.append( *viLeaks );
+					vProcessList[iProcessIDinList].vData.push_back( sTemp );
+				}
+				vProcessList[iProcessIDinList].ClearAllocs();
+
+				vector<string>::iterator viHandleIter = vProcessList[iProcessIDinList].vHandleLeaks.begin();
+				// Print handle leaks
+				while( viHandleIter != vProcessList[iProcessIDinList].vHandleLeaks.end() )
+				{
+					sTemp.clear();
+					sTemp.append( viHandleIter->c_str() );
+					vProcessList[iProcessIDinList].vData.push_back( sTemp );
+					viHandleIter++;
+				}
+				// Clear handle leaks from list
+				vProcessList[iProcessIDinList].vHandleLeaks.clear();
+
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				// Print sub test leaks
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					// Print sub test start
+					string sLine( LABEL_TEST_START ); sLine.append( " " );
+					sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
+					sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+					sLine.append( viSubTestIter->sSubTestStartHandleCount );
+					vProcessList[iProcessIDinList].vData.push_back( sLine );
+					sLine.clear();
+
+					// DLL Loads.
+					for( vector<string>::iterator it = viSubTestIter->vData.begin();
+						it != viSubTestIter->vData.end(); it++ )
+					{
+						vProcessList[iProcessIDinList].vData.push_back( (*it) );
+					}
+
+					// Subtest leaks.
+					vector<string> vSubLeaks;
+					vector<string>::iterator viSubLeaks;
+					viSubTestIter->GetLeakList( vSubLeaks );
+					for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
+					{
+						sLine.append( LABEL_MEM_LEAK );
+						sLine.append( " " );
+						sLine.append( *viSubLeaks );
+						vProcessList[iProcessIDinList].vData.push_back( sLine );
+						sLine.clear();
+					}
+					viSubTestIter->ClearAllocs();
+
+					if( !viSubTestIter->sEndTime.empty() )
+					{
+						// Print sub test end
+						sLine.append( LABEL_TEST_END ); sLine.append( " " );
+						sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
+						sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+						sLine.append( viSubTestIter->sSubTestEndHandleCount );
+						vProcessList[iProcessIDinList].vData.push_back( sLine );
+					}
+					viSubTestIter++;
+				}
+
+				// Clear sub tests from list
+				vProcessList[iProcessIDinList].vSubTests.clear();
+				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+			}
+			else if( ! _stricmp( pCommand, LABEL_HANDLE_LEAK ) )
+			{
+				// Make whole line
+				sTemp.append( " " );
+				sTemp.append( sRestOfLine );
+				vProcessList[iProcessIDinList].vHandleLeaks.push_back( sTemp );
+			}
+			else if( ! _stricmp( pCommand, LABEL_DLL_LOAD ) )
+			{
+				// Add module load to process data.
+				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+				// Add module load to subtest data if test running.
+				for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
+					it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
+				{
+					if( it->bRunning )
+						it->vData.push_back( sWholeTempLine );
+				}
+
+			}
+			else if( ! _stricmp( pCommand, LABEL_DLL_UNLOAD ) )
+			{
+				// Add module load to process data.
+				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+				// Add module unload to subtest data if test running.
+				for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
+					it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
+				{
+					if( it->bRunning )
+						it->vData.push_back( sWholeTempLine );
+				}
+			}
+			else if( sTemp.find( LABEL_LOGGING_CANCELLED ) != string::npos ||
+				     sTemp.find( LABEL_PROCESS_END ) != string::npos || sTemp.find( LABEL_ERROR_OCCURED ) != string::npos ||
+					 sTemp.find( LABEL_HANDLE_LEAK ) != string::npos )
+			{
+				vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+			}
+			else if( ! _stricmp( pCommand, LABEL_TEST_START ) )
+			{
+				bRet = true; // Set return value true we found start.
+				// Get sub test time
+				string sSubTestTime = GetStringUntilNextSpace( sRestOfLine );
+				// Get sub test name
+				string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
+				// Get sub test start handle count
+				string sSubTestStartHandleCount = GetStringUntilNextSpace( sRestOfLine );
+
+				CSubTestData SubTestData;
+				SubTestData.bRunning = true;
+				SubTestData.sStartTime = sSubTestTime;
+				SubTestData.sSubTestName = sSubTestName;
+				SubTestData.sSubTestStartHandleCount = sSubTestStartHandleCount.c_str();
+
+				vProcessList[iProcessIDinList].vSubTests.push_back( SubTestData );
+			}
+			else if( ! _stricmp( pCommand, LABEL_TEST_END ) )
+			{
+				// Get sub test time
+				string sSubTestEnd = GetStringUntilNextSpace( sRestOfLine );
+				// Get sub test name
+				string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
+				// Get sub test end handle count
+				string sSubTestEndHandleCount = GetStringUntilNextSpace( sRestOfLine );
+
+				// Find subtest
+				vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+				while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+				{
+					if( viSubTestIter->sSubTestName == sSubTestName && viSubTestIter->sEndTime.empty() )
+					{
+						viSubTestIter->sEndTime = sSubTestEnd;
+						viSubTestIter->bRunning = false;
+						viSubTestIter->sSubTestEndHandleCount = sSubTestEndHandleCount.c_str();
+					}
+					viSubTestIter++;
+				}
+			}
+		}
+	}
+
+	// Print all saved data from processes
+	for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
+	{
+		// Print saved lines
+		for( unsigned int iDataCounter = 0 ; iDataCounter < vProcessList[i].vData.size() ; iDataCounter++ )
+		{
+			m_DataSaver.AddString( vProcessList[i].vData[iDataCounter].c_str() );
+			m_DataSaver.AddLineToLast();
+		}
+
+		string sTemp;
+
+		// Save leaks
+		vector<string> vLeaks;
+		vector<string>::iterator viLeaks;
+		vProcessList[i].GetLeakList( vLeaks );
+		for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
+		{
+			sTemp.clear();
+			sTemp.append( LABEL_MEM_LEAK );
+			sTemp.append( " " );
+			sTemp.append( *viLeaks );
+			m_DataSaver.AddString( sTemp.c_str() );
+			m_DataSaver.AddLineToLast();
+		}
+
+		vector<string>::iterator viHandleIter = vProcessList[i].vHandleLeaks.begin();
+		// Print handle leaks, if there is data left, there was no process end.
+		while( viHandleIter != vProcessList[i].vHandleLeaks.end() )
+		{
+			sTemp.clear();
+			sTemp.append( viHandleIter->c_str() );
+			m_DataSaver.AddString( sTemp.c_str() );
+			m_DataSaver.AddLineToLast();
+			viHandleIter++;
+		}
+		vector<CSubTestData>::iterator viSubTestIter = vProcessList[i].vSubTests.begin();
+		// Print sub test data, if there is data left, there was no process end.
+		while( viSubTestIter != vProcessList[i].vSubTests.end() )
+		{
+			// Print sub test start
+			string sLine( LABEL_TEST_START ); sLine.append( " " );
+			sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
+			sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+			sLine.append( viSubTestIter->sSubTestStartHandleCount );
+			m_DataSaver.AddString( sLine.c_str() );
+			m_DataSaver.AddLineToLast();
+			sLine.clear();
+
+			// DLL Loads.
+			for( vector<string>::iterator it = viSubTestIter->vData.begin();
+				it != viSubTestIter->vData.end(); it++ )
+			{
+				m_DataSaver.AddString( (*it).c_str() );
+				m_DataSaver.AddLineToLast();
+			}
+
+			// Subtest leaks.
+			vector<string> vSubLeaks;
+			vector<string>::iterator viSubLeaks;
+			viSubTestIter->GetLeakList( vSubLeaks );
+			for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
+			{
+				sLine.append( LABEL_MEM_LEAK );
+				sLine.append( " " );
+				sLine.append( *viSubLeaks );
+				m_DataSaver.AddString( sLine.c_str() );
+				m_DataSaver.AddLineToLast();
+				sLine.clear();
+			}
+
+			// Print sub test end
+			sLine.append( LABEL_TEST_END ); sLine.append( " " );
+			sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
+			sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+			sLine.append( viSubTestIter->sSubTestEndHandleCount );
+			m_DataSaver.AddString( sLine.c_str() );
+			m_DataSaver.AddLineToLast();
+
+			viSubTestIter++;
+		}
+	}
+	// Save lines to file.
+	m_DataSaver.SaveLinesToFile( pOutputFileName, TEXT_DATA );
+	// Close file.
+	in.close();
+	return bRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::GetDataSaver
+// Gets data saver object.
+// -----------------------------------------------------------------------------
+CATDataSaver* CATParseTraceFile::GetDataSaver(void)	
+{
+	LOG_LOW_FUNC_ENTRY("CATParseTraceFile::GetDataSaver");
+	return &m_DataSaver;
+}
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATParseXML.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATParseXML.
+*
+*/
+
+
+#include "../inc/CATParseXML.h"
+#include "../inc/catdatasaver.h"
+#include "../inc/CATBase.h"
+
+#include <xercesc/parsers/XercesDOMParser.hpp>
+
+const char cCanNotFindEpocroot[] = "Can not find EPOCROOT from devices.xml.\n";
+const char cErrorInDeviceXml[] = "Error in devices.xml!\n";
+const char cCanNotFind[] = "Can not find file: %s.\n";
+
+CATParseXML::CATParseXML(void)
+{
+	LOG_FUNC_ENTRY("CATParseXML::CATParseXML");
+	try 
+	{
+		xercesc::XMLPlatformUtils::Initialize();
+	}
+	catch ( ... )
+	{
+		//Print error
+		printf("XML initialization failed.\n");
+	}
+}
+
+CATParseXML::~CATParseXML(void)
+{
+	LOG_FUNC_ENTRY("CATParseXML::~CATParseXML");
+}
+
+// -----------------------------------------------------------------------------
+// CATParseXML::GetEpocRootPathFromXML
+// Find epocroot path in xml file
+// -----------------------------------------------------------------------------
+string CATParseXML::GetEpocRootPathFromXML(const char* pSourcePath)
+{
+	LOG_FUNC_ENTRY("CATParseXML::GetEpocRootPathFromXML");
+	string sEpocRootPath;
+	// Check that source exists
+	if ( ! CATBase::FileExists( pSourcePath ) )
+	{
+		LOG_STRING( "Source xml not found." );
+		return sEpocRootPath;
+	}
+	try 
+	{
+		xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser();
+		xercesc::DOMDocument* pDomDoc;
+
+		// Get devices.xml document
+		parser->parse( pSourcePath );
+		pDomDoc = parser->getDocument();
+
+		// Get root element
+		xercesc::DOMElement* pRootElem = pDomDoc->getDocumentElement();
+
+		if( pRootElem )
+		{
+			// Get all "device" elements
+			LPWSTR wTemp = CATDataSaver::CharToWChar( "device" );
+			xercesc::DOMNodeList* pDeviceNodeList = pRootElem->getElementsByTagName( wTemp );
+			if( wTemp )
+				delete[] wTemp;
+
+			// Find default SDK
+
+			bool bEpocRootFound = false;
+			int iLength = pDeviceNodeList->getLength();
+			for( int i = 0 ; i < iLength ; i++ )
+			{
+				xercesc::DOMNode* pDeviceNode = pDeviceNodeList->item(i);
+
+				xercesc::DOMNamedNodeMap* pAttributeList = pDeviceNode->getAttributes();
+
+				// Find attribute "default"
+
+				int iAttribListLength = pAttributeList->getLength();
+				for( int x = 0 ; x < iAttribListLength ; x++ )
+				{
+					xercesc::DOMNode* pAttribNode = pAttributeList->item(x);
+					const LPWSTR pNodeName = (const LPWSTR)pAttribNode->getNodeName();
+
+					if( wcscmp( pNodeName, L"default" ) == 0 )
+					{
+						const LPWSTR pNodeValue = (const LPWSTR)pAttribNode->getNodeValue();
+						
+						// Find node value 'yes'
+						if( wcscmp( pNodeValue, L"yes" ) == 0 )
+						{
+							// Find <epocroot> node
+							xercesc::DOMNode* pChildNode = pDeviceNode->getFirstChild();
+							if( !pChildNode )
+								break;
+							while( !bEpocRootFound )
+							{
+								if( wcscmp( pChildNode->getNodeName() , L"epocroot" ) == 0 )
+								{
+									bEpocRootFound = true;
+
+									// Node value is child text node
+									xercesc::DOMNode* pTempTextNode = pChildNode->getFirstChild();
+									const LPWSTR pPathNodeValue = (const LPWSTR)pTempTextNode->getNodeValue();
+
+									CATDataSaver::WCharToChar( sEpocRootPath, pPathNodeValue );
+
+									break;
+								}
+								pChildNode = pChildNode->getNextSibling();
+								if( !pChildNode )
+									break;
+							}
+						} // If node value yes
+					} // If node name default
+					if( bEpocRootFound )
+						break;
+				} // for x
+				if( bEpocRootFound )
+					break;
+			} // for i
+		}
+		if(parser)
+			delete parser; //lint !e118
+ 		xercesc::XMLPlatformUtils::Terminate();
+	}
+    catch (...)
+	{
+        printf("XML parsing failed.");
+    }
+	return sEpocRootPath;
+}
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATProject.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,2413 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a project.
+*
+*/
+
+
+#include "../inc/CATProject.h"
+#include "../inc/CATModule2.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/CATDatParser.h"
+
+//dbghelp.dll version function.
+extern int showDbgHelpVersionInfo( bool showVersion );
+
+// ----------------------------------------------------------------------------
+// CATProject::CATProject()
+// ----------------------------------------------------------------------------
+CATProject::CATProject()
+{
+	LOG_FUNC_ENTRY("CATProject::CATProject");
+
+	m_bUninstrumented = true;
+	m_bAbldTest = false;
+
+	// Use windows api to acquire current directory info.
+	GetCurrentDirectory( MAX_LINE_LENGTH, m_cCurrentDir );
+
+	m_eBuildSystem = SBS_V1;
+	m_eBuildType = UDEB;
+	m_eLoggingMode = TRACE;
+	m_eMode = NOT_DEFINED;
+	
+	m_iLoggingLevel = 3;
+	
+	m_pAnalyzer = 0;
+
+	m_sBinaryTarget = "";
+	m_sBuildCommand = "";
+	m_sDataFile = "";
+	m_sDataFileOutput = "";
+	m_sDataFileTemp = "";
+	m_sEpocRoot = "\\";
+	m_sMakeFile = "";
+	m_sPlatform = "";
+	m_sS60FileName = "";
+	m_sTargetModule = "";
+	m_sVariant = "";
+
+	m_vRomSymbolFiles.clear();
+	m_vModules.clear();
+	m_vStaticLibraries.clear();
+	m_vTargetModules.clear();
+	m_vUnsupportedModules.clear();
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::~CATProject()
+// ----------------------------------------------------------------------------
+CATProject::~CATProject()
+{
+	LOG_FUNC_ENTRY("CATProject::~CATProject");
+
+	CleanModuleVectors();
+
+	// Delete analyzer
+	if ( m_pAnalyzer )
+		delete m_pAnalyzer;
+
+	// Temporary datafile
+	if ( !m_sDataFileTemp.empty() )
+	{
+		if ( FileExists( m_sDataFileTemp.c_str() ) )
+			FileDelete( m_sDataFileTemp, false );
+	}
+}
+
+bool CATProject::SetArguments( ARGUMENTS& arguments )
+{
+	LOG_FUNC_ENTRY("CATProject::SetArguments");
+	bool bRet = true;
+
+	//Project mode.
+	if( arguments.eHookSwitch == HOOK_INTERNAL )
+	{
+		SetMode( CATProject::COMPILE );
+		SetLoggingMode( CATProject::FILE );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTERNAL )
+	{
+		SetMode( CATProject::COMPILE );
+		SetLoggingMode( CATProject::TRACE );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTERNAL_FAST )
+	{
+		SetMode( CATProject::COMPILE );
+		SetLoggingMode( CATProject::TRACE_FAST );
+	}
+	/* Extension*/
+	else if ( arguments.eHookSwitch == HOOK_EXTENSION_INTERNAL )
+	{
+		SetMode( CATProject::INSTRUMENT );
+		SetLoggingMode( CATProject::FILE );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTENSION_EXTERNAL )
+	{
+		SetMode( CATProject::INSTRUMENT );
+		SetLoggingMode( CATProject::TRACE );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTENSION_EXTERNAL_FAST )
+	{
+		SetMode( CATProject::INSTRUMENT );
+		SetLoggingMode( CATProject::TRACE_FAST );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTENSION_UNINSTRUMENT )
+	{
+		SetMode( CATProject::UNINSTRUMENT );
+	}
+	else if ( arguments.eHookSwitch == HOOK_EXTENSION_FAILED )
+	{
+		SetMode( CATProject::UNINSTRUMENT_FAILED );
+	}
+	//Return if uninstrumenting because no other arguments are set.
+    if ( GetMode() == CATProject::UNINSTRUMENT
+		|| GetMode() == CATProject::UNINSTRUMENT_FAILED )
+	{
+		return bRet;
+	}
+
+	// No build / instrument.
+	if ( arguments.HOOK.bNoBuild )
+		SetMode( CATProject::INSTRUMENT_CONSOLE );
+
+	// Call stack sizes
+	SetAllocCallStackSize( arguments.HOOK.iAllocCallStackSize );
+	SetFreeCallStackSize( arguments.HOOK.iFreeCallStackSize );
+
+	//Build system.
+	if ( arguments.HOOK.iBuildSystem == 1 )
+		SetBuildSystem( CATProject::SBS_V1 );
+	else if ( arguments.HOOK.iBuildSystem == 2 )
+		SetBuildSystem( CATProject::SBS_V2 );
+
+	//Test module build only
+	if ( arguments.HOOK.bAbldTest == true )
+		m_bAbldTest = true;
+
+	//Platform.
+	if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "armv5" ) )
+		SetPlatform( arguments.HOOK.sPlatform );
+	else if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "gcce" ) )
+		SetPlatform( arguments.HOOK.sPlatform );
+	else if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "winscw" ) )
+		SetPlatform( arguments.HOOK.sPlatform );
+	else
+	{
+		LOG_STRING( "Error, no supported platform specified (armv5/gcce/winscw).");
+		bRet = false;
+	}
+
+	//BuildType.
+	if ( !_stricmp( arguments.HOOK.sBuildType.c_str(), "urel" ) )
+		SetBuildType( CATProject::UREL );
+	else if ( !_stricmp( arguments.HOOK.sBuildType.c_str(), "udeb" ) )
+		SetBuildType( CATProject::UDEB );
+	else
+	{
+		LOG_STRING( "Error, no build type specified.");
+		bRet = false;
+	}
+
+	//Internal data file.
+	if ( arguments.HOOK.bDataFileName )
+		SetS60FileName( arguments.HOOK.sDataFileName );
+
+	//Build command.
+	if ( arguments.HOOK.sBuildCmd.empty() && ( 
+		GetMode() == CATProject::COMPILE ||
+		GetMode() == CATProject::INSTRUMENT ||
+		GetMode() == CATProject::INSTRUMENT_CONSOLE
+		))
+	{
+		cout << AT_MSG << "Error, no build command specified." << endl;
+		bRet = false;
+	}
+
+	SetBuildCommand( arguments.HOOK.sBuildCmd );
+
+	//Variant.
+	SetVariant( arguments.HOOK.sFeatureVariant );
+
+	//Target programs.
+	SetTargetModules( arguments.HOOK.vTargetPrograms );
+
+	return bRet;
+}
+
+void CATProject::CleanModuleVectors()
+{
+	LOG_FUNC_ENTRY("CATProject::CleanModuleVectors");
+	// delete modules from vector.
+	for( size_t i = 0; i < m_vModules.size()  ; i++ )
+		delete m_vModules[i];
+	m_vModules.clear();
+	
+	// Delete modules from vector (unsupported).
+	for( size_t i = 0; i < m_vUnsupportedModules.size()  ; i++ )
+		delete m_vUnsupportedModules[i];
+	m_vUnsupportedModules.clear();
+
+	// Delete modules from static library vector.
+	for( size_t i = 0; i < m_vStaticLibraries.size() ; i++ )
+		delete m_vStaticLibraries[i];
+	m_vStaticLibraries.clear();
+}
+// ----------------------------------------------------------------------------
+// CATProject::Run
+// ----------------------------------------------------------------------------
+int CATProject::Run()
+{
+	LOG_FUNC_ENTRY("CATProject::Run");
+	int iReturnCode = 0;
+	switch( m_eMode )
+	{
+	case COMPILE:
+		// Run compile
+		iReturnCode = RunCompile();
+		if ( iReturnCode == AT_RETURN_CODE::READ_MAKEFILE_ERROR
+			|| iReturnCode == AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR
+			|| iReturnCode == AT_RETURN_CODE::INVALID_MMP_DEFINED )
+		{
+			DeleteTemporaryDirs();
+			DirDelete( AT_TEMP_DIR, true );
+		}
+		else
+		{
+			DisplayCompileSummary();
+			DisplayBuildSummary();
+		}
+		break;
+	case CLEAN:
+		iReturnCode = RunClean();
+		break;
+	case ANALYZE:
+		iReturnCode = RunAnalyze();
+		break;
+	case INSTRUMENT:
+		iReturnCode = RunInstrument();
+		break;
+	case INSTRUMENT_CONSOLE:
+		iReturnCode = RunInstrumentConsole();
+		if ( iReturnCode == AT_RETURN_CODE::READ_MAKEFILE_ERROR
+			|| iReturnCode == AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR )
+		{
+			DeleteTemporaryDirs();
+			DirDelete( AT_TEMP_DIR, true );
+		}
+		else
+		{
+			DisplayBuildSummary();
+		}
+		break;
+	case UNINSTRUMENT:
+		iReturnCode = RunUninstrument();
+		// Show summary
+		DisplayCompileSummary();
+		DisplayBuildSummary();
+		break;
+	case UNINSTRUMENT_CONSOLE:
+		iReturnCode = RunUninstrumentConsole();
+		// Show summary
+		DisplayCompileSummary();
+		DisplayBuildSummary();
+		break;
+	case UNINSTRUMENT_FAILED:
+		iReturnCode = RunUninstrumentFailed();
+		// Display message
+		cout << AT_MSG << "Build aborted, because project contains compile error(s)."
+			<< endl;
+		break;
+	default:
+		cout << AT_MSG << "Error, mode not supported / implemented." << endl;
+		break;
+	}
+	// Error messages
+	switch( iReturnCode )
+	{
+		case AT_RETURN_CODE::MAKEFILE_ERROR:
+			cout << AT_MSG << "Error, creating/reading makefiles." << endl;
+			break;
+		case AT_RETURN_CODE::COMPILE_ERROR:
+			cout << AT_MSG << "Error, compiling project." << endl;
+			break;
+		case AT_RETURN_CODE::UNKNOWN:
+			cout << AT_MSG << "Error, unknown." << endl;
+			break;
+		case AT_RETURN_CODE::WRONG_DATA_FILE_VERSION:
+			cout << AT_MSG << "unable to analyze the data file.\n";
+			cout << AT_MSG << "wrong data file version.\n";
+			break;
+		case AT_RETURN_CODE::INVALID_DATA_FILE:
+			cout << AT_MSG << "Error, invalid datafile." << endl;
+			break;
+		case AT_RETURN_CODE::RELEASABLES_ERROR:
+			cout << AT_MSG << "Error, copying releasable(s)." << endl;
+			break;
+		case AT_RETURN_CODE::RESTORE_MODULES_ERROR:
+			cout << AT_MSG << "Error, restoring mmp file(s)." << endl;
+			break;
+		case AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR:
+			cout << AT_MSG << "Error, creating temporary cpp file(s)." << endl;
+			break;
+		case AT_RETURN_CODE::CLEANING_TEMP_ERROR:
+			cout << AT_MSG << "Error, cleaning temporary dir(s)." << endl;
+			break;
+		case AT_RETURN_CODE::READ_MAKEFILE_ERROR:
+			cout << AT_MSG << "Error, reading makefile." << endl;
+			break;
+		case AT_RETURN_CODE::MODIFY_MODULES_ERROR:
+			cout << AT_MSG << "Error, modifying mmp file(s)." << endl;
+			break;
+		case AT_RETURN_CODE::INVALID_MMP_DEFINED:
+			break;
+		case AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR:
+			cout << AT_MSG << "Error, writing attributes." << endl;
+			break;
+		case AT_RETURN_CODE::READ_ATTRIBUTES_ERROR:
+			cout << AT_MSG << "Error, reading project configuration. Instrument project again." << endl;
+			break;
+		case AT_RETURN_CODE::EMPTY_DATA_FILE:
+			cout << AT_MSG << "Error, no data to be analyzed." << endl;
+			break;
+		case AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR:
+			cout << AT_MSG << "Error, no modules found with supported target type." << endl;
+			break;
+		case AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR:
+			cout << AT_MSG << "Error, kernel side component found component. Build/instrument aborted." << endl;
+			break;
+	}	
+	return iReturnCode;
+}
+// ----------------------------------------------------------------------------
+// CATProject::RunRecoveryAndExit()
+// Restore modules quick and exit. Used when user wants to kill/end process.
+// ----------------------------------------------------------------------------
+int CATProject::RunRecoveryAndExit()
+{
+	LOG_FUNC_ENTRY("CATProject::RunRecoveryAndExit");
+	cout << AT_MSG << "Error, user requested exit." << endl;
+	VerifyAndRecoverModules();
+	DeleteTemporaryDirs();
+	DirDelete( AT_TEMP_DIR, true );
+	cout << AT_MSG << "Exit." << endl;
+	return AT_RETURN_CODE::USER_ISSUED_EXIT;
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::IsUninstrumented()
+// Reads projects configuration file if it exists. 
+// Return false in case the data contains information that project is
+// uninstrumented. Otherwise returns always true.
+// ----------------------------------------------------------------------------
+bool CATProject::IsUninstrumented()
+{
+	LOG_FUNC_ENTRY("CATProject::IsUninstrumented");
+	string sCfgFile( AT_TEMP_DIR );
+	sCfgFile.append( "\\" );
+	sCfgFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+	if ( ! FileExists( sCfgFile.c_str() ) )
+		return true;
+	if( !ReadAttributes() )
+	{
+		LOG_STRING( "Error, reading project.cfg file." );
+		return false;
+	}
+	return m_bUninstrumented;
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::RunCompile()
+// Helper functions to run different modes.
+// ----------------------------------------------------------------------------
+int CATProject::RunCompile()
+{
+	LOG_FUNC_ENTRY("CATProject::RunCompile");
+	// Store attributes
+	if( ! MakeTempDirIfNotExist() )
+		return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	if ( ! WriteAttributes() )
+		return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	// Create makefile
+	if ( ! CreateMakeFile() )
+		return AT_RETURN_CODE::MAKEFILE_ERROR;
+	// Read makefile to get project attributes
+	if ( ! ReadMakeFile() )
+		return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+	// Filter unsupported
+	FilterModules();
+	// Check that we have some "valid" modules to hook
+	if ( m_vModules.size() == 0 &&(  m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+		return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+	// Check is possible target module defined in project
+	if ( ! IsTargetModuleInProject() )
+		return AT_RETURN_CODE::INVALID_MMP_DEFINED;
+	// Clean temporary dirs of modules
+	if ( ! CleanTemporaryDirs() )
+		return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+	// Create temporary cpps for modulse
+	if (! CreateTemporaryCpps() )
+		return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+	// Hook modules
+	if (! ModifyModules() )
+		return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+	// Compile all
+	// Return code
+	int iRetCode = AT_RETURN_CODE::OK;
+	// Compile
+	if ( ! Compile() )
+		iRetCode = AT_RETURN_CODE::COMPILE_ERROR;
+	// Listings
+	if (! CreateListings() )
+		iRetCode = AT_RETURN_CODE::COMPILE_ERROR;
+	// Releasables
+	if (! CopyReleasables() )
+		iRetCode = AT_RETURN_CODE::RELEASABLES_ERROR;
+	// Restore "unhook" modules
+	if (! RestoreModules() )
+		iRetCode = AT_RETURN_CODE::RESTORE_MODULES_ERROR;
+	// Return error code OK
+	return iRetCode;
+}
+
+int CATProject::RunClean()
+{
+	LOG_FUNC_ENTRY("CATProject::RunClean");
+	int iRetCode = AT_RETURN_CODE::OK;
+	bool bNothingFound = true;
+	// Read attributes.
+	if (  ReadAttributes() )
+	{
+		bNothingFound = false;
+		if ( m_eBuildSystem == SBS_V1 )
+			InitSbs1MakeFileWithPathToTemp();
+		// Read makefile to get project attributes
+		if( ReadMakeFile() )
+		{
+			// Filter unsupported
+			FilterModules();
+			// Restore modules to make sure no changes left
+			if( VerifyAndRecoverModules() )
+			{
+				// Run reallyclean
+				switch ( m_eBuildSystem )
+				{
+				case SBS_V1:
+					RunReallyCleanSbs1();
+					break;
+				case SBS_V2:
+					RunReallyCleanSbs2();
+					break;
+				default:
+					break;
+				}
+				// Delete temporary dirs of modules
+				if(! DeleteTemporaryDirs() )
+				{
+					
+				}
+			}
+			else
+			{
+				
+			}
+		}
+	}
+	// Projects
+	if ( ! DirDelete( AT_TEMP_DIR, true ) )
+	{
+
+	}
+	else
+		bNothingFound = false;
+
+	if ( bNothingFound )
+		cout << AT_MSG << "Nothing found to clean." << endl;
+	else
+		cout << AT_MSG << "Cleaning done." << endl;
+	return iRetCode;
+}
+
+int CATProject::RunAnalyze()
+{
+	LOG_FUNC_ENTRY("CATProject::RunAnalyze");
+
+	// Parse data file if it is trace.
+	if ( !IsDataFile( m_sDataFile ) )
+	{
+		m_sDataFileTemp.clear();
+		m_sDataFileTemp.append( m_sDataFile );
+		m_sDataFileTemp.append( ".atool" );
+		cout << AT_MSG << "Parsing trace file..." << endl;
+		CATParseTraceFile Parser;
+		if ( ! Parser.StartParse( m_sDataFile.c_str(), m_sDataFileTemp.c_str() ) )
+		{
+			return AT_RETURN_CODE::EMPTY_DATA_FILE;
+		}
+		m_sDataFile = m_sDataFileTemp;
+	}
+
+	// Init makefile member for this run mode.
+	if ( m_eBuildSystem == SBS_V1 )
+		InitSbs1MakeFileWithPathToTemp();
+	// Read makefile to get project attributes
+    if( ! ReadMakeFile() )
+	{
+		cout << AT_MSG << "Error, cannot find project build with AnalyzeTool." << endl;
+	}
+	else
+		FilterModules();
+
+	#ifndef ADDR2LINE
+	// Initialize modules locating code lines.
+	for( size_t i = 0 ; i < m_vModules.size() ; i++ )
+	{
+		m_vModules.at(i)->InitializeAddressToLine();
+	}
+	#endif
+
+	// Create analyzer
+	m_pAnalyzer = new CATDatParser( &m_vModules );
+
+	// Pass some info from project if it "exists" to analyzer.
+	if ( m_vModules.size() > 0 )
+	{
+		// Pass platform.
+		m_pAnalyzer->SetProjectPlatform( m_sPlatform );
+		// Pass build type.
+		m_pAnalyzer->SetProjectBuildType( m_eBuildType );
+	}
+	
+	// Set file.
+	m_pAnalyzer->SetInputFile( m_sDataFile );
+
+	// Set rom symbol file.
+	m_pAnalyzer->SetRomSymbolFiles( m_vRomSymbolFiles );
+
+	// Set output file if specified
+	if ( ! m_sDataFileOutput.empty() )
+	{
+		m_pAnalyzer->SetOutputFile( m_sDataFileOutput );
+	}
+	// Set log level
+	m_pAnalyzer->SetLogLevel( m_iLoggingLevel );
+
+	// Analyze
+	return m_pAnalyzer->Analyze();
+}
+
+int CATProject::RunInstrument()
+{
+	LOG_FUNC_ENTRY("CATProject::RunInstrument");
+	// Store attributes
+	if( ! MakeTempDirIfNotExist() )
+		return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	if ( ! WriteAttributes() )
+		return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	if ( m_eBuildSystem == SBS_V1 )
+	{
+		// Initialize level 1 make file member.
+		if ( ! InitSbs1MakeFileWithPath() )
+			return AT_RETURN_CODE::MAKEFILE_ERROR;
+		// Copy it to temporary folder.
+		CopyMakeFileSbs1ToTemporaryFolder();
+		// Run export.
+		if( ! RunExportSbs1() )
+			return AT_RETURN_CODE::MAKEFILE_ERROR;
+		// Create level 2 makefiles.
+		if ( ! CreateMakeFileSbs1Level2() )
+			return AT_RETURN_CODE::MAKEFILE_ERROR;
+	}
+	else if ( m_eBuildSystem == SBS_V2 )
+	{
+		// Create makefile only when using SBS v.2
+		if ( ! CreateMakeFile() )
+			return AT_RETURN_CODE::MAKEFILE_ERROR;
+	}
+	else
+	{
+		return AT_RETURN_CODE::UNKNOWN;
+	}
+	// Read makefile to get project attributes
+	if ( ! ReadMakeFile() )
+		return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+	// Filter unsupported
+	FilterModules();
+	// Check that we have some "valid" modules to hook
+	if ( m_vModules.size() == 0 &&(  m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+		return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+
+	// Clean temporary dirs of modules
+	if ( ! CleanTemporaryDirs() )
+		return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+	// Create temporary cpps for modulse
+	if (! CreateTemporaryCpps() )
+		return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+	// Hook modules
+	if (! ModifyModules() )
+		return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+	return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunInstrumentConsole()
+{
+	LOG_FUNC_ENTRY("CATProject::RunInstrumentConsole");
+	if( ! MakeTempDirIfNotExist() )
+		return AT_RETURN_CODE::UNKNOWN;
+	// Store attributes
+	m_bUninstrumented = false;
+	if ( ! WriteAttributes() )
+		return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	// Create makefile
+	if ( ! CreateMakeFile() )
+		return AT_RETURN_CODE::MAKEFILE_ERROR;
+	// Read makefile to get project attributes
+	if ( ! ReadMakeFile() )
+		return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+	// Filter unsupported
+	FilterModules();
+	// Check that we have some "valid" modules to hook
+	if ( m_vModules.size() == 0 &&(  m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+		return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+
+	// Clean temporary dirs of modules
+	if ( ! CleanTemporaryDirs() )
+		return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+	// Create temporary cpps for modulse
+	if (! CreateTemporaryCpps() )
+		return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+	// Hook modules
+	if (! ModifyModules() )
+		return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+	// Run Reallyclean when using abld.
+	if ( m_eBuildSystem == SBS_V1 )
+		RunReallyCleanSbs1();
+	return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunUninstrument()
+{
+	LOG_FUNC_ENTRY("CATProject::RunUninstrument");
+	// Read attributes.
+	if ( ! ReadAttributes() )
+		return AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+	// Init makefile member for this run mode.
+	if ( m_eBuildSystem == SBS_V1 )
+		InitSbs1MakeFileWithPathToTemp();
+	// Read makefile to get project attributes
+	if ( ! ReadMakeFile() )
+		return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+	// Filter unsupported
+	FilterModules();
+	// Check that we have some "valid" modules to hook
+	if ( m_vModules.size() == 0 &&(  m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+		return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+	// Create lst files
+    if (! CreateListings() )
+		return AT_RETURN_CODE::COMPILE_ERROR;
+	// Copy releasables of modules
+	if (! CopyReleasables() )
+		return AT_RETURN_CODE::RELEASABLES_ERROR;
+	// Restore "unhook" modules
+	if (! RestoreModules() )
+		return AT_RETURN_CODE::RESTORE_MODULES_ERROR;
+	// Return error code OK
+	return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunUninstrumentConsole()
+{
+	LOG_FUNC_ENTRY("CATProject::RunUninstrumentConsole");
+	int iErrorCode = AT_RETURN_CODE::OK;
+	// Read attributes
+	if ( ReadAttributes() )
+	{
+		// Init makefile member for this run mode.
+		if ( m_eBuildSystem == SBS_V1 )
+			InitSbs1MakeFileWithPathToTemp();
+		// Read makefile to get project attributes
+		if( ReadMakeFile() )
+		{
+			// Filter unsupported
+			FilterModules();
+			// Create lst files
+			CreateListings();
+			if (! CopyReleasables() )
+				iErrorCode = AT_RETURN_CODE::RELEASABLES_ERROR;
+		}
+		else
+			iErrorCode = AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+		// Change state to uninstrumented and write status
+		m_bUninstrumented = true;
+		if ( ! WriteAttributes() )
+			iErrorCode = AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+	}
+	else
+	{
+		iErrorCode = AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+	}
+	return iErrorCode;
+}
+
+int CATProject::RunUninstrumentFailed()
+{
+	LOG_FUNC_ENTRY("CATProject::RunUninstrumentFailed");
+	// Read attributes.
+	if ( ! ReadAttributes() )
+		return AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+	// Init makefile member for this run mode.
+	if ( m_eBuildSystem == SBS_V1 )
+		InitSbs1MakeFileWithPathToTemp();
+	// Read makefile to get project attributes
+	if( ReadMakeFile() )
+	{
+		// Filter modules
+		FilterModules();
+		// Restore modules to make sure no changes left
+		if( RestoreModules() )
+		{
+			// Delete temporary dirs of modules
+			if(! DeleteTemporaryDirs() )
+			{
+
+			}
+
+		}
+		else
+		{
+
+		}
+	}
+	else
+	{
+
+	}
+	// Projects
+	if ( ! DirDelete( AT_TEMP_DIR, true ) )
+	{
+
+	}
+	return AT_RETURN_CODE::OK;
+}
+
+// ----------------------------------------------------------------------------
+// Main Functions
+// ----------------------------------------------------------------------------
+void CATProject::DisplayCompileSummary()
+{
+	LOG_FUNC_ENTRY("CATProject::DisplayCompileSummary");
+	cout << AT_BUILD_SUMMARY_HEADER;
+	// Supported modules
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		// Successful
+		if ( m_vModules.at(i)->GetErrors().empty() )
+		{
+			// Create build complete file for Carbide xtension
+			m_vModules.at(i)->CreateBuildCompleteFile();
+			cout << AT_BUILD_SUMMARY_INSTRUMENTED_BUILD_COMPLETE
+				<< GetPathOrFileName( true, m_vModules.at(i)->GetMmpFile() )
+				<< endl
+				<< AT_BUILD_SUMMARY_TARGET
+				<< m_vModules.at(i)->GetBinaryName()
+				<< endl;
+			// Datafiles
+			// Use module data file name if project's data file not defined.
+			if ( m_eLoggingMode == CATProject::FILE 
+				&& m_vModules.at(i)->GetTargetType().compare("exe") == 0 )
+			{
+				if ( m_sS60FileName.empty() )
+					cout << AT_BUILD_SUMMARY_DATA_FILE_NAME
+						<< m_vModules.at(i)->GetS60FileName()
+						<< endl;
+				else
+					cout << AT_BUILD_SUMMARY_DATA_FILE_NAME
+					<< m_sS60FileName
+					<< endl;
+			}
+		}
+		else
+		{
+			// Failed
+			cout << AT_BUILD_SUMMARY_FAILED
+				<< GetPathOrFileName( true, m_vModules.at(i)->GetMmpFile() )
+				<< endl
+				<< AT_BUILD_SUMMARY_TARGET
+				<< m_vModules.at(i)->GetBinaryName()
+				<< endl;
+			// Print errors.
+			cout << AT_BUILD_SUMMARY_ERRORS
+				<< m_vModules.at(i)->GetErrors()
+				<< endl;
+		}
+	}
+
+	// Static libraries
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if ( m_vStaticLibraries.at(i)->GetErrors().empty() )
+		{
+			cout << AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE
+				<< GetPathOrFileName( true, m_vStaticLibraries.at(i)->GetMmpFile())
+				<< endl
+				<< AT_BUILD_SUMMARY_TARGET
+				<< m_vStaticLibraries.at(i)->GetBinaryName()
+				<< endl
+				<< AT_BUILD_SUMMARY_STATIC_LIBRARY
+				<< endl;
+				
+		}
+		else
+		{
+			// Failed
+			cout << AT_BUILD_SUMMARY_FAILED
+				<< GetPathOrFileName( true, m_vStaticLibraries.at(i)->GetMmpFile() )
+				<< endl
+				<< AT_BUILD_SUMMARY_TARGET
+				<< m_vStaticLibraries.at(i)->GetBinaryName()
+				<< endl;
+			// Print errors.
+			cout << AT_BUILD_SUMMARY_ERRORS
+				<< m_vStaticLibraries.at(i)->GetErrors()
+				<< endl;
+		}
+	}
+
+	// Unsupported modules
+	for( size_t i = 0; i < m_vUnsupportedModules.size(); i++ )
+	{
+		cout << AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE
+			<< GetPathOrFileName( true, m_vUnsupportedModules.at(i)->GetMmpFile() )
+			<< endl
+			<< AT_BUILD_SUMMARY_TARGET
+			<< m_vUnsupportedModules.at(i)->GetBinaryName()
+			<< endl;
+		cout << m_vUnsupportedModules.at(i)->GetCompileInfoText() << endl;
+	}
+}
+
+void CATProject::DisplayBuildSummary( void )
+{
+	LOG_FUNC_ENTRY("CATProject::DisplayBuildSummary");
+	cout << endl;
+	// Build information
+	cout << AT_BUILD_SUMMARY_BUILD_TYPE << GetBuildTypeString() << endl;
+	// Platform
+	cout << AT_BUILD_SUMMARY_BUILD_PLATFORM << m_sPlatform << endl;
+	// Possible variant
+	if ( ! m_sVariant.empty() )
+		cout << AT_BUILD_SUMMARY_BUILD_VARIANT << m_sVariant << endl;
+	// Logging mode
+	cout << AT_BUILD_SUMMARY_LOGGING_MODE;
+	if ( m_eLoggingMode == FILE )
+		cout  << AT_BUILD_SUMMARY_FILE;
+	else if ( m_eLoggingMode == TRACE )
+		cout << AT_BUILD_SUMMARY_TRACE;
+	else if ( m_eLoggingMode == TRACE_FAST )
+		cout << AT_BUILD_SUMMARY_TRACE_FAST;
+	cout << endl;
+	// Call stack sizes
+	cout << AT_BUILD_SUMMARY_ALLOC_CALL_STACK_SIZE
+		<< m_iAllocCallStackSize
+		<< endl;
+	cout << AT_BUILD_SUMMARY_FREE_CALL_STACK_SIZE
+		<< m_iFreeCallStackSize
+		<< endl;
+
+	if(!_stricmp(m_sPlatform.c_str(), ("winscw")))
+	{
+		//print version info only when version is not up-to-date
+		cout << endl;
+		showDbgHelpVersionInfo( false );
+	}
+}
+
+bool CATProject::CreateMakeFile()
+{
+	switch ( m_eBuildSystem )
+	{
+	case SBS_V1:
+		if( ! CreateMakeFileSbs1() )
+			return false;
+		// Copy main make file.
+		if( ! CopyMakeFileSbs1ToTemporaryFolder() )
+			return false;
+		// Run export.
+		if( ! RunExportSbs1() )
+			return false;
+		// Create level 2 makefiles.
+		if( ! CreateMakeFileSbs1Level2() )
+			return false;
+		return true;
+	case SBS_V2:
+		return CreateMakeFileSbs2();
+	default:
+		return false;
+	}
+}
+
+bool CATProject::CreateMakeFileSbs1()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs1");
+
+	// If variant defined check does it exist.
+	if( ! m_sVariant.empty() )
+	{
+		if ( ! CheckVariant( m_sEpocRoot, m_sVariant ) )
+		{
+			cout << INVALID_VARIANT_ERROR;
+			if ( IsDefaultVariant( m_sEpocRoot ) )
+			{
+				m_sVariant = "default";
+				cout << USING_DEFAULT_VARIANT_MESSAGE;
+				if ( ! WriteAttributes() )
+					return false;
+			}
+			else
+			{
+				cout << NO_DEFAULT_VARIANT_ERROR;
+				return false;
+			}
+		}
+	}
+
+	// Create level 1 make file.
+	string sCmd( "bldmake bldfiles " );
+	sCmd.append( m_sPlatform );
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	(void)system( sCmd.c_str() );
+	return InitSbs1MakeFileWithPath();
+}
+
+bool CATProject::CopyMakeFileSbs1ToTemporaryFolder()
+{
+	LOG_FUNC_ENTRY("CATProject::CopyMakeFileSbs1ToTemporaryFolder");
+	// Check that temporary dir exists if not create it.
+	if ( ! MakeTempDirIfNotExist() )
+		return false;
+	// Copy makefile to temporary directory
+	string sMakeFileInTemp( AT_TEMP_DIR );
+	sMakeFileInTemp.append( "\\" );
+	sMakeFileInTemp.append( AT_LEVEL_1_MAKEFILE_NAME );
+	if ( ! FileCopyToPath( m_sMakeFile, sMakeFileInTemp ) )
+		return false;
+	return true;
+
+}
+
+bool CATProject::RunReallyCleanSbs1()
+{
+	LOG_FUNC_ENTRY("CATProject::RunReallyCleanSbs1");
+	// Check that abld.bat has been made.
+	if ( ! FileExists( "abld.bat" ) )
+		return false;
+	// Run reallyclean.
+	string sCmd;
+	if ( m_bAbldTest )
+		sCmd = "abld test reallyclean ";
+	else
+		sCmd = "abld reallyclean ";
+	sCmd.append( m_sPlatform );
+	if ( ! m_sVariant.empty() )
+	{
+		sCmd.append( "." );
+		sCmd.append( m_sVariant );
+	}
+	sCmd.append( " " );
+	sCmd.append( GetBuildTypeString() );
+	if ( m_vTargetModules.size() > 1 )
+	{
+		RunAbldCommandToAllTargets( sCmd );
+	}
+	else
+	{
+		AddTargetModuleIfDefined( sCmd );
+		cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+		(void) system( sCmd.c_str() );
+	}
+	return true;
+}
+
+bool CATProject::RunReallyCleanSbs2()
+{
+	LOG_FUNC_ENTRY("CATProject::RunReallyCleanSbs2");
+	string sCmd("");
+	if ( m_sBuildCommand.empty() )
+	{
+		// If no build command defined (not found in project.cfg).
+		sCmd.append( RAPTOR_CMD_BASE );;
+		sCmd.append( m_sPlatform );
+		sCmd.append( "_" );
+		sCmd.append( GetBuildTypeString() );
+		if ( ! m_sVariant.empty() )
+		{
+			sCmd.append( "." );
+			sCmd.append( m_sVariant );
+		}
+		sCmd.append( RAPTOR_REALLYCLEAN_LOG );
+		AddTargetModuleIfDefined( sCmd );
+		sCmd.append( " REALLYCLEAN" );
+	}
+	else
+	{
+		// When build command set use it.
+		sCmd.append( m_sBuildCommand );
+		sCmd.append( RAPTOR_REALLYCLEAN_LOG );
+		sCmd.append( " REALLYCLEAN" );
+	}
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet == 0 )
+		return true;
+	return false;
+}
+
+bool CATProject::RunExportSbs1()
+{
+	LOG_FUNC_ENTRY("CATProject::RunExportSbs1");
+	// Run export.
+	string sCmd;
+	if ( m_bAbldTest )
+		sCmd = "abld test export";
+	else
+		sCmd = "abld export";
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	(void) system( sCmd.c_str() );
+	return true;
+}
+
+bool CATProject::CreateMakeFileSbs1Level2()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs1Level2");
+	// Create level 2 makefiles.
+	
+	string sCmd;
+	
+	if ( m_bAbldTest )
+		sCmd ="abld test makefile ";
+	else
+		sCmd ="abld makefile ";
+
+	sCmd.append( m_sPlatform );
+	if ( ! m_sVariant.empty() )
+	{
+		sCmd.append( "." );
+		sCmd.append( m_sVariant );
+	}
+	
+	// Check if multiple targets defined and sbs 1.
+	if ( m_vTargetModules.size() > 1 )
+	{
+		RunAbldCommandToAllTargets( sCmd );
+	}
+	else
+	{
+		AddTargetModuleIfDefined( sCmd );
+		cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+		(void) system( sCmd.c_str() );
+	}
+	return true;
+}
+
+bool CATProject::CreateMakeFileSbs2()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs2");
+	// Delete build directory if it exists before creating new makefiles.
+	if ( DirectoryExists( "atool_temp\\build" ) )
+		DirDelete( "atool_temp\\build", true );
+	// Create command to create makefiles.
+	string sCmd( m_sBuildCommand );
+	sCmd.append( " " );
+	sCmd.append( RAPTOR_MAKEFILE_SWITCH );
+	sCmd.append( " " );
+	sCmd.append( RAPTOR_NOBUILD_SWITCH );
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet == 0 )
+		return true;
+	return false;
+}
+
+bool CATProject::ReadMakeFile()
+{
+	// Clean modules before reading.
+	CleanModuleVectors();
+	if ( m_eBuildSystem == SBS_V1 )
+	{
+		// Read level 1 makefile which contains module name and makefiles.
+		if( ! ReadMakeFileSbs1Level1() )
+			return false;
+		// Read level 2 makefiles.
+		vector<CATModule2*>::iterator it;
+		// If we are compiling or etc... we need to create temporary directories.
+		if ( m_eMode == COMPILE || m_eMode == INSTRUMENT || m_eMode == INSTRUMENT_CONSOLE )
+		{
+			// Read make makefiles from /epoc32/build... and create temporary directory.
+			bool bLevel2 = true;
+			for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+			{
+				if( ! (*it)->CreateTemporaryDirectory() )
+					return false;
+				if( ! (*it)->ReadMakeFile() )
+				{
+					bLevel2 = false;
+					break;
+				}
+			}
+			// If failed reading modules from level 2 makefiles.
+			if ( ! bLevel2 )
+			{
+				// Clean modules.
+				CleanModuleVectors();
+				// Try use default variant if it exists.
+				if ( CheckVariant( m_sEpocRoot, "default" ) )
+				{
+					m_sVariant = "default";
+					cout << USING_DEFAULT_VARIANT_MESSAGE;
+					if ( ! WriteAttributes() )
+						return false;
+					if ( ! InitSbs1MakeFileWithPath() )
+						return false;
+					if ( ! ReadMakeFileSbs1Level1() )
+						return false;
+					for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+					{
+						if( ! (*it)->CreateTemporaryDirectory() )
+							return false;
+						if( ! (*it)->ReadMakeFile() )
+							return false;
+					}
+
+				}
+			}
+		}
+		else
+		{
+			// Read make files from temporary directories.
+			for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+			{
+				if ( ! (*it)->ReadMakeFileFromTemp() )
+					return false;
+			}
+		}
+		return true;
+	}
+	else if ( m_eBuildSystem == SBS_V2 )
+	{
+		// Read make file.
+		if( ! ReadMakeFileSbs2() )
+			return false;
+		// Create module temporary directories if we are compiling or etc...
+		if ( m_eMode == COMPILE || m_eMode == INSTRUMENT || m_eMode == INSTRUMENT_CONSOLE )
+			{
+			for( vector<CATModule2*>::iterator it = m_vModules.begin(); it < m_vModules.end(); it++ )
+				(*it)->CreateTemporaryDirectory();
+			for( vector<CATModule2*>::iterator it = m_vStaticLibraries.begin(); it < m_vStaticLibraries.end(); it++ )
+				(*it)->CreateTemporaryDirectory();
+			}
+	}
+	return true;
+}
+
+bool CATProject::ReadMakeFileSbs1Level1()
+{
+	LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs1Level1");
+
+	bool bRet = false;
+
+	//Try to open makefile
+	ifstream in;
+	in.open( m_sMakeFile.c_str() );
+
+	//File open ok?
+	if( !in.good() )
+	{
+		printf( "Can not open file: %s\n", m_sMakeFile.c_str() );
+		in.close();
+		return bRet;
+	}
+
+	// Add also these so "compatible with sbs2".
+	// Releasables path (binaries).
+	string sReleasePath( m_sEpocRoot );
+	// add trailing '\' if root path is missing it
+	if ( sReleasePath.size() < 1 )
+		sReleasePath.append( "\\" );
+	else if ( sReleasePath.at( sReleasePath.length() -1 ) != '\\' )
+		sReleasePath.append( "\\" );
+	sReleasePath.append( "epoc32\\release" );
+	string sFullVariantPath( m_sPlatform );
+	sFullVariantPath.append( "\\" );
+	sFullVariantPath.append( GetBuildTypeString() );
+
+	char cTemp[MAX_LINE_LENGTH];
+	bool bContinueSearch = true;
+	bool bMmpInfoFound = false;
+	CATModule2* pModule = 0;
+	string sTempLineFromFile;
+	string sMmpFileSearchString;
+	if ( m_bAbldTest )
+		sMmpFileSearchString = MMPTESTFILE_SEARCH_STRING;
+	else
+		sMmpFileSearchString = MMPFILE_SEARCH_STRING;
+	do
+	{
+		// get line from file
+		in.getline( cTemp, MAX_LINE_LENGTH );
+		sTempLineFromFile.clear();
+		sTempLineFromFile.append( cTemp );
+
+		//Search makefile string
+		if( sTempLineFromFile.find( MAKEFILE_SEARCH_STRING ) != string::npos )
+		{
+			bMmpInfoFound = true;
+			if( sTempLineFromFile.find( sMmpFileSearchString ) != string::npos )
+			{
+				bRet = true;
+				//Parse mmp path + mmp filename
+				sTempLineFromFile.erase( 0, sTempLineFromFile.find_first_of("\"") );
+				sTempLineFromFile.erase( 0, 1 );
+
+				string sPath = sTempLineFromFile.substr(0, sTempLineFromFile.find_first_of("\"") );
+
+				sPath = ChangeSlashToBackSlash( sPath );
+				//Remove text "bld.inf"
+				sPath.erase( (sPath.find_last_of( "\\" ) + 1) , string::npos );
+
+				string sFileName = sTempLineFromFile.substr( (sTempLineFromFile.find( sMmpFileSearchString ) + sMmpFileSearchString.length() + 3), string::npos );
+				sFileName = ChangeSlashToBackSlash( sFileName );
+				sFileName = sFileName.substr( 0, sFileName.find_first_of("\"") );
+
+				// Append .mmp to filename if it does not exist
+				if ( sFileName.find(".mmp") == string::npos )
+					sFileName.append(".mmp");
+
+				//Insert drive letter
+				sPath.insert(0, string( m_cCurrentDir).substr(0,2) );
+		
+				//Insert mmp file to the end
+				sPath.append( sFileName );
+
+				ChangeToLower( sPath );
+				
+				// If target programs defined find from those or do not
+				// add module to vector.
+				bool bAddToVector = true;
+				if ( m_vTargetModules.size() > 0 )
+				{
+					bAddToVector = false;
+					vector<string>::iterator it;
+					for( it = m_vTargetModules.begin() ; it != m_vTargetModules.end() ; it++ )
+					{
+						string sFind( *it );
+						sFind.insert( 0, "\\" );
+						if ( sPath.find( sFind ) != string::npos )
+						{
+							bAddToVector = true;
+							break;
+						}
+					}	
+				}
+
+				if ( bAddToVector )
+				{
+					pModule = new CATModule2();
+					pModule->SetMmpFile( sPath );
+					pModule->SetVariantType( GetBuildTypeString() );
+					pModule->SetVariantPlatform( m_sPlatform );
+					pModule->SetReleasePath( sReleasePath );
+					pModule->SetFullVariantPath( sFullVariantPath );
+					pModule->SetBuildSystem( SBS_V1 );
+					m_vModules.push_back( pModule );
+				}
+			}
+		}
+		else if( bMmpInfoFound )
+			//Do not continue search if mmp info lines are all handled
+			bContinueSearch = false;
+		if( !in.good() )
+			bContinueSearch = false;
+	}
+	while( bContinueSearch );
+
+	bContinueSearch = true;
+
+	//Search MAKEFILES for invidual modules
+	do
+	{
+		in.getline( cTemp, MAX_LINE_LENGTH );
+		sTempLineFromFile.clear();
+		sTempLineFromFile.append( cTemp );
+		// find the lines 'MAKEFILE[modulename]_FILES'
+		if( (sTempLineFromFile.find( "MAKEFILE" ) == 0) && (sTempLineFromFile.find( "_FILES" ) != string::npos) )
+		{
+			//Math the makefile line with one of our modules
+			for( size_t i = 0 ; i < m_vModules.size() ; i++ )
+			{
+				//Create name
+				string sMakeFile( "MAKEFILE" );
+				string sTempMmpFile( RemovePathAndExt( m_vModules.at(i)->GetMmpFile(), true ) );
+				ChangeToUpper( sTempMmpFile );
+				sMakeFile.append( sTempMmpFile );
+				sMakeFile.append( "_FILES" );
+				// matched
+				if( sTempLineFromFile.find( sMakeFile ) != string::npos )
+				{
+					//parse the makefile name from line
+					in.getline( cTemp, MAX_LINE_LENGTH );
+					sTempLineFromFile.clear();
+					sTempLineFromFile.append( cTemp );
+					//Remove character "\""
+					sTempLineFromFile.erase( 0, ( sTempLineFromFile.find_first_of("\"") + 1 ) );
+					// in winscw last part is '" \' and on armd '"' so remove all after last '"'
+					sTempLineFromFile.erase( sTempLineFromFile.find_last_of("\""), sTempLineFromFile.size() );
+					// Set correct makefile for module
+					m_vModules.at( i )->SetMakeFile( sTempLineFromFile );
+					// break 
+					break;
+				} // If mathed to mmp
+			} // End of mmp file loop
+		} // found lines 'MAKEFILE[modulename]_FILES'
+		if( !in.good() )
+			bContinueSearch = false;
+	}
+	while( bContinueSearch );
+	in.close();
+	return bRet;
+}
+
+bool CATProject::ReadMakeFileSbs2( void )
+{
+	LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs2(void)");
+	// File is by default named make_build.default but when building specific layer
+	// make_build_LAYERNAME.default is produced by Raptor.
+	// So find makefile(s) and read them.
+	vector<string> vMakeFiles = DirList( "atool_temp\\build\\", false, true );
+	bool bRet = true;
+	for( vector<string>::iterator it = vMakeFiles.begin(); it != vMakeFiles.end() ; it++ )
+	{
+		// Recognize multiple makefiles.
+		if ( it->find("make_build_") != string::npos && it->find(".default") != string::npos )
+		{
+			if ( ! ReadMakeFileSbs2( *it ) )
+				bRet = false;
+		}
+		// Single makefile.
+		else if ( it->find( "make_build.default" ) != string::npos )
+		{
+			if ( ! ReadMakeFileSbs2( *it ) )
+				bRet = false;
+		}
+	}
+	// We got some modules?
+	if ( m_vModules.size() == 0 )
+		bRet = false;
+	return bRet;
+}
+
+bool CATProject::ReadMakeFileSbs2( string& sMakeFile )
+{
+	LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs2(string)");
+	try {
+		// Open file
+		ifstream in;
+		in.open( sMakeFile.c_str() , ios_base::in );
+		// Check that open ok
+		if ( ! in.good() )
+		{
+			cout << AT_MSG << "Error, opening file "
+				<< RAPTOR_MAKEFILE << endl;
+			in.close();
+			return false;
+		}
+		// Source line from file
+		string sSourceLine;
+		// Module pointer
+		CATModule2* pModule = 0;
+		// Are we looking for module attributes
+		bool bFindAttributes = false;
+		// Until end of file
+		while( in.good() )
+		{
+			// Get new line from file
+			string sLine;
+			getline(in, sLine);
+			// New module
+			if ( sLine.find( RAPTOR_PROJECT_META ) == 0 )
+			{
+				// Remove project_meta from line
+				sLine.erase(0, strlen( RAPTOR_PROJECT_META ) );
+				LOG_STRING("Found module: " << sLine );
+				// Check is name empty
+				// This seems to happen when sbs2 "wraps" i.e. mifconv to a module type item
+				if ( sLine.empty() )
+				{
+					LOG_STRING("skipping empty module");
+					// Skip it
+					continue;
+				}
+				// If module add it to vector
+				if ( pModule )
+				{
+					// Add sources,
+					pModule->AddSources( sSourceLine );
+					// Build system.
+					pModule->SetBuildSystem( SBS_V1 );
+					// Push to vector.
+					m_vModules.push_back( pModule );
+				}
+				// New module
+				pModule = new CATModule2();
+				// Clear sourceline
+				sSourceLine.clear();
+				// Set modules mmp with path
+
+				if ( ! pModule->SetMmpFile( sLine ) )
+				{
+					// Fatal error setting mmp file
+					in.close();
+					return false;
+				}
+				// Find attributes on
+				bFindAttributes = true;
+				// Get new line from file
+				getline(in, sLine);
+			}
+			// If attribute finding on
+			if ( bFindAttributes )
+			{
+				// Pickup modules attributes
+				if ( sLine.find ( RAPTOR_SOURCE ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_SOURCE ) );
+					sSourceLine = sLine;
+				}
+				else if ( sLine.find ( RAPTOR_TARGET ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_TARGET ) );
+					pModule->SetTarget( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_TARGETYPE ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_TARGETYPE ));
+					pModule->SetTargetType( sLine );
+				}
+				else if ( sLine.find( RAPTOR_REQUESTEDTARGETEXT ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_REQUESTEDTARGETEXT ) );
+					pModule->SetRequestedTargetExt( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_VARIANTPLATFORM ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_VARIANTPLATFORM ));
+					pModule->SetVariantPlatform( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_VARIANTTYPE ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_VARIANTTYPE ));
+					pModule->SetVariantType( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_FEATUREVARIANT ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_FEATUREVARIANT ));
+					pModule->SetFeatureVariant( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_FEATUREVARIANTNAME ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_FEATUREVARIANTNAME ));
+					pModule->SetFeatureVariantName( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_RELEASEPATH ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_RELEASEPATH ));
+					pModule->SetReleasePath( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_FULLVARIANTPATH ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_FULLVARIANTPATH ));
+					pModule->SetFullVariantPath( sLine );
+				}
+				else if ( sLine.find ( RAPTOR_COMPILE_DEFINITIONS ) == 0 )
+				{
+					sLine.erase(0, strlen( RAPTOR_COMPILE_DEFINITIONS ) );
+					pModule->SetCompileDefinitions( sLine );
+				}
+			}
+		} // while in.good()
+		// Add last module if n number of modules found
+		if ( pModule )
+		{
+			if ( ! pModule->GetTarget().empty() )
+			{
+				// Add sources
+				pModule->AddSources( sSourceLine );
+				// Build system.
+				pModule->SetBuildSystem( SBS_V1 );
+				// Push back to vector
+				m_vModules.push_back( pModule );
+			}
+		}
+		// Close file
+		in.close();
+		return true;
+	} // try.
+	catch(...)
+	{
+		LOG_STRING("Unexpected exception reading sbs 2 makefile");
+		return false;
+	}
+}
+bool CATProject::CreateTemporaryDirectories()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateTemporaryDirectories");
+	bool bRet = true;
+	for( size_t i = 0 ; i < m_vModules.size(); i++)
+	{
+		if( ! m_vModules.at(i)->CreateTemporaryDirectory() )
+			bRet = false;
+	}
+	for( size_t i = 0 ; i < m_vStaticLibraries.size(); i++)
+	{
+		if( ! m_vStaticLibraries.at(i)->CreateTemporaryDirectory() )
+			bRet = false;
+	}
+	return bRet;
+
+}
+
+bool CATProject::CreateTemporaryCpps()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateTemporaryCpps");
+	bool bRet = true;
+	for( size_t i = 0 ; i < m_vModules.size(); i++)
+	{
+		if( ! m_vModules.at(i)->CreateTempCpp(
+			m_sS60FileName, m_eLoggingMode, m_eBuildType, m_iAllocCallStackSize, m_iFreeCallStackSize ) )
+			bRet = false;
+	}
+	return bRet;
+}
+
+bool CATProject::FilterModules()
+{
+	LOG_FUNC_ENTRY("CATProject::FilterModules");
+	vector<CATModule2*>::iterator it;
+	// Loop thru modules.
+	it = m_vModules.begin();
+	while( it != m_vModules.end() )
+	{
+		// Get target type of module to separate string (will be modified).
+		string sTargetType = (*it)->GetTargetType();
+		// Modules compile definitions.
+		string sCompileDefinition = (*it)->GetCompileDefinitions();
+		// Check is it supported.
+		if ( !IsTargetTypeSupported( sTargetType) )
+		{
+			(*it)->SetCompileInfoText( AT_UNSUPPORTED_TARGET_TYPE );
+			// Not supported add to not supported vector.
+			m_vUnsupportedModules.push_back( *it );
+			// Erase cell.
+			it = m_vModules.erase( it );
+		}
+		// Check if its static library
+		else if ( _stricmp( sTargetType.c_str(), "lib" ) == 0 )
+		{
+			// Static librarie move to their vector.
+			m_vStaticLibraries.push_back( *it );
+			// Erase cell.
+			it = m_vModules.erase( it );
+		
+		}
+		else if ( sCompileDefinition.find( KERNEL_MODE_COMPILE_DEFINITION ) != string::npos )
+		{
+			(*it)->SetCompileInfoText( AT_UNSUPPORTED_COMPILE_DEFINITION );
+			// Not supported add to not supported vector.
+			m_vUnsupportedModules.push_back( *it );
+			// Erase cell.
+			it = m_vModules.erase( it );
+		}
+		else
+			it++;
+	}
+	return true;
+}
+
+bool CATProject::ModifyModules()
+{
+	LOG_FUNC_ENTRY("CATProject::ModifyModules");
+	bool bRet = true;
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		if (! m_vModules.at(i)->ModifyMmp() )
+			bRet = false;
+	}
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if (! m_vStaticLibraries.at(i)->ModifyMmp() )
+			bRet = false;
+	}
+	return bRet;
+}
+
+bool CATProject::RestoreModules()
+{
+	LOG_FUNC_ENTRY("CATProject::RestoreModules");
+	bool bRet = true;
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		if (! m_vModules.at(i)->RestoreMmp() )
+			bRet = false;
+	}
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if (! m_vStaticLibraries.at(i)->RestoreMmp() )
+			bRet = false;
+	}
+	return bRet;
+}
+
+bool CATProject::VerifyAndRecoverModules()
+{
+	LOG_FUNC_ENTRY("CATProject::VerifyAndRecoverModules");
+	bool bRet = true;
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		if (! m_vModules.at(i)->VerifyAndRecoverMmp() )
+			bRet = false;
+	}
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if (! m_vStaticLibraries.at(i)->VerifyAndRecoverMmp() )
+			bRet = false;
+	}
+	return bRet;
+}
+bool CATProject::Compile()
+{
+	switch ( m_eBuildSystem )
+	{
+	case SBS_V1:
+		// Run Reallyclean.
+		if( ! RunReallyCleanSbs1() )
+			return false;
+		return CompileSbs1();
+	case SBS_V2:
+		return CompileSbs2();
+	default:
+		return false;
+	}
+}
+
+bool CATProject::CompileSbs1()
+{
+	LOG_FUNC_ENTRY("CATProject::CompileSbs1");
+	string sCommand("");
+	if ( m_sBuildCommand.empty() )
+	{
+		sCommand = "abld build";
+		// -debug if urel
+		if ( m_eBuildType == UREL )
+			sCommand.append( " -debug" );
+
+		// No variant
+		if ( m_sVariant.empty() )
+		{
+			sCommand.append( " " );
+			sCommand.append( m_sPlatform );
+		}
+		else
+		{
+			// Add variant
+			sCommand.append( " " );
+			sCommand.append( m_sPlatform );
+			sCommand.append( "." );
+			sCommand.append( m_sVariant );
+		}
+
+		// urel vs udeb
+		sCommand.append( " " );
+		sCommand.append( GetBuildTypeString() );
+
+		// Possible target module
+		AddTargetModuleIfDefined( sCommand );
+	}
+	// Check that build command contains -debug switch if sbs v.1 used
+	else if ( ! m_sBuildCommand.empty() 
+		&& m_eBuildType == UREL 
+		&& m_eBuildSystem == SBS_V1 
+		&& m_sBuildCommand.find( "-debug" ) == string::npos )
+	{
+		// Find correct index to insert -debug switch
+		size_t iPos = m_sBuildCommand.find( "build" );
+		if ( iPos != string::npos )
+		{
+			sCommand = m_sBuildCommand;
+			sCommand.insert( iPos+5, " -debug" );
+		}
+		else
+		{
+			LOG_STRING("Overwriting given build command to add -debug switch. Original command is: " << m_sBuildCommand );
+			if ( m_bAbldTest )
+				sCommand = "abld test build -debug ";
+			else
+				sCommand = "abld build -debug ";
+			// No variant
+			if ( m_sVariant.empty() )
+			{
+				sCommand.append( m_sPlatform );
+			}
+			else
+			{
+				// Add variant
+				sCommand.append( m_sPlatform );
+				sCommand.append( "." );
+				sCommand.append( m_sVariant );
+			}
+
+			// urel vs udeb
+			sCommand.append( " " );
+			sCommand.append( GetBuildTypeString() );
+			// Possible target module
+			AddTargetModuleIfDefined( sCommand );
+		}
+	}
+	else
+		sCommand = m_sBuildCommand;
+	// Run command
+	cout << AT_MSG_SYSTEM_CALL << sCommand << endl;
+	(void)system( sCommand.c_str() );
+	return true;
+}
+
+bool CATProject::CompileSbs2()
+{
+	LOG_FUNC_ENTRY("CATProject::CompileSbs2");
+	// Create command to compile with raptor
+	string sCmd( m_sBuildCommand );
+	sCmd.append( RAPTOR_BUILD_LOG );
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet == 0 )
+		return true;
+	return false;
+}
+
+bool CATProject::CreateListings()
+{
+	// Create listings if no addr2line defined
+	#ifndef ADDR2LINE
+	if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 )
+	{
+		switch ( m_eBuildSystem )
+		{
+		case SBS_V1:
+			return CreateListingsSbs1();
+		case SBS_V2:
+			return CreateListingsSbs2();
+		default:
+			return false;
+		}
+	}
+	#endif
+	return true;
+}
+
+bool CATProject::CreateListingsSbs1()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateListingsSbs1");
+	string sCommand;
+	if ( m_bAbldTest )
+		sCommand = "abld test listing ";
+	else
+		sCommand = "abld listing ";
+
+	// Listing
+	if ( m_sVariant.empty() )
+	{
+		// No variant
+		sCommand.append( m_sPlatform );
+	}
+	else
+	{
+		// Use specified variant
+		sCommand.append( m_sPlatform );
+		sCommand.append( "." );
+		sCommand.append( m_sVariant );
+	}
+	// udeb vs urel
+	sCommand.append( " " );
+	sCommand.append( GetBuildTypeString() );
+
+	if ( m_vTargetModules.size() > 1 )
+	{
+		RunAbldCommandToAllTargets( sCommand );
+	}
+	else
+	{
+		AddTargetModuleIfDefined( sCommand ); 
+		cout << AT_MSG_SYSTEM_CALL << sCommand << endl;
+		(void)system( sCommand.c_str() );
+	}
+	return true;
+}
+
+bool CATProject::CreateListingsSbs2()
+{
+	LOG_FUNC_ENTRY("CATProject::CreateListingsSbs2");
+	string sCmd( m_sBuildCommand );
+	sCmd.append( RAPTOR_LISTING_LOG );
+	sCmd.append( " LISTING");
+	cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+	int iRet = (int)system( sCmd.c_str() );
+	if ( iRet == 0 )
+		return true;
+	return false;
+}
+
+bool CATProject::CopyReleasables()
+{
+	bool bRet = true;
+	LOG_FUNC_ENTRY("CATProject::CopyReleasables");
+	// Only copy releasables on armv5 platform and no addr2line defined.
+	#ifndef ADDR2LINE
+	if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 ) 
+	{
+		for( size_t i = 0; i < m_vModules.size(); i++ )
+		{
+			if ( ! m_vModules.at(i)->CopyReleasables() )
+				bRet = false;
+		}
+		// Static libraries lst files.
+		// First create directory for them (delete old one if exists).
+		if ( ! DirectoryExists( AT_TEMP_LST_DIR ) )
+		{
+			DirCreate( AT_TEMP_LST_DIR, true );
+		}
+		else
+		{
+			DirDelete( AT_TEMP_LST_DIR, true );
+			DirCreate( AT_TEMP_LST_DIR, true );
+		}
+		for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+		{
+			if( ! m_vStaticLibraries.at(i)->CopyLstFilesToDir( AT_TEMP_LST_DIR ) )
+				bRet = false;
+		}
+
+		// Delete lst files from all type of modules in project.
+		// Ignoring errors because different modules might use same source/lst files.
+		for( size_t i = 0; i < m_vModules.size(); i++ )
+			m_vModules.at(i)->DeleteLstFilesFromSrc();
+		for ( size_t i = 0 ; i < m_vUnsupportedModules.size(); i ++ )
+			m_vUnsupportedModules.at(i)->DeleteLstFilesFromSrc();
+		for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+			m_vStaticLibraries.at(i)->DeleteLstFilesFromSrc();
+		
+		return bRet;
+	}
+	#endif
+	// When addr2line defined and used we use symbol and map file(s).
+	#ifdef ADDR2LINE
+	if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 )
+	{
+		// Verify that module(s) symbol file(s) exist
+		for( size_t i = 0; i < m_vModules.size(); i++ )
+		{
+			// Check symbol file.
+			if ( ! m_vModules.at(i)->SymbolFileExist() )
+				bRet = false;
+			// Check map  file.
+			if ( ! m_vModules.at(i)->MapFileExist() )
+				bRet = false;
+		}
+	}
+	#endif
+	// Platform winscw.
+	else if ( _stricmp( m_sPlatform.c_str(), "winscw" ) == 0 )
+	{
+		// Verify that module(s) binaries exist
+		for( size_t i = 0; i < m_vModules.size(); i++ )
+		{
+			if ( ! m_vModules.at(i)->BinaryFileExist() )
+				bRet = false;
+		}
+		// For static libraries binary/target is same as their library.
+		for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+			if ( ! m_vStaticLibraries.at(i)->BinaryFileExist() )
+				bRet = false;
+	}
+	// Platform gcce.
+	else if ( _stricmp( m_sPlatform.c_str(), "gcce" ) == 0 )
+	{
+		// Verify that module(s) symbol file(s) exist
+		for( size_t i = 0; i < m_vModules.size(); i++ )
+		{
+			// Check symbol file.
+			if ( ! m_vModules.at(i)->SymbolFileExist() )
+				bRet = false;
+		}
+	}
+	return bRet;
+}
+
+// ----------------------------------------------------------------------------
+// Write project's (user) attributes to a file under temp folder
+// ----------------------------------------------------------------------------
+bool CATProject::WriteAttributes() const
+{
+	LOG_FUNC_ENTRY("CATProject::WriteAttributes");
+	// File to write to
+	string sOutFile( AT_TEMP_DIR );
+	sOutFile.append( "\\" );
+	sOutFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+	// Open file truncate if exists
+	ofstream out( sOutFile.c_str(), ios_base::trunc );
+	// Check file opened successfully
+	if ( ! out.good() )
+		return false;
+	// Write attributes line by line
+	out << m_bUninstrumented << endl; // Is project instrumented
+	// Sbs version
+	if ( m_eBuildSystem == CATProject::SBS_V2 )
+		out << "SBS_2" << endl; 
+	else
+		out << "SBS_1" << endl;
+	out << endl; // Reserved for possible binary data
+	out << m_sPlatform << endl;
+	out << m_sVariant << endl;
+	out << m_eLoggingMode << endl;
+	out << m_eBuildType << endl;
+	out << m_sS60FileName << endl;
+	out << m_iAllocCallStackSize << endl;
+	out << m_iFreeCallStackSize << endl;
+	for ( size_t i = 0 ; i < m_vTargetModules.size() ; i++ )
+		out << m_vTargetModules.at(i) << AT_PROJECT_ATTRIBUTES_SEPARATOR;
+	out << endl;
+	out << m_sBuildCommand << endl;
+	out.close();
+	return true;
+}
+// ----------------------------------------------------------------------------
+// Reads project's (user) attributes to a file under temp folder
+// ----------------------------------------------------------------------------
+bool CATProject::ReadAttributes()
+{
+	LOG_FUNC_ENTRY("CATProject::ReadAttributes");
+	// File to read on
+	string sInFile( AT_TEMP_DIR );
+	sInFile.append( "\\" );
+	sInFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+	// Open file
+	ifstream in( sInFile.c_str() );
+	// Check file opened successfully
+	if ( ! in.good() )
+		return false;
+	// Read attributes
+	char cLine[ MAX_LINE_LENGTH ];
+	string sLine;
+	in.getline( cLine, MAX_LINE_LENGTH );
+	int iValue = atoi( cLine );
+	if ( iValue == 1 )
+		m_bUninstrumented = true;
+	else
+		m_bUninstrumented = false;
+	// Sbs version
+	in.getline( cLine, MAX_LINE_LENGTH ); string sBuildSystem = string( cLine );
+	if ( sBuildSystem.compare( "SBS_1" ) == 0 )
+		m_eBuildSystem = CATProject::SBS_V1;
+	else if ( sBuildSystem.compare( "SBS_2" ) == 0 )
+		m_eBuildSystem = CATProject::SBS_V2;
+	else {
+		LOG_STRING("Error invalid build system defined in project.cfg");
+		m_eBuildSystem = CATProject::SBS_V1;
+	}
+	in.getline( cLine, MAX_LINE_LENGTH ); // reserverd for possible binary timestamp or similar
+	in.getline( cLine, MAX_LINE_LENGTH ); m_sPlatform = string( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_sVariant = string( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_eLoggingMode = atoi( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_eBuildType = atoi( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_sS60FileName = string( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_iAllocCallStackSize = atoi( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); m_iFreeCallStackSize = atoi( cLine );
+	in.getline( cLine, MAX_LINE_LENGTH ); sLine = cLine;
+	size_t iSpot = sLine.find( AT_PROJECT_ATTRIBUTES_SEPARATOR );
+	while ( iSpot != string::npos )
+	{
+		string sTarget = sLine.substr(0, iSpot );
+		m_vTargetModules.push_back( sTarget );
+		sLine.erase(0, iSpot + AT_PROJECT_ATTRIBUTES_SEPARATOR.size() );
+		iSpot = sLine.find( AT_PROJECT_ATTRIBUTES_SEPARATOR );
+	}
+	in.getline( cLine, MAX_LINE_LENGTH ); m_sBuildCommand = cLine;
+	in.close();
+	return true;
+}
+
+// ----------------------------------------------------------------------------
+// Creates atool_temp directory to current folder if does not exist
+// ----------------------------------------------------------------------------
+bool CATProject::MakeTempDirIfNotExist()
+{
+	LOG_FUNC_ENTRY("CATProject::MakeTempDirIfNotExist");
+	if ( ! DirectoryExists( AT_TEMP_DIR ) )
+	{
+		if( !CreateDirectory( AT_TEMP_DIR , NULL ) )
+		{
+			return false;
+		}
+	}
+	return true;
+}
+// ----------------------------------------------------------------------------
+// Utilities
+// ----------------------------------------------------------------------------
+
+bool CATProject::RunAbldCommandToAllTargets( const string& sCommand )
+{
+	LOG_FUNC_ENTRY("CATProject::RunAbldCommandToAllTargets");
+
+	// Check for space at the commands end.
+	string sSystemCall( sCommand );
+	if ( *(sSystemCall.rbegin()) != ' ' )
+		sSystemCall.append( " " );
+
+	// Loop calls.
+	bool bRet = true;
+	for ( vector<string>::iterator it = m_vTargetModules.begin(); it < m_vTargetModules.end(); it++ )
+	{
+		string sCall( sSystemCall );
+		sCall.append( RemovePathAndExt( *it, true ) );
+		cout << AT_MSG_SYSTEM_CALL << sCall << endl;
+		if ( (int) system( sCall.c_str() ) != 0 )
+			bRet = false;
+	}
+	return bRet;
+}
+
+void CATProject::AddTargetModuleIfDefined( string& sCmd )
+{
+	LOG_FUNC_ENTRY("CATProject::AddTargetModuleIfDefined");
+	// Do we have target modules defined
+	if ( m_vTargetModules.size() > 0 )
+	{
+		switch( m_eBuildSystem )
+		{
+		case SBS_V1:
+			// Add first target modules name without extension to build cmd.
+			sCmd.append( " " );
+			sCmd.append( RemovePathAndExt( m_vTargetModules.at( 0 ), true ) );
+			break;
+		case SBS_V2:
+			// Add all target modules to build command using raptor switch '-p'.
+			for( size_t i = 0 ; i < m_vTargetModules.size() ; i++ )
+			{
+				LOG_STRING("Adding :" << m_vTargetModules.at( i ) );
+				sCmd.append( " -p " );
+				sCmd.append( m_vTargetModules.at( i ) );
+			}
+			break;
+		}
+	}
+}
+
+bool CATProject::IsTargetModuleInProject() const
+{
+	LOG_FUNC_ENTRY("CATProject::IsTargetModuleInProject");
+	vector<CATModule2*>::const_iterator modules;
+	vector<CATModule2*>::const_iterator staticModules;
+	vector<string>::const_iterator targets;
+	bool bRet = true;
+	// Do we have target modules defined
+	if ( m_vTargetModules.size() > 0 )
+	{
+		// Sbs version 1 support only single target module.
+		if ( m_eBuildSystem == SBS_V1 )
+		{
+			// Try to find module from project.
+			bRet = false;
+			string sTarget = m_vTargetModules.at(0);
+			for( modules = m_vModules.begin() ; modules != m_vModules.end() ; modules++ )
+			{
+				if( (*modules)->GetMmpFile().find( sTarget ) != string::npos )
+				{
+					// Found it return true.
+					bRet = true;
+					break;
+				}
+			}
+			for( staticModules = m_vStaticLibraries.begin(); staticModules != m_vStaticLibraries.end(); staticModules++ )
+			{
+				if( (*staticModules)->GetMmpFile().find( sTarget ) != string::npos )
+				{
+					bRet = true;
+					break;
+				}
+			}
+			if ( ! bRet )
+			{
+				// Not found display error message.
+				cout << AT_MSG << "Error, " << sTarget << " not defined in project." << endl;
+			}
+		}
+		// Sbs version 2 supports multiple target modules.
+		else if ( m_eBuildSystem == SBS_V2 )
+		{
+			// Check that all targets are defined in project.
+			for( targets = m_vTargetModules.begin(); targets != m_vTargetModules.end() ; targets++ )
+			{
+				// Found iterated target?
+				bool bFound = false;
+				for ( modules = m_vModules.begin() ; modules != m_vModules.end() ; modules++ )
+				{
+					if( (*modules)->GetMmpFile().find( *targets ) != string::npos )
+					{
+						// yes.
+						bFound = true;
+						break;
+					}
+				}
+				for( staticModules = m_vStaticLibraries.begin(); staticModules != m_vStaticLibraries.end(); staticModules++ )
+				{
+					if( (*staticModules)->GetMmpFile().find( *targets ) != string::npos )
+					{
+						bFound = true;
+						break;
+					}
+				}
+				if ( ! bFound )
+				{
+					// Display error when not found and set return value false.
+					bRet = false;
+					cout << AT_MSG << "Error, " << targets->c_str() << " not defined in project." << endl;
+				}
+			}
+		}
+	}
+	return bRet;
+}
+
+string CATProject::GetBuildTypeString()
+{
+	LOG_LOW_FUNC_ENTRY("CATProject::GetBuildTypeString");
+	// Return build type as lowercase string
+	switch( m_eBuildType )
+	{
+	case UDEB:
+		return string("udeb");
+	case UREL:
+		return string("urel");
+	default:
+		return "";
+	}
+}
+
+string CATProject::GetBuildTypeString( int eType )
+{
+	LOG_LOW_FUNC_ENTRY("CATProject::GetBuildTypeString( int eType )");
+	// Return build type as lowercase string
+	switch( eType )
+	{
+	case UDEB:
+		return string("udeb");
+	case UREL:
+		return string("urel");
+	default:
+		return string("unknown");
+	}
+}
+
+bool CATProject::CleanTemporaryDirs()
+{
+	LOG_FUNC_ENTRY("CATProject::CleanTemporaryDirs");
+	bool bRet = true;
+	// Modules
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		if ( ! m_vModules.at(i)->CleanTemporaryDir() )
+			bRet = false;
+	}
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if ( ! m_vStaticLibraries.at(i)->CleanTemporaryDir() )
+			bRet = false;
+	}
+	// Projects
+	vector<string> vFileList = DirList( AT_TEMP_DIR, false , true );
+	vector<string>::iterator it2 = vFileList.begin();
+	// Size of constant table
+	int iCount = sizeof( TEMP_EXTENSION_NO_DELETE ) / sizeof( string );
+	while ( it2 != vFileList.end() )
+	{
+		// Get extension and compare it to list
+		bool bDelete = true;
+		string sExtension = GetExtension( *it2 );
+		ChangeToLower( sExtension );
+		for ( int i = 0 ; i < iCount ; i++ )
+		{
+			if( sExtension.compare( TEMP_EXTENSION_NO_DELETE[i] ) == 0 )
+			{
+				bDelete = false;
+				break;
+			}
+		}
+		if ( bDelete )
+		{
+			// Delete file
+			if ( ! FileDelete( *it2, true ) )
+				bRet = false;
+		}
+		// Increment
+		it2++;
+	}
+	return bRet;
+}
+
+bool CATProject::DeleteTemporaryDirs()
+{
+	LOG_FUNC_ENTRY("CATProject::DeleteTemporaryDirs");
+	bool bRet = true;
+	// Modules
+	for( size_t i = 0; i < m_vModules.size(); i++ )
+	{
+		if (! m_vModules.at(i)->DeleteTemporaryDir() )
+			bRet = false;
+	}
+	for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+	{
+		if (! m_vStaticLibraries.at(i)->DeleteTemporaryDir() )
+			bRet = false;
+	}
+	return bRet;
+}
+
+bool CATProject::InitSbs1MakeFileWithPathToTemp()
+{
+	LOG_FUNC_ENTRY("CATProject::InitSbs1MakeFileWithPathToTemp");
+	// Use temporary folder
+	m_sMakeFile.clear();
+	m_sMakeFile.append( AT_TEMP_DIR );
+	m_sMakeFile.append( "\\" );
+	m_sMakeFile.append( AT_LEVEL_1_MAKEFILE_NAME );
+	// At end check does it exist, return the result.
+	return FileExists( m_sMakeFile.c_str() );
+}
+
+bool CATProject::InitSbs1MakeFileWithPath()
+{
+	LOG_FUNC_ENTRY("CATProject::InitMakeFileWithPath");
+	if ( m_sEpocRoot.empty() )
+	{
+		LOG_STRING("Error, epocroot is not set.");
+		return false;
+	}
+	m_sMakeFile.clear();
+	m_sMakeFile.append( m_sEpocRoot );
+	if( *m_sMakeFile.rbegin() != '\\' )
+		m_sMakeFile.append( "\\" );
+	m_sMakeFile.append( "epoc32\\build\\" );
+	// Add current directory to path (first remove driveletter).
+	string sCurrentDir( m_cCurrentDir );
+	if ( sCurrentDir.length() < 3 )
+	{
+		LOG_STRING("Error, current dir invalid.");
+		return false;
+	}
+	sCurrentDir.erase(0,3);
+	m_sMakeFile.append( sCurrentDir );
+	m_sMakeFile.append( "\\" );
+	// Platform
+	string sPlatInUpper( m_sPlatform);
+	ChangeToUpper( sPlatInUpper );
+	m_sMakeFile.append( sPlatInUpper );
+	// Possible variant
+	if ( m_sVariant.empty() )
+	{
+		// Test modules only?
+		if ( m_bAbldTest )
+			m_sMakeFile.append( "TEST" );
+		m_sMakeFile.append( "." );
+		m_sMakeFile.append( "MAKE" );
+	}
+	else
+	{
+		m_sMakeFile.append( "." );
+		m_sMakeFile.append( m_sVariant );
+		// Test modules only?
+		if ( m_bAbldTest )
+			m_sMakeFile.append( "TEST" );
+		m_sMakeFile.append( ".MAKE" );
+	}
+	// At end check does it exist, return the result.
+	return FileExists( m_sMakeFile.c_str() );
+}
+
+// ----------------------------------------------------------------------------
+// Get & Sets
+// ----------------------------------------------------------------------------
+void CATProject::SetBuildSystem( BUILD_SYSTEM eSystem )
+{
+	LOG_FUNC_ENTRY("CATProject::SetBuildSystem");
+	m_eBuildSystem = eSystem;
+}
+void CATProject::SetMode( PROJECT_MODE eMode )
+{
+	LOG_FUNC_ENTRY("CATProject::SetMode");
+	m_eMode = eMode;
+}
+int CATProject::GetMode() const
+{
+	LOG_LOW_FUNC_ENTRY("CATProject::GetMode");
+	return m_eMode;
+}
+void CATProject::SetEpocRoot( const string& sEpocRoot )
+{
+	LOG_FUNC_ENTRY("CATProject::SetEpocRoot");
+	m_sEpocRoot = sEpocRoot;
+}
+void CATProject::SetPlatform( const string& sPlatform )
+{
+	LOG_FUNC_ENTRY("CATProject::SetPlatform");
+	m_sPlatform = sPlatform;
+}
+void CATProject::SetVariant( const string& sVariant )
+{
+	LOG_FUNC_ENTRY("CATProject::SetVariant");
+	m_sVariant = sVariant;
+}
+void CATProject::SetLoggingMode( LOGGING_MODE eLoggingMode)
+{
+	LOG_FUNC_ENTRY("CATProject::SetLoggingMode");
+	m_eLoggingMode = eLoggingMode;
+}
+void CATProject::SetAllocCallStackSize( int iAllocCallStackSize )
+{
+	m_iAllocCallStackSize = iAllocCallStackSize;
+}
+void CATProject::SetFreeCallStackSize( int iFreeCallStackSize )
+{
+	m_iFreeCallStackSize = iFreeCallStackSize;
+}
+void CATProject::SetBuildType( BUILD_TYPE eType )
+{
+	LOG_FUNC_ENTRY("CATProject::SetBuildType");
+	m_eBuildType = eType;
+}
+void CATProject::SetS60FileName( const string& sFileName)
+{
+	LOG_FUNC_ENTRY("CATProject::SetS60FileName");
+	m_sS60FileName = sFileName;
+}
+void CATProject::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
+{
+	LOG_FUNC_ENTRY("CATProject::SetRomSymbolFiles");
+	m_vRomSymbolFiles = vRomSymbolFiles;
+}
+void CATProject::SetTargetModule(const string& sTargetModule)
+{
+	LOG_FUNC_ENTRY("CATProject::SetTargetModule");
+	m_sTargetModule = sTargetModule;
+	ChangeToLower( m_sTargetModule);
+}
+void CATProject::SetBinaryTarget(const string& sBinaryTarget)
+{
+	LOG_FUNC_ENTRY("CATProject::SetBinaryTarget");
+	m_sBinaryTarget = sBinaryTarget;
+	ChangeToLower( m_sBinaryTarget );
+}
+void CATProject::SetDataFile( const string& sDataFile )
+{
+	LOG_FUNC_ENTRY("CATProject::SetDataFile");
+	m_sDataFile = sDataFile;
+}
+void CATProject::SetLogLevel( int iLogLevel )
+{
+	LOG_FUNC_ENTRY("CATProject::SetLogLevel");
+	m_iLoggingLevel = iLogLevel;
+}
+void CATProject::SetDataFileOutput( const string& sDataFileOutput )
+{
+	LOG_FUNC_ENTRY("CATProject::SetDataFileOutput");
+	m_sDataFileOutput = sDataFileOutput;
+}
+void CATProject::SetTargetModules( const vector<string>& vTargetModules )
+{
+	LOG_FUNC_ENTRY("CATProject::SetTargetModules");
+	m_vTargetModules = vTargetModules;
+}
+void CATProject::SetBuildCommand( const string& sBuildCommand )
+{
+	LOG_FUNC_ENTRY("CATProject::SetBuildCommand");
+	m_sBuildCommand = sBuildCommand;
+}
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/arguments.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,798 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Argument parsing functions.
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+//Forward declarations.
+bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool checkDataFileName( string& sFileName );
+bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args );
+
+// Constants for old "hooking" parameter parsing.
+#define INVALID_PARAMETER "AnalyzeTool : Error, invalid parameter: "
+const char DATAFILENAME_INVALID_CHARS[] = " &^+-@$%*()|\\/[]{}<>?;:,\"'";
+
+/**
+* Check datafile name for invalid characters.
+* @return true if file name ok.
+*/
+bool checkDataFileName( string& sFileName )
+{
+	for ( size_t i = 0; i < sFileName.length(); i++ )
+	{
+		const char c = sFileName.at( i );
+		if( strchr( DATAFILENAME_INVALID_CHARS, c ) != 0 )
+			return false;
+	}
+	return true;
+}
+
+/**
+* Parse base arguments from given vector of strings.
+* Removes debug / help arguments from vector.
+*/
+bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+	// Iterator used in this function.
+	vector<string>::iterator it;
+	// If no arguments set show help true.
+ 	if ( vArgs.size() == 0 )
+	{
+		args.eMainSwitch = SWITCH_UNKNOWN;
+		args.bHelp = true;
+	}
+	//Try find help and debug switches.
+	//Note: -help is main switch what shows syntax examples.
+	for(it = vArgs.begin(); it != vArgs.end(); it++ )
+	{
+		//Help switches.
+		if ( ! _stricmp( (*it).c_str(), "-?" ) )
+		{
+			args.bHelp = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--?" ) )
+		{
+			args.bHelp = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--help" ) )
+		{
+			args.bHelp = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "/?" ) )
+		{
+			args.bHelp = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		//Debug switches.
+		else if ( ! _stricmp( (*it).c_str(), "-show_debug" ) )
+		{
+			args.bDebugConsole = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--show_debug" ) )
+		{
+			args.bDebugConsole = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-show_debug_all" ) )
+		{
+			args.bDebugConsole = true;
+			args.bDebugLowLevel = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--show_debug_all" ) )
+		{
+			args.bDebugConsole = true;
+			args.bDebugLowLevel = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-show_dbgview" ) )
+		{
+			args.bDebugDbgView = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--show_dbgview" ) )
+		{
+			args.bDebugDbgView = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-show_dbgview_all" ) )
+		{
+			args.bDebugDbgView = true;
+			args.bDebugLowLevel = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "--show_dbgview_all" ) )
+		{
+			args.bDebugDbgView = true;
+			args.bDebugLowLevel = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+		//Raptor switch.
+		else if ( ! _stricmp( (*it).c_str(), "-sbs2" ) )
+		{
+			args.bEnableSbs2 = true;
+			it = vArgs.erase( it );
+			if ( it == vArgs.end() )
+				break;
+		}
+	}
+	if ( vArgs.size() > 0 )
+	{
+		//Pick up main switch.
+		it = vArgs.begin();
+		if ( ! _stricmp( (*it).c_str(), "-a" ) )
+			args.eMainSwitch = SWITCH_ANALYZE;
+		else if ( ! _stricmp( (*it).c_str(), "-p" ) )
+			args.eMainSwitch = SWITCH_PARSE_TRACE;
+		else if ( ! _stricmp( (*it).c_str(), "-c" ) )
+			args.eMainSwitch = SWITCH_CLEAN;
+		else if ( ! _stricmp( (*it).c_str(), "-v" ) )
+			args.eMainSwitch = SWITCH_VERSION;
+		else if ( ! _stricmp( (*it).c_str(), "-vdbghelp" ) )
+			args.eMainSwitch = SWITCH_DBGHELP_VERSION;
+		else if ( ! _stricmp( (*it).c_str(), "-help" ) )
+			args.eMainSwitch = SWITCH_HELP;
+		else if ( ! _stricmp( (*it).c_str(), "-me" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_EXTERNAL;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-e" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_EXTERNAL_FAST;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-mi" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_INTERNAL;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-instrument_i" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_EXTENSION_INTERNAL;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-instrument_e" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_EXTENSION_EXTERNAL;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-instrument_ef" ) )
+		{
+			args.eMainSwitch = SWITCH_HOOK;
+			args.eHookSwitch = HOOK_EXTENSION_EXTERNAL_FAST;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-uninstrument" ) )
+		{
+			args.eMainSwitch = SWITCH_UNHOOK;
+			args.eHookSwitch = HOOK_EXTENSION_UNINSTRUMENT;
+		}
+		else if ( ! _stricmp( (*it).c_str(), "-uninstrument_failed" ) )
+		{
+			args.eMainSwitch = SWITCH_UNHOOK;
+			args.eHookSwitch = HOOK_EXTENSION_FAILED;
+		}
+	}
+	return true;
+}
+
+/**
+* Parse analyze related arguments from given vector of strings.
+*/
+bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+	bool bRet = true;
+	if ( vArgs.size() < 2 )
+	{
+		cout << AT_MSG << "Error, missing datafile." << endl;
+		return false;
+	}
+	// Iterator used in this function.
+	vector<string>::const_iterator it;
+	for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
+	{
+		if ( it->find("-l") != string::npos )
+		{
+			if ( it->length() == 3 )
+			{
+				// Create char array for atoi function
+				char level[2];
+				level[0] = it->at(2);
+				level[1] = 0; // null terminate
+				// check that its digit first
+				if ( isdigit(level[0]) )
+				{
+					// pass array to atoi
+					int iLoggingLevel = atoi( level );
+					if ( iLoggingLevel >= 0 && iLoggingLevel <= 3 )
+					{
+						// log level ok
+						args.ANALYZE.iLoggingLevel = iLoggingLevel;
+						continue;
+					}
+				}
+				bRet = false;
+				cout << AT_MSG << "Invalid logging level specified (0-3)." << endl;
+				args.ANALYZE.iLoggingLevel = -1;
+			}
+		}
+		// No else here because logging level check is done to all args in list.
+		// Rom symbol file
+		if( _stricmp( it->c_str(), "-s" ) == 0 )
+		{
+			it++;
+			if ( it == vArgs.end() )
+			{
+				bRet = false;
+				cout << AT_MSG << "Missing symbol file." << endl;
+				break; // Leave for loop.
+			}
+			else
+			{
+				args.ANALYZE.bSymbolFile = true;
+				args.ANALYZE.vSymbolFiles.push_back( *it );
+				continue;
+			}
+		}
+		else 
+		{
+			// If we got datafile we must assume this is output
+			if( ! args.ANALYZE.sDataFile.empty() )
+			{
+				if ( args.ANALYZE.sOutputFile.empty() )
+					args.ANALYZE.sOutputFile = *it;
+				else
+				{
+					bRet = false;
+					cout << AT_MSG << "Invalid parameter: " << *it << endl;
+				}
+			}
+			// If this is file we assume datafile
+			else if( CATBase::FileExists( it->c_str() ) )
+			{
+				args.ANALYZE.sDataFile = *it;
+			}
+			else
+			{
+				bRet = false;
+				cout << AT_MSG << "Specified datafile does not exist." << endl;
+			}
+		}
+	}
+	if ( args.ANALYZE.sDataFile.empty() )
+		bRet = false;
+	return bRet;
+}
+
+
+/**
+* Parse hooking related arguments from given vector of strings.
+*/
+bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+	bool bRet = true;
+	try {
+		// Iterator used in this function.
+		vector<string>::const_iterator it;
+
+		// Check that we have some arguments except main switch.
+		if ( vArgs.size() < 2 )
+		{
+			if ( args.eHookSwitch == HOOK_EXTENSION_UNINSTRUMENT
+				|| args.eHookSwitch == HOOK_EXTENSION_FAILED
+				)
+				return bRet;
+			cout << AT_MSG << "Error, Missing build command." << endl;
+			bRet = false;
+		}
+		bool bBuildFound = false;
+		for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
+		{
+			// If's to pickup atool options
+			// no build switch
+			if ( _stricmp( it->c_str(), "-nobuild" ) == 0 )
+			{
+				args.HOOK.bNoBuild = true;
+			}
+			// call stack size(s)
+			else if ( _stricmp( it->c_str(), "-acs" ) == 0 || _stricmp( it->c_str(), "-fcs" ) == 0 )
+			{
+				// Free vs Alloc
+				bool bAlloc = true;
+				if ( _stricmp( it->c_str(), "-fcs" ) == 0 )
+					bAlloc = false;
+				// Value
+				it++;
+				if ( it== vArgs.end() )
+				{
+					bRet = false;
+					cout << AT_MSG << "Error, missing call stack size parameter." << endl;
+					break;
+				}
+				else if ( ! _stricmp( it->c_str(), "sbs" ) 
+					|| ! _stricmp( it->c_str(), "abld" )
+					|| ! _stricmp( it->c_str(), "-f" ) )
+				{
+					bRet = false;
+					cout << AT_MSG << "Error, missing call stack size parameter." << endl;
+					break;
+				}
+				else
+				{
+					int i;
+					// Try to parse integer value using stream.
+					istringstream ss( *it );
+					if ( ss>>i )
+					{
+						// Value parsed ok now check bounds.
+						if ( i < AT_CALL_STACK_SIZE_MIN  )
+						{
+							bRet = false;
+							cout << AT_MSG << "Error, specified call stack size value too small." << endl;
+							break;
+						}
+						else if ( i > AT_CALL_STACK_SIZE_MAX )
+						{
+							bRet = false;
+							cout << AT_MSG << "Error, specified call stack size value too big." << endl;
+							break;
+						}
+						else
+						{
+							// Value valid.
+							if ( bAlloc )
+								args.HOOK.iAllocCallStackSize = i;
+							else
+								args.HOOK.iFreeCallStackSize = i;
+						}
+					}
+					else
+					{
+						// Error parsing value using stream.
+						bRet = false;
+						cout << AT_MSG << "Error, specified call stack size value invalid." << endl;
+						break;
+					}
+
+				}
+			}
+			// Data file name.
+			else if ( _stricmp( it->c_str(), "-f" ) == 0 )
+			{
+				it++;
+				if ( it == vArgs.end() )
+				{
+					bRet = false;
+					cout << AT_MSG << "Error, missing internal data gathering file name." << endl;
+					break;
+				}
+				else if ( ! _stricmp( it->c_str(), "sbs" ) || ! _stricmp( it->c_str(), "abld" ) )
+				{
+					bRet = false;
+					cout << AT_MSG << "Error, missing internal data gathering file name." << endl;
+					break;
+				}
+				else
+				{
+					if ( checkDataFileName( string( *it ) ) )
+					{
+						// Pickup filename.
+						args.HOOK.bDataFileName = true;
+						args.HOOK.sDataFileName = *it;
+					}
+					else
+					{
+						bRet = false;
+						cout << AT_MSG << "Error, specified internal data gathering file name contains invalid character(s)." << endl;
+						break;
+					}
+				}
+			}
+			// Build command parsing.
+			else if ( _stricmp( it->c_str(), "sbs" ) == 0 )
+			{
+				// By default sbs command is not valid.
+				bRet = false;
+				// By default build found
+				bBuildFound = true;
+				// Use raptor build system, pickup all rest arguments to sbs commmand.
+				bool bFoundConfig = false; // Is configuration defined.
+				args.HOOK.iBuildSystem = 2;
+				vector<string>::const_iterator itC = it;
+				args.HOOK.sBuildCmd.clear();
+				for ( ; itC != vArgs.end() ; itC++ )
+				{
+					args.HOOK.sBuildCmd.append( *itC );
+					args.HOOK.sBuildCmd.append( " " );
+					args.HOOK.vBuildCmd.push_back( *itC );
+				}
+				// Remove last space
+				if ( args.HOOK.vBuildCmd.size() > 1 )
+					args.HOOK.sBuildCmd.erase( args.HOOK.sBuildCmd.size()-1 );
+
+				// Parse needed variables from sbs command.
+				vector<string>::iterator itSbs;
+				for( itSbs = args.HOOK.vBuildCmd.begin(); itSbs != args.HOOK.vBuildCmd.end() ; itSbs++ )
+				{
+					// Program(s).
+					if ( _stricmp( itSbs->c_str(), "-p" ) == 0 )
+					{
+						// Next is program.
+						itSbs++;
+						args.HOOK.vTargetPrograms.push_back( *itSbs );
+					}
+					else if ( itSbs->find( "--project=" ) != string::npos )
+					{
+						itSbs->erase(0, 10 );
+						args.HOOK.vTargetPrograms.push_back( *itSbs );
+					}
+					// platform & build type ( configuration )
+					else if ( _stricmp( itSbs->c_str(), "-c" ) == 0 || itSbs->find( "--config=" ) != string::npos )
+					{
+						// Error message if config found more than once.
+						if ( bFoundConfig )
+						{
+							cout << AT_MSG << "Error, no support defining more than one configuration." << endl;
+							bRet = false;
+							continue;
+						}
+
+						if (_stricmp( itSbs->c_str(), "-c" ) == 0 )
+						{
+							// Next is the configuration
+							itSbs++;
+							// Check that iterator is valid.
+							if ( itSbs == args.HOOK.vBuildCmd.end() )
+								break;
+						}
+						else
+						{
+							// Remove the "--config=".
+							itSbs->erase( 0, 9 );
+							// Check its not empty.
+							if ( itSbs->size() == 0 )
+								break;
+						}
+						
+						// Identify configuration, if successful set sbs command as valid.
+						if ( parseSbsConfiguration( *itSbs, args ) )
+							bRet = true;
+						// Set we encountered one configuration.
+						bFoundConfig = true;
+					}
+				}
+				// Error message if command is missing configuration.
+				if ( !bFoundConfig )
+					cout << AT_MSG << "Error, missing configuration definition from sbs cmd." << endl;
+			}
+			else if ( _stricmp( it->c_str(), "abld" ) == 0 )
+			{
+				bBuildFound = true;
+				// Use abld build system, pickup all rest argumenst as abld options.
+				args.HOOK.iBuildSystem = 1;
+				
+				vector<string>::const_iterator itC = it;
+				args.HOOK.sBuildCmd.clear();
+				for ( ; itC != vArgs.end() ; itC++ )
+				{
+					args.HOOK.sBuildCmd.append( *itC );
+					args.HOOK.sBuildCmd.append( " " );
+					args.HOOK.vBuildCmd.push_back( *itC );
+				}
+				
+				string sCmd( args.HOOK.sBuildCmd ); // build command to lower case here.
+				for( size_t i = 0 ; i < sCmd.size(); i++ )
+					sCmd.at(i) = tolower( sCmd.at(i) );
+
+				// Remove all until platform
+				if ( sCmd.find("build ") != string::npos )
+				{
+					// Check is test defined
+					if ( sCmd.substr(0, sCmd.find("build ")).find("test") != string::npos )
+						args.HOOK.bAbldTest = true;
+					sCmd.erase( 0, sCmd.find("build")+6 );
+				}
+				else
+					return false;
+				
+				//Is -debug switch in command?
+				if( sCmd.find( "-debug " ) != string::npos )
+				{
+					sCmd.erase( sCmd.find( "-debug " ), 7 );
+				}
+
+				// Parse needed "variables" from command.
+				bool bOk = false;
+
+				// Find platform
+				if ( sCmd.find( "armv5" ) != string::npos )
+				{
+					bOk = true;
+					args.HOOK.sPlatform = "armv5";
+					sCmd.erase( sCmd.find( "armv5" ), 5 );
+				}
+				else if ( sCmd.find( "winscw" ) != string::npos )
+				{
+					bOk = true;
+					args.HOOK.sPlatform = "winscw";
+					sCmd.erase( sCmd.find( "winscw" ), 6 );
+				}
+				else if ( sCmd.find( "gcce" ) != string::npos )
+				{
+					bOk = true;
+					args.HOOK.sPlatform = "gcce";
+					sCmd.erase( sCmd.find( "gcce" ), 4 );
+				}
+				if ( bOk )
+				{
+					// Feature variant.
+					if ( sCmd.at(0 ) == '.' )
+					{
+						sCmd.erase(0,1);
+						args.HOOK.sFeatureVariant = sCmd.substr( 0, sCmd.find_first_of(' ') );
+						sCmd.erase(0, sCmd.find_first_of(' ')+1 );
+					}
+				}
+				else
+				{
+					// not platform specified.
+					cout << AT_MSG << "Error, no supported platform found in abld parameters (armv5/winscw/gcce)." << endl;
+					bRet = false;
+				}
+				
+				// find build type
+				bOk = false;
+				if (  sCmd.find( "urel" ) != string::npos )
+				{
+					bOk = true;
+					args.HOOK.sBuildType = "urel";
+					sCmd.erase( sCmd.find( "urel" ), 4 );
+				}
+
+				else if ( sCmd.find( "udeb" ) != string::npos )
+				{
+					bOk = true;
+					args.HOOK.sBuildType = "udeb";
+					sCmd.erase( sCmd.find( "udeb" ), 4 );
+				}
+				if( !bOk )
+				{
+					// no build type specified.
+					cout << AT_MSG << "Error, no build type specified in abld parameters (udeb/urel)." << endl;
+					bRet = false;
+				}
+		
+				// Is there multiple programs (only should be used from extension).
+				if ( sCmd.find(" -p") != string::npos )
+				{
+					sCmd.erase( sCmd.find(" -p" ), sCmd.size() - sCmd.find(" -p" ) );
+					// Loop thru all parameters and pick up programs.
+					vector<string>::iterator it;
+					for( it = args.HOOK.vBuildCmd.begin(); it != args.HOOK.vBuildCmd.end(); it++ )
+					{
+						if ( _stricmp( it->c_str(), "-p" ) == 0 )
+						{
+							// Next is program.
+							it++;
+							string sProgram = *it;
+							// Make sure program name ends with ".mmp".
+							CATBase::ChangeToLower( sProgram );
+							if ( sProgram.length() >= 4 )
+							{
+                                string sEnd = sProgram.substr( sProgram.length()-4, 4 );
+								if ( sEnd.compare( ".mmp" ) != 0 )
+									sProgram.append( ".mmp" );
+							}
+							else
+								sProgram.append( ".mmp" );
+							args.HOOK.vTargetPrograms.push_back( sProgram );
+						}
+					}
+				}
+				else {
+					// find single defined program.
+					if ( sCmd.find_first_not_of(' ') != string::npos )
+					{
+						size_t iS = sCmd.find_first_not_of(' ');
+						size_t iE = sCmd.find_first_of(' ', iS );
+						string sProgram;
+						if ( iE == string::npos )
+							sProgram = sCmd.substr( iS, sCmd.size()-iS );
+						else
+							sProgram =  sCmd.substr( iS, iE-iS);
+						// Make sure program name ends with ".mmp".
+						CATBase::ChangeToLower( sProgram );
+						if ( sProgram.length() >= 4 )
+						{
+                            string sEnd = sProgram.substr( sProgram.length()-4, 4 );
+							if ( sEnd.compare( ".mmp" ) != 0 )
+								sProgram.append( ".mmp" );
+						}
+						else
+							sProgram.append( ".mmp" );
+						args.HOOK.vTargetPrograms.push_back( sProgram );
+					}
+				}
+			}
+			else
+			{
+				if ( ! bBuildFound )
+				{
+					bRet = false;
+					cout << AT_MSG << "Error, invalid parameter :" << *it << endl;
+					break;
+				}
+			}
+		}
+	}
+	catch(...)
+	{
+		bRet = false;
+		cout << AT_MSG << "Error parsing arguments." << endl;
+	}
+	return bRet;
+}
+
+
+/**
+* Parse trace parsing related arguments from given vector of strings.
+*/
+bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+	// Iterator used in this function.
+	vector<string>::const_iterator it = vArgs.begin();
+
+	if ( it == vArgs.end() )
+		return false;
+
+	it++;
+
+	if ( it == vArgs.end() )
+	{
+		cout << AT_MSG << "Error, input file not defined (raw data file)." << endl;
+		return false;
+	}
+
+	//Input.
+	args.PARSE.bDataFile = true;
+	args.PARSE.sDataFile = *it;
+	
+	it++;
+	if ( it == vArgs.end() )
+	{
+	
+		cout << AT_MSG << "Error, output file not defined (device data file)." << endl;
+		return false;
+	}
+
+	//Output.
+	args.PARSE.bOutputFile = true;
+	args.PARSE.sOutputFile = *it;
+	return true;
+}
+
+/**
+* Identifies/parses the configuration string when raptor used (-c / --config= ).
+*/
+bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args )
+{
+	CATBase::ChangeToLower( sConfiguration );
+	vector<string> tokens = CATBase::ParseStringToVector( sConfiguration, '.' );
+	
+	//we check if winscw/armv5 and udeb/urel is used
+	//rest of the "." are variants which we all support by default.
+
+	//first we check if some of aliases is used
+	if ( tokens.at(0).compare("armv5_urel") == 0 )
+	{
+		args.HOOK.sPlatform = "armv5";
+		args.HOOK.sBuildType = "urel";
+		return true;
+	}
+	else if ( tokens.at(0).compare("armv5_udeb") == 0 )
+	{
+		args.HOOK.sPlatform = "armv5";
+		args.HOOK.sBuildType = "udeb";
+		return true;
+	}
+	else if ( tokens.at(0).compare("winscw_udeb") == 0)
+	{
+		args.HOOK.sPlatform = "winscw";
+		args.HOOK.sBuildType = "udeb";
+		return true;
+	}
+	else if ( tokens.at(0).compare("winscw_urel") == 0 )
+	{
+		args.HOOK.sPlatform = "winscw";
+		args.HOOK.sBuildType = "urel";
+		return true;
+	}
+	//if 1st token is not an alias, lets try dot configurations
+	else if ( tokens.at(0).compare("arm") == 0 )
+	{
+		// check we have atleast 3 tokens. i.e arm v5 debug x ...
+		if ( tokens.size() >= 3 )
+		{
+			// Next configuration is arm version, we only support v5.
+			if ( tokens.at(1).compare( "v5" ) == 0)
+			{
+				args.HOOK.sPlatform = "armv5";
+
+				// Check next configuration part is debug or release
+				if ( tokens.at(2).compare( "udeb" ) == 0)
+				{
+					args.HOOK.sBuildType = "udeb";
+					return true;
+				}
+				else if ( tokens.at(2).compare( "urel" ) == 0 )
+				{
+					args.HOOK.sBuildType = "urel";
+					return true;
+				}
+				else
+				{
+					cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(2) << endl;
+				    cout << AT_MSG << "Supported are: udeb,urel." << endl;
+				    return false;
+				}
+			}
+			else
+			{
+				cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(1) << endl;
+				cout << AT_MSG << "Supported are: v5." << endl;
+				return false;
+			}
+		}
+	}
+	
+	cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(0) << endl;
+	cout << AT_MSG << "Supported are: arm, armv5_urel, armv5_udeb, winscw_udeb, winscw_urel." << endl;
+	return false;
+
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/atool.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,236 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Defines the entry point for the console application.
+*
+*/
+
+// Includes.
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATDatParser.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/CATProject.h"
+
+//Debug logging parameters
+//To enable debugging as argument to atool.exe use:
+//--show_debug / -show_debug : Normal logging in console.
+//--show_debug_all / -show_debug_all : Log all (low level functions also) to console.
+//--show_dbgview / -show_dbgview : Normal logging to windows debug messages.
+//--show_dbgview_all / -show_dbgview_all : Log all (low level functions also) to windows debug messages.
+
+//Return codes (errorlevel) defined in AT_RETURN_CODE structure see ATCommonDefines.h.
+
+extern bool g_bDebugConsole = false;
+extern bool g_bDebugDbgView = false;
+extern bool g_bDebugLowLevel = false;
+
+//Argument parsing.
+extern bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args );
+
+//Helps.
+extern void print_help( void );
+extern void print_syntax_examples( void );
+
+//AT Library check functions
+extern bool CheckATLibrariesArmv5( string sEpocRoot );
+extern bool CheckATLibrariesArmv5Abiv2( string sEpocRoot );
+extern bool CheckATLibrariesWinscw( string sEpocRoot );
+
+//CLE version functions.
+extern int showVersionInfo( void );
+
+//dbghelp.dll version function.
+extern int showDbgHelpVersionInfo( bool showVersion );
+
+//Miscelllanaeous functions.
+extern bool CheckSBS2Folder( void );
+
+const char DEBUG_PARAMETER_CONSOLE[] = "-debug";
+const char DEBUG_PARAMETER_DBGVIEW[] = "-dbgview";
+const char SBS2_PARAMETER[] = "-sbs2";
+char g_cCurrentDir[MAX_LINE_LENGTH];
+
+//Global compile class objects are neededif ctrl+c is pressed mmp file must be restored.
+CATProject project_module;
+
+//Parse object.
+CATParseTraceFile Parser;
+
+/**
+* Handle process control signals.
+*/
+BOOL WINAPI HandlerRoutine( DWORD dwCtrlType )
+{
+	//Run recovery and exit for project if user presses ctrl+c
+	//or close signal is received.
+	if( dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_CLOSE_EVENT )
+	{
+		int iMode = project_module.GetMode();
+		if ( iMode == CATProject::COMPILE
+			|| iMode == CATProject::INSTRUMENT
+			|| iMode == CATProject::INSTRUMENT_CONSOLE )
+			project_module.RunRecoveryAndExit();
+	}
+	//Return false so program execution is stopped.
+	return false;
+}
+// TESTING
+int _tmain( int argc, _TCHAR* argv[] )
+{
+	#ifdef MEM_LEAK_CHECK
+	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+	#endif
+	try {
+		//Set function to handle process control signals.
+		SetConsoleCtrlHandler( HandlerRoutine, true );
+		vector<string> vArguments;
+		for( int i = 1 ; i < argc ; i++ )
+		{
+			vArguments.push_back( argv[i] );
+		}
+		//Help variables.
+		string sEpocRoot("");
+		//Parse base arguments.
+		ARGUMENTS args;
+		parseBaseArguments( vArguments, args );
+
+		// Debugging messages.
+		if ( args.bDebugConsole == true )
+			g_bDebugConsole = true;
+		if ( args.bDebugDbgView == true )
+			g_bDebugDbgView = true;
+		if ( args.bDebugLowLevel == true )
+			g_bDebugLowLevel = true;
+
+		//According to main switch parse rest arguments.
+		switch( args.eMainSwitch )
+		{
+		case SWITCH_UNKNOWN:
+			print_help();
+			return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+		case SWITCH_ANALYZE:
+			if ( ! parseAnalyzeArguments( vArguments, args ) )
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			// Get epocroot
+			if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+				return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+			project_module.SetEpocRoot( sEpocRoot );
+			// project not uninstrumented run it first.
+			if ( ! project_module.IsUninstrumented() )
+			{
+				project_module.SetMode( CATProject::UNINSTRUMENT_CONSOLE );
+				project_module.Run();
+			}
+			// Set mode.
+			project_module.SetMode( CATProject::ANALYZE );
+			project_module.SetLogLevel( args.ANALYZE.iLoggingLevel );
+			project_module.SetDataFile( args.ANALYZE.sDataFile );
+			if ( args.ANALYZE.bSymbolFile )
+				project_module.SetRomSymbolFiles( args.ANALYZE.vSymbolFiles );
+			project_module.SetDataFileOutput( args.ANALYZE.sOutputFile);
+			return project_module.Run();
+		case SWITCH_HOOK:
+			// Parse arguments related to hooking.
+			if ( ! parseHookArguments( vArguments, args ) )
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			// Set variables for project.
+			if ( ! project_module.SetArguments( args ) )
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			// Get epocroot
+			if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+				return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+			project_module.SetEpocRoot( sEpocRoot );
+			// Check AnalyzeTool libraries
+			if ( _stricmp( args.HOOK.sPlatform.c_str(), "winscw") == 0 )
+			{
+				// Emulator winscw platform
+				if ( ! CheckATLibrariesWinscw(sEpocRoot) )
+					return AT_RETURN_CODE::AT_LIBS_MISSING;
+			}
+			else
+			{
+				// Armv5
+				if ( args.HOOK.iBuildSystem == 2 )
+				{
+					// Abiv2
+					if ( ! CheckATLibrariesArmv5Abiv2(sEpocRoot) )
+						return AT_RETURN_CODE::AT_LIBS_MISSING;
+				}
+				else
+				{
+					// Abiv1
+					if( ! CheckATLibrariesArmv5(sEpocRoot) )
+						return AT_RETURN_CODE::AT_LIBS_MISSING;
+				}
+			}
+			// Run hooking.
+			return project_module.Run();
+			//Uninstrument
+		case SWITCH_UNHOOK:
+			// Set variables for project.
+			if ( ! project_module.SetArguments( args ) )
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			// Get epocroot
+			if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+				return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+			project_module.SetEpocRoot( sEpocRoot );
+			return project_module.Run();
+		case SWITCH_VERSION:
+			return showVersionInfo();
+		case SWITCH_DBGHELP_VERSION:
+			return showDbgHelpVersionInfo( true );
+		case SWITCH_CLEAN:
+			project_module.SetMode( CATProject::CLEAN );
+			if ( CheckSBS2Folder() )
+				project_module.SetBuildSystem( CATProject::SBS_V2 );
+			else
+				project_module.SetBuildSystem( CATProject::SBS_V1 );
+			return project_module.Run();
+		case SWITCH_PARSE_TRACE:
+			if ( ! parseParseArguments( vArguments, args ) )
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			if (  CATBase::IsDataFile( args.PARSE.sDataFile ) )
+			{
+				cout << AT_MSG << "Error, " << args.PARSE.sDataFile << " is already parsed." << endl;
+				return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+			}
+			if ( args.PARSE.bOutputFile )
+			{
+				//Save data with name in arguments[3]
+				Parser.StartParse( args.PARSE.sDataFile.c_str(), args.PARSE.sOutputFile.c_str() );
+			}
+			else
+			{
+				Parser.StartParse( args.PARSE.sDataFile.c_str(), NULL );
+			}
+			return AT_RETURN_CODE::OK;
+		case SWITCH_HELP:
+			print_help();
+			print_syntax_examples();
+			return AT_RETURN_CODE::OK;
+		default:
+			cout << AT_MSG << "Invalid parameters." << endl;
+			return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+		}
+
+	} catch(...)
+	{
+		cout << AT_MSG << "Error, unhandled exception." << endl;
+		return AT_RETURN_CODE::UNHANDLED_EXCEPTION;
+	}
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/cataddr2line.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Main module for addr2line pinpointing.
+*
+*/
+
+#include "../inc/cataddr2line.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATDatParser.h"
+
+#define ASCII_CHAR_CARRIAGE_RETURN 0x0D
+
+CATAddr2line::CATAddr2line()
+{
+	LOG_FUNC_ENTRY("CATAddr2line::CATAddr2line");
+}
+
+bool CATAddr2line::Open( const string& sParameter, const unsigned long /* iLong */ )
+{
+	LOG_FUNC_ENTRY("CATAddr2line::Open");
+	//Debugging for addr2line task.
+	//debug.open( "addr2line-lines.txt", ios_base::trunc );
+
+	m_sMapFileName.clear();
+	// Add .map extendsion
+	m_sMapFileName.append( sParameter );
+	m_sMapFileName.append( ".map" );
+
+	ReadMapFileArmv5();
+
+	//Make symfile path+name
+	string sFullPathToSymFile(sParameter);
+	sFullPathToSymFile.erase( sFullPathToSymFile.find_last_of( "." ), string::npos );
+	sFullPathToSymFile.append( ".sym" );
+
+	// Check with extension + .sym also.
+	if ( ! CATBase::FileExists( sFullPathToSymFile.c_str() ) )
+	{
+		sFullPathToSymFile.clear();
+		sFullPathToSymFile.append( sParameter );
+		sFullPathToSymFile.append( ".sym" );
+	}
+
+	return server.Initialize( sFullPathToSymFile );
+}
+
+string CATAddr2line::GetError( void )
+{
+	LOG_FUNC_ENTRY("CATAddr2line::GetError");
+	string s;
+	return s;
+}
+
+bool CATAddr2line::Close( void )
+{
+	LOG_FUNC_ENTRY("CATAddr2line::Close");
+	//Debugging for addr2line task.
+	//debug.close();
+	return true;
+}
+
+bool CATAddr2line::AddressToLine( CATMemoryAddress* result )
+{
+	LOG_FUNC_ENTRY("CATAddr2line::AddressToLine");
+	
+	result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE);
+
+	if( !server.GetProcessCreatedState() )
+		return false;
+	//Count address
+	ULONG uStartA = result->GetModuleStartAddress();
+	ULONG uMemoryA = result->GetAddress();
+	ULONG uCountedA = uMemoryA - uStartA;
+	uCountedA += FUNCTIONS_OFFSET_IN_GCCE;
+
+	string sTemp = CATBase::NumberToHexString( uCountedA );
+    //Remove "0x"
+    size_t iCounter = sTemp.find_first_of('x');
+    if( iCounter != string::npos )
+    {
+		sTemp.erase( 0, (int)iCounter+1 );
+    }
+	// Write to pipe that is the standard input for a child process.
+	server.WriteToPipe( sTemp ); 
+ 
+	// Read from pipe that is the standard output for child process.
+    string s = server.ReadFromPipe();
+
+	//If output not empty, parse output
+	if( !s.empty() )
+	{
+		//Debugging code for addr2line task.
+		//debug.write( "##########\n", 12 );
+		//debug.write( s.c_str(), s.size() );
+		result->SetAddressToLineState( CATMemoryAddress::EXACT );
+
+		string s2;
+		size_t iLocation = s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN );
+
+		bool bFunctionNameFoundUsingAddr2line = false;
+
+		//Function name
+		
+		if(iLocation != string::npos )
+		{
+			s2 = s.substr( 0, iLocation );
+			//All characters ascii?
+			if( CATBase::IsAscii( s2.c_str(), (int)s2.length() ) )
+			{
+				//addr2line returns $x if function name not found
+				//length must over 2 to be real function name
+				if( s2.length() > 2 )
+				{
+					bFunctionNameFoundUsingAddr2line = true;
+					result->SetFunctionName( s2 );
+					s.erase( 0, iLocation+2 );
+				}
+			}
+		}
+		//If function name not found using addr2line find it from map file
+		if( !bFunctionNameFoundUsingAddr2line )
+		{
+			string sFuncName( GetFunctionNameUsingAddress( uCountedA ) );
+			//If function name empty, print "???"
+			if( sFuncName.empty() )
+			{
+				s2 = "???";
+				result->SetFunctionName( s2 );
+				if(iLocation != string::npos )
+				{
+					s.erase( 0, iLocation+2 );
+				}
+			}
+			else
+				result->SetFunctionName( sFuncName );
+		}
+		iLocation = s.find_first_of( ':' );
+
+		//Filename and location
+
+		if(iLocation != string::npos )
+		{
+			s2 = s.substr( 0, iLocation );
+			result->SetFileName( s2 );
+			s.erase( 0, iLocation+1 );
+		}
+
+		//Exact line number
+
+		s2 = s.substr( 0, s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN ) );
+		result->SetExactLineNumber( atoi( s2.c_str() ) );
+	}
+	return true;
+}
+
+bool CATAddr2line::ReadMapFileArmv5()
+{
+	LOG_FUNC_ENTRY("CATModule2::ReadMapFileArmv5");
+	// Open .map file
+	ifstream in( m_sMapFileName.c_str() );
+	// File open ok?
+	if( ! in.good() )
+	{
+		in.close();
+		return false;
+	}
+	char cTemp[MAX_LINE_LENGTH];
+	bool bFirstFuncFound = false;
+	bool bFirstLine = true;
+	// Get all lines where is "Thumb"
+	do
+	{
+		// Load one line from .map file
+		in.getline( cTemp, MAX_LINE_LENGTH );
+		if( bFirstLine )
+		{
+			bFirstLine = false;
+			if( strstr( cTemp, "ARM Linker" ) == NULL )
+				return false;
+		}
+		// Find _E32Startup
+		if( !bFirstFuncFound && ( strstr( cTemp, "_E32Startup" ) != NULL) )
+		{
+			bFirstFuncFound = true;
+		}
+		else if( !bFirstFuncFound && ( strstr( cTemp, "_E32Dll" ) != NULL) )
+		{
+			bFirstFuncFound = true;
+		}
+		else if( !bFirstFuncFound )
+			// Skip if _E32Startup not found
+			continue;
+
+		if( strstr( cTemp, "Thumb Code" ) != NULL || strstr( cTemp, "ARM Code" ) != NULL)
+		{
+			MAP_FUNC_INFO structMapFileLineInfo;
+			structMapFileLineInfo.sWholeLine.append( cTemp );
+
+			// Get memory string address from line
+			char* pStart = strstr( cTemp, "0x" );
+			// Check did strstr return null.
+			if ( pStart == NULL )
+				continue;
+			char* pTemp = pStart;
+			char TempString[MAX_LINE_LENGTH];
+			TempString[0] = 0;
+			size_t iLength = 0;
+			while( *pTemp != ' ' )
+			{
+				TempString[iLength] = *pTemp;
+				pTemp++;
+				iLength++;
+			}
+			TempString[iLength] = 0;
+
+			structMapFileLineInfo.iAddress = CATDatParser::_httoi( TempString );
+
+			pTemp = cTemp;
+			TempString[0] = 0;
+			
+			// Get function name
+
+			// Skip spaces
+			while( *pTemp == ' ' )
+			{
+				pTemp++;
+			}
+			iLength = 0;
+			// Find end of function name
+			string sTemp( pTemp );
+
+			// Location of character ')'
+			iLength = sTemp.find_first_of(')');
+
+			// Location of character ' '
+			size_t iLength2 = sTemp.find_first_of(' ');
+			
+			// If ')' character is the last char and
+			// character ' ' is closer than ')' use location of ' '
+			if( ( iLength + 1 ) == sTemp.length() && iLength2 < iLength )
+				iLength = iLength2 - 1;
+			
+			if( iLength != string::npos )
+				sTemp.resize( (iLength + 1) );
+
+			structMapFileLineInfo.sFunctionName.append( sTemp.c_str() );
+
+			bool bARM = false;
+			// Find function length
+			pStart = strstr( cTemp, "Thumb Code" );
+			if( pStart == NULL )
+			{
+				pStart = strstr( cTemp, "ARM Code" );
+				bARM = true;
+			}
+			if( pStart != NULL )
+			{
+				if( bARM )
+					pStart += 8;
+				else
+					pStart += 10;
+				while(*pStart == ' ')
+				{
+					pStart++;
+				}
+				sTemp.clear();
+				sTemp.append( pStart );
+				size_t iSize = sTemp.find_first_of(' ');
+				if( iSize != string::npos )
+					sTemp.resize( iSize );
+			}
+
+			structMapFileLineInfo.iFuncLength = atoi( sTemp.c_str() );
+			if( bFirstFuncFound && structMapFileLineInfo.iFuncLength > 0 )
+				// Save to list
+				m_vMapFileFuncList.push_back( structMapFileLineInfo );
+		}
+	}
+	while( in.good() );
+	in.close();
+	return true;
+}
+
+// Find function name of given address
+string CATAddr2line::GetFunctionNameUsingAddress( unsigned long iAddress )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2line::GetSymbolIndexUsingAddress");
+	string sRet;
+	for( size_t i = 0; i < m_vMapFileFuncList.size(); i++ )
+	{
+		unsigned long iStart = m_vMapFileFuncList.at( i ).iAddress;
+		unsigned long iEnd = ( m_vMapFileFuncList.at( i ).iAddress
+			+ m_vMapFileFuncList.at( i ).iFuncLength );
+
+		if ( iAddress >= iStart && iAddress < iEnd )
+			return m_vMapFileFuncList.at( i ).sFunctionName;
+	}
+	return sRet;
+}
+
+//Note: New filtering functions commented out until they are taken into use.
+/**
+* Filter string out of unwanted characters.
+*/
+/*
+void CATAddr2line::FilterString( string &sString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2line::FilterString");
+	string sFiltered("");
+	for( size_t i = 0 ; i < sString.length() ; i++ )
+	{
+		const char p = sString.at( i );
+		if ( p != 0 && strchr( ADDR2LINEALLOWEDCHARS, p ) != 0 )
+			sFiltered.push_back( p );
+	}
+	sString = sFiltered;
+}
+*/
+/**
+* Find line feed position from string.
+*/
+/*
+size_t CATAddr2line::FindLineFeed( const string& sString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2line::FindLineFeed");
+	size_t iLineFeed1 = sString.find( 12 );
+	size_t iLineFeed2 = sString.find( 15 );
+	if ( iLineFeed1 < iLineFeed2 && iLineFeed1 != string::npos )
+		return iLineFeed1;
+	else if ( iLineFeed2 != string::npos )
+		return iLineFeed2;
+	else
+		return string::npos;
+}
+*/
+/**
+* Erase characters from start of the string until other char than linefeed found.
+*/
+/*
+void CATAddr2line::EraseUntilNoLineFeed( string& sString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2line::EraseUntilNoLineFeed");
+	for ( size_t i = 0 ; i < sString.length() ; i++ )
+	{
+		if ( sString.at( i ) != 15 && sString.at( i ) != 12 )
+			break;
+	}
+	sString.erase( 0, i );
+}
+*/
+/**
+* Split multiple line string with unexpected line feeds to vector of strings.
+*/
+/*
+vector<string> CATAddr2line::SplitToStrings( string& sMultiLineString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2line::SplitToStrings");
+    vector<string> vLines;
+	while ( 1 )
+	{
+		size_t iLineFeed = FindLineFeed( sMultiLineString );
+		if ( iLineFeed == string::npos )
+			break;
+		string sCell = sMultiLineString.substr(0, iLineFeed );
+		sMultiLineString.erase(0, iLineFeed );
+		EraseUntilNoLineFeed( sMultiLineString );
+		FilterString( sCell );
+		vLines.push_back( sCell );
+	}
+	// If no lines were found set single one.
+	if ( vLines.size() == 0 )
+		vLines.push_back( sMultiLineString );
+	return vLines;
+}
+*/
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/cataddr2lineserver.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class representing a server that uses addr2line.exe.
+*
+*/
+
+#include "../inc/cataddr2lineserver.h"
+#include "../inc/CATBase.h"
+
+// ----------------------------------------------------------------------------
+// Constructor
+// ----------------------------------------------------------------------------
+CATAddr2lineServer::CATAddr2lineServer()
+{
+	LOG_FUNC_ENTRY("CATAddr2lineServer::CATAddr2lineServer");
+	m_bProcessCreated = false;
+
+	// Pipe handles.
+	m_hChildErroutRd = 0;
+	m_hChildErroutRdDup = 0;
+	m_hChildErroutWr = 0;
+	m_hChildStdinRd = 0;
+	m_hChildStdinWr = 0;
+	m_hChildStdinWrDup = 0;
+	m_hChildStdoutRd = 0;
+	m_hChildStdoutWr = 0;
+	m_hChildStdoutRdDup = 0;
+	
+	m_hSaveErrout = 0;
+	m_hSaveStdin = 0;
+	m_hSaveStdout = 0;
+
+    // Set the bInheritHandle flag so pipe handles are inherited.
+    m_saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    m_saAttr.bInheritHandle = TRUE;
+    m_saAttr.lpSecurityDescriptor = NULL;
+
+	// Symbol file.
+	m_sFullPathAndBinaryName = "";
+}
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+CATAddr2lineServer::~CATAddr2lineServer()
+{
+	LOG_FUNC_ENTRY("CATAddr2lineServer::~CATAddr2lineServer");
+	// Close the pipe handle so the child process stops reading.
+    CloseHandle(m_hChildStdinWrDup);
+    // Close the write end of the pipe
+    CloseHandle(m_hChildStdoutWr);
+    // Close the write end of the error pipe
+	CloseHandle(m_hChildErroutWr);
+}
+bool CATAddr2lineServer::Initialize( const string& sFullPathAndBinaryName )
+{
+    LOG_FUNC_ENTRY("CATAddr2lineServer::Initialize");
+	BOOL fSuccess;
+	m_sFullPathAndBinaryName = sFullPathAndBinaryName;
+
+    // The steps for redirecting child process's STDOUT:
+    //     1. Save current STDOUT, to be restored later.
+    //     2. Create anonymous pipe to be STDOUT for child process.
+    //     3. Set STDOUT of the parent process to be write handle to
+    //        the pipe, so it is inherited by the child process.
+    //     4. Create a noninheritable duplicate of the read handle and
+    //        close the inheritable read handle.
+ 
+    // Save the handle to the current STDOUT. 
+    m_hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+
+    // Create a pipe for the child process's STDOUT.
+    if (! CreatePipe(&m_hChildStdoutRd, &m_hChildStdoutWr, &m_saAttr, 0))
+		return PrintErrorAndExit( "Stdout pipe creation failed\n" );
+
+    // Set a write handle to the pipe to be STDOUT.
+   if (! SetStdHandle(STD_OUTPUT_HANDLE, m_hChildStdoutWr))
+		return PrintErrorAndExit( "Redirecting STDOUT failed\n" );
+
+    // Create noninheritable read handle and close the inheritable read
+    // handle.
+    fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildStdoutRd,
+        GetCurrentProcess(), &m_hChildStdoutRdDup , 0,
+        FALSE,
+        DUPLICATE_SAME_ACCESS);
+    if( !fSuccess )
+		return PrintErrorAndExit( "DuplicateHandle failed" );
+    CloseHandle(m_hChildStdoutRd);
+
+    // The steps for redirecting child process's STDIN:
+    //     1.  Save current STDIN, to be restored later.
+    //     2.  Create anonymous pipe to be STDIN for child process.
+    //     3.  Set STDIN of the parent to be the read handle to the
+    //         pipe, so it is inherited by the child process.
+    //     4.  Create a noninheritable duplicate of the write handle,
+    //         and close the inheritable write handle.
+ 
+    // Save the handle to the current STDIN.
+    m_hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
+
+    // Create a pipe for the child process's STDIN.
+    if (! CreatePipe(&m_hChildStdinRd, &m_hChildStdinWr, &m_saAttr, 0))
+		return PrintErrorAndExit( "Stdin pipe creation failed\n" );
+ 
+    // Set a read handle to the pipe to be STDIN. 
+    if (! SetStdHandle(STD_INPUT_HANDLE, m_hChildStdinRd)) 
+		return PrintErrorAndExit( "Redirecting Stdin failed\n" ); 
+ 
+    // Duplicate the write handle to the pipe so it is not inherited. 
+	
+    fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildStdinWr, 
+        GetCurrentProcess(), &m_hChildStdinWrDup, 0, 
+        FALSE,                  // not inherited 
+        DUPLICATE_SAME_ACCESS); 
+    if (! fSuccess) 
+		return PrintErrorAndExit( "DuplicateHandle failed\n" );
+
+    CloseHandle(m_hChildStdinWr);
+ 
+    // The steps for redirecting child process's ERROUT:
+    //     1. Save current STDOUT, to be restored later.
+    //     2. Create anonymous pipe to be STDOUT for child process.
+    //     3. Set STDOUT of the parent process to be write handle to
+    //        the pipe, so it is inherited by the child process.
+    //     4. Create a noninheritable duplicate of the read handle and
+    //        close the inheritable read handle.
+ 
+    // Save the handle to the current STDOUT. 
+    m_hSaveErrout = GetStdHandle( STD_ERROR_HANDLE ); 
+
+    // Create a pipe for the child process's ERROUT.
+    if (! CreatePipe(&m_hChildErroutRd, &m_hChildErroutWr, &m_saAttr, 0))
+		return PrintErrorAndExit( "Errout pipe creation failed\n" );
+
+    // Set a write handle to the pipe to be ERROUT.
+   if (! SetStdHandle(STD_ERROR_HANDLE, m_hChildErroutWr))
+		return PrintErrorAndExit( "Redirecting ERROUT failed\n" );
+
+    // Create noninheritable read handle and close the inheritable read
+    // handle.
+   
+    fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildErroutRd,
+        GetCurrentProcess(), &m_hChildErroutRdDup , 0,
+        FALSE,
+        DUPLICATE_SAME_ACCESS);
+    if( !fSuccess )
+		return PrintErrorAndExit( "DuplicateHandle failed" );
+    
+	CloseHandle(m_hChildErroutRd);
+	CloseHandle(m_hChildErroutRdDup);
+	
+	// Now create the child process. 
+    fSuccess = CreateChildProcess();
+    if (!fSuccess )
+		return PrintErrorAndExit( "Create process failed\n" );
+ 
+    // After process creation, restore the saved STDIN and STDOUT.
+	if (! SetStdHandle(STD_INPUT_HANDLE, m_hSaveStdin))
+        return PrintErrorAndExit( "Re-redirecting Stdin failed\n" );
+
+	if (! SetStdHandle(STD_OUTPUT_HANDLE, m_hSaveStdout))
+       return PrintErrorAndExit( "Re-redirecting Stdout failed\n" );
+
+	if (! SetStdHandle(STD_ERROR_HANDLE, m_hSaveErrout))
+       return PrintErrorAndExit( "Re-redirecting Stderrout failed\n" );
+
+	m_bProcessCreated = true;
+    return true;
+}
+BOOL CATAddr2lineServer::CreateChildProcess() 
+{ 
+    LOG_FUNC_ENTRY("CATAddr2lineServer::CreateChildProcess");
+    PROCESS_INFORMATION piProcInfo; 
+    STARTUPINFO siStartInfo;
+    BOOL bFuncRetn = FALSE; 
+ 
+    // Set up members of the PROCESS_INFORMATION structure.
+    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
+ 
+	// Set up members of the STARTUPINFO structure.
+    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
+    siStartInfo.cb = sizeof(STARTUPINFO); 
+ 
+	//atool.exe:s path + filename
+	char buffer[MAX_PATH];
+
+	GetModuleFileName( NULL, buffer, MAX_PATH );
+
+	string sCommand( buffer );
+
+	//Remove 'atool.exe'
+	size_t tPos = sCommand.rfind( "\\" );
+	if ( tPos != string::npos )
+		sCommand.resize( sCommand.rfind( "\\" )+1 );
+	else
+		sCommand.clear();
+
+	sCommand.append( "addr2line.exe" );
+
+	//addr2line file exists
+	if( !CATBase::FileExists( sCommand.c_str() ) )
+		return PrintErrorAndExit( "File not found addr2line.exe\n" );
+
+	//Sym file exists
+	if( !CATBase::FileExists( m_sFullPathAndBinaryName.c_str() ) )
+	{
+		string sTemp( "File not found " );
+		sTemp.append( m_sFullPathAndBinaryName );
+		sTemp.append( "\n" );
+		return PrintErrorAndExit( sTemp );
+	}
+
+	sCommand.append(" -f -C -e ");
+	sCommand.append( m_sFullPathAndBinaryName );
+
+	// Create the child process. 
+    bFuncRetn = CreateProcess(NULL,
+		(LPSTR)sCommand.c_str(), // command line
+        NULL,          // process security attributes
+        NULL,          // primary thread security attributes
+        TRUE,          // handles are inherited
+        0,             // creation flags
+        NULL,          // use parent's environment
+        NULL,          // use parent's current directory
+        &siStartInfo,  // STARTUPINFO pointer
+        &piProcInfo);  // receives PROCESS_INFORMATION
+
+    if (bFuncRetn == 0)
+    {
+       //CreateProcess failed
+       return false;
+    }
+    else
+    {
+       CloseHandle(piProcInfo.hProcess);
+       CloseHandle(piProcInfo.hThread);
+       return bFuncRetn;
+    }
+}
+VOID CATAddr2lineServer::WriteToPipe( const string& sAddress ) 
+{ 
+	LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::WriteToPipe");
+    DWORD dwRead, dwWritten;
+    CHAR chBuf[2]; //This is for enter key
+
+    //Write data to a pipe. 
+    dwRead = (DWORD)sAddress.length();
+	WriteFile(m_hChildStdinWrDup, sAddress.c_str(), dwRead, &dwWritten, NULL);
+
+	chBuf[0] = 0x0A; //Enter
+	chBuf[1] = 0; //NULL
+	//Write enter key to a pipe
+	WriteFile(m_hChildStdinWrDup, chBuf, 1, &dwWritten, NULL);
+} 
+string CATAddr2lineServer::ReadFromPipe(VOID) 
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::ReadFromPipe");
+	string s;
+	DWORD dwRead;
+    CHAR chBuf[BUFSIZE];
+    // Read output from the child process, and save data to string.
+    ReadFile( m_hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL);
+	s.append( chBuf );
+    return s;
+}
+bool CATAddr2lineServer::GetProcessCreatedState( void )
+{
+	LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::GetProcessCreatedState");
+	return m_bProcessCreated;
+}
+bool CATAddr2lineServer::PrintErrorAndExit( const string sInput )
+{
+	LOG_FUNC_ENTRY("CATAddr2lineServer::PrintErrorAndExit");
+	cout << AT_MSG << sInput;
+	return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catalloc.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catalloc.h"
+
+string CATAlloc::GetAllocString( void )
+{
+	LOG_LOW_FUNC_ENTRY("CATAlloc::GetAllocString");
+	// Create alloc string
+	string sLine("");
+	sLine.append( m_sTime ); sLine.append(" " );
+	sLine.append( m_sSize );
+
+	// Add all call stack fragments to line.
+	string sCallStack;
+	map<unsigned long, string>::iterator it;
+	for( it = m_vCallStack.begin() ; it != m_vCallStack.end() ; it++ )
+	{
+		sCallStack.append( (*it).second );
+		sCallStack.append( " " );
+	}
+	// Remove the last space
+	if ( sCallStack.size() > 0 )
+		sCallStack.erase( sCallStack.size()-1, 1 );
+	
+	if ( m_iCSCount != 0 )
+	{
+		// Check integrity (calculate number of spaces in call stack)
+		unsigned long iCount = 0;
+		size_t pos = 0;
+		while ( pos != string::npos )
+		{
+			iCount++;
+			pos = sCallStack.find_first_of( ' ', pos+1 );
+		}
+		if ( iCount != m_iCSCount )
+			cout << AT_MSG << "Error, integrity check failed in alloc." << endl;
+	}
+
+	// Add call stack to line.
+	if ( sCallStack.size() > 0 )
+	{
+		sLine.append(" " );
+		sLine.append( sCallStack );
+	}
+
+	// return alloc line.
+	return sLine;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catallocs.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catallocs.h"
+
+void CATAllocs::Alloc( const string& sAllocString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::Alloc");
+	string sAlloc( sAllocString );
+	CATAlloc alloc;
+	string sAddress = GetStringUntilNextSpace( sAlloc, true );
+	alloc.m_sTime = GetStringUntilNextSpace( sAlloc, true );
+	alloc.m_sSize = GetStringUntilNextSpace( sAlloc, true );
+	alloc.m_vCallStack.insert( pair<unsigned long,string>(1, sAlloc) );
+	// Add allocation
+	pair< map<string,CATAlloc>::iterator, bool> ret;
+	ret = m_vAllocs.insert( pair<string, CATAlloc>( sAddress, alloc ) );
+	if( ret.second == false )
+	{
+		// Allocation to this memory address was already added.
+		LOG_STRING( "CATAllocs: Allocating same address again, address: " << sAddress );
+	}
+}
+
+void CATAllocs::AllocH( const string& sAllocHString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::AllocH");
+	string sAllocH( sAllocHString );
+	// Parse alloc & create new allocation.
+	CATAlloc alloc;
+	string sAddress = GetStringUntilNextSpace( sAllocH, true );
+	alloc.m_sTime = GetStringUntilNextSpace( sAllocH, true );
+	alloc.m_sSize = GetStringUntilNextSpace( sAllocH, true );
+	alloc.m_iCSCount = _httoi( string( GetStringUntilNextSpace( sAllocH, true ) ).c_str() );
+	// Insert call stack fragment as "first" 1 because we are header.
+	if ( alloc.m_iCSCount > 0 )
+		alloc.m_vCallStack.insert( pair<unsigned long,string>( 0, sAllocH ) );
+	// Add allocation
+	pair< map<string,CATAlloc>::iterator, bool> ret;
+	ret = m_vAllocs.insert( pair<string, CATAlloc>( sAddress, alloc ) );
+	if( ret.second == false )
+	{
+		// Allocation to this memory address was already added.
+		LOG_STRING( "CATAllocs: Allocating same address again, address: " << sAddress );
+	}
+}
+
+void CATAllocs::AllocF( const string& sAllocFString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::AllocF");
+	string sAllocF( sAllocFString );
+	string sAddress = GetStringUntilNextSpace( sAllocF, true );
+	string sTime = GetStringUntilNextSpace( sAllocF, true );
+	unsigned long iNumber = _httoi( string( GetStringUntilNextSpace( sAllocF, true ) ).c_str() );
+	string sCallSstack = sAllocF;
+	// Find correct allocation into which add call stack fragment.
+	map<string, CATAlloc>::iterator it;
+	it = m_vAllocs.find( sAddress );
+	// TODO: If cannot find, create new in cache.
+	if ( it == m_vAllocs.end() )
+	{
+		LOG_STRING( "CATAllocs: Allocate fragment without header: " << sAddress );
+		return;
+	}
+	pair< map<unsigned long,string>::iterator, bool> ret;
+	// Add call stack to it.
+	ret = it->second.m_vCallStack.insert( pair<unsigned long,string>( iNumber, sCallSstack ) );
+	if( ret.second == false )
+	{
+		LOG_STRING( "CATAllocs: Same allocation fragment again: " << sAddress );
+	}
+}
+
+// Free message.
+void CATAllocs::Free( const string& sFreeString )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::Free");
+	string sFree( sFreeString );
+	string sKey = GetStringUntilNextSpace( sFree );
+	// Find related allocation.
+	map<string, CATAlloc>::iterator it;
+	it = m_vAllocs.find( sKey );
+	if ( it == m_vAllocs.end() )
+	{
+		LOG_STRING( "CATAllocs: Free message which has no alloc pair: " << sKey );
+		return;
+	}
+	// Delete it.
+	m_vAllocs.erase( it );
+}
+
+// FreeH.
+void CATAllocs::FreeH( const string& sFreeH )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::FreeH");
+	// Current implementation does not use call stack of
+	// free message to anything.
+	string sFree( sFreeH );
+	string sKey = GetStringUntilNextSpace( sFree );
+	// Time stamp. (not used currently)
+	// Call stack count. (not used currently)
+	// Call stack data. (not used currently)
+
+	// Find related allocation.
+	map<string, CATAlloc>::iterator it;
+	it = m_vAllocs.find( sKey );
+	if ( it == m_vAllocs.end() )
+	{
+		LOG_STRING( "CATAllocs: FreeH message which has no alloc pair: " << sKey );
+		return;
+	}
+	// Delete it.
+	m_vAllocs.erase( it );
+}
+
+// FreeF.
+void CATAllocs::FreeF( const string& /* sFreeF */ )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::FreeF");
+	// Fragments are currently ignored.
+	// Memory address. (not used currently)
+	// Time stamp. (not used currently)
+	// Packet number. (not used currently)
+	// Call stack data. (not used currently)
+}
+
+// Get "leak" list ordered by allocation time.
+void CATAllocs::GetLeakList( vector<string>& vLeakList )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::GetLeakList");
+
+	// Create multimap where key is timestamp.
+	// Add allocations there so they will go ascending order.
+	multimap<string,string> mmap;
+	multimap<string,string>::iterator itMmap;
+	
+	map<string, CATAlloc>::iterator it;
+	for( it = m_vAllocs.begin(); it != m_vAllocs.end() ; it++ )
+	{
+		string sTime = it->second.m_sTime;
+		
+		string sLine = it->first;
+		sLine.append(" ");
+		sLine.append( it->second.GetAllocString() );
+
+		mmap.insert( pair<string,string>( sTime, sLine ) );
+	}
+	
+	// Iterate list to parameter vector.
+	vLeakList.clear();
+	for ( itMmap = mmap.begin(); itMmap != mmap.end(); itMmap++ )
+		vLeakList.push_back( itMmap->second );
+}
+
+// Clear alloc data.
+void CATAllocs::ClearAllocs( void )
+{
+	LOG_LOW_FUNC_ENTRY("CATAllocs::ClearAllocs");
+	m_vAllocs.clear();
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catdbghelper.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Windows debug api implementation for IAddressToLine interface.
+*
+*/
+
+#include "../inc/catdbghelper.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATMemoryAddress.h"
+#include <dbghelp.h>
+
+/**
+* Notes on version number of api functions.
+* 5.1	Windows XP
+* 5.2	Windows Server 2003
+* 6.8	Debugging Tools for Windows 6.8
+* SymSetOptions			DbgHelp.dll 5.1 or later
+* SymSetSearchPath		DbgHelp.dll 5.1 or later
+* SymLoadModuleEx			Versions 5.2 and 6.0
+* SymLoadModule64			DbgHelp.dll 5.1 or later
+* SymFromAddr				Versions 4.0 and 5.1
+* SymGetLineFromAddr64	DbgHelp.dll 5.1 or later
+*/
+
+// Wrapper class for symbol information package.
+struct CSymbolInfo : public SYMBOL_INFO_PACKAGE
+{
+	CSymbolInfo()
+	{
+		si.SizeOfStruct = sizeof( SYMBOL_INFO );
+		si.MaxNameLen = sizeof( name );
+	}
+};
+
+// Wrapper class for line information container.
+struct CLineInfo : public IMAGEHLP_LINE64
+{
+	CLineInfo()
+	{
+		SizeOfStruct = sizeof( IMAGEHLP_LINE64 );
+	}
+};
+
+CATDbgHelper::CATDbgHelper()
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::CDbgHelper");
+	// Set the some "default" base address.
+	m_BaseAddress = 0x2;
+	m_bMap = false;
+	m_pBinaryFile = NULL;
+}
+
+CATDbgHelper::~CATDbgHelper()
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::~CDbgHelper");
+	// Close dbghelper only once.
+	if ( CDBGHELPER_OPEN )
+	{
+		Close();
+	}
+	if ( m_pBinaryFile )
+	{
+		delete[] m_pBinaryFile;
+		m_pBinaryFile = NULL;
+	}
+}
+
+bool CATDbgHelper::Open( const string& sParameter, const unsigned long iLong )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::Open");
+	// Verify that file exits. Version 5.1.2600.5512 of dbghelp.dll does not correctly
+	// return error code if missing image file. This can lead upto applicaton crash.
+	if ( ! CATBase::FileExists( sParameter.c_str() ) )
+	{
+		LOG_STRING( "Missing image file: " << sParameter );
+		return false;
+	}
+
+	// Is it urel try read map?
+	if ( sParameter.find( "\\urel\\" ) != string::npos )
+	{
+		string sMapFile = sParameter;
+		sMapFile.append( ".map" );
+		ReadMapFile( sMapFile );
+	}
+
+	// Set base address used
+	m_BaseAddress = iLong + AT_VIRTUAL_OFFSET_DBGHELPER;
+	// Binary file (also referred as symbol).
+	size_t length = sParameter.length();
+	if ( length == 0 )
+	{
+		LOG_STRING("DbgHelp:Invalid binary parameter.");
+		return false;
+	}
+
+	char* pChar = new char[ sParameter.length()+1 ];
+	strcpy( pChar, sParameter.c_str() );
+	// Have to be casted to PSTR before using dbg api. Even tho its typedef same.
+	// This will avoid access violations bug.
+	// Note pChar is not deleted because its the member pointer just casted its
+	// memory allocation freed in destructor.
+	if ( m_pBinaryFile )
+		delete[] m_pBinaryFile;
+
+	m_pBinaryFile = (PSTR) pChar;
+
+	// Initialize dbghelper if not done only once.
+	if ( ! CDBGHELPER_OPEN )
+	{
+		// Set symbol options
+		SymSetOptions( SYMOPT_LOAD_LINES | SYMOPT_DEBUG | SYMOPT_UNDNAME | SYMOPT_LOAD_ANYTHING );
+		if ( !SymInitialize( GetCurrentProcess(), NULL, TRUE ) )
+		{
+			LOG_STRING("DbgHelp:Error initializing dbghelper " << (int) GetLastError());
+			return false;
+		}
+		LOG_STRING("DbgHelp:dbghelper opened.");
+		CDBGHELPER_OPEN = true;
+	}
+
+	// Set symbol search path.
+	if ( !SymSetSearchPath( GetCurrentProcess(), NULL ) )
+	{
+		LOG_STRING("DbgHelp:Error setting symbol search path " << (int) GetLastError());
+		return false;
+	}
+
+	// Load module.
+	DWORD64 ret;
+	ret = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); // 5.1 api version.
+	if ( ret != m_BaseAddress  && ret != 0)
+	{
+		LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError());
+		return false;
+	}
+	CDBGHELPER_CLIENTS++;
+	return true;
+}
+
+string CATDbgHelper::GetError( void )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::GetError");
+	return string("not implemented.");
+}
+
+bool CATDbgHelper::Close( void )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::Close");
+	if ( ! SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) )
+	{
+		LOG_STRING("Dbghelp:Module unload failed.");
+	}
+	CDBGHELPER_CLIENTS--;
+	if ( CDBGHELPER_OPEN && CDBGHELPER_CLIENTS == 0)
+	{
+		// Cleanup dbghelper.
+		if ( ! SymCleanup( GetCurrentProcess() ) )
+		{
+			LOG_STRING("dbghelper cleanup failed.");
+			return false;
+		}
+		LOG_STRING("dbghelper closed.");
+		// Set state not opened.
+		CDBGHELPER_OPEN = false;
+	}
+	return true;
+}
+
+bool CATDbgHelper::AddressToLine( CATMemoryAddress* result )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::AddressToLine");
+	
+	// Set state out of range
+	result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE );
+
+	// check that dbghelper has been initialized successfully.
+	if ( ! CDBGHELPER_OPEN )
+		return false;
+
+	// Check has binary been moved, if so unload and load to new base address.
+	if ( result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER != m_BaseAddress )
+	{
+		// Unload.
+		if ( SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) )
+		{
+			// Set new base address.
+			m_BaseAddress = result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER;
+			// (Re)load.
+			DWORD64 loading = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL );
+			if ( loading != m_BaseAddress  && loading != 0)	
+			{
+				LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError());
+				return false;
+			}
+		}
+		else
+			LOG_STRING("Dbghelp:Module unload failed " << (int) GetLastError() );
+	}
+	// Address to find (offset+given address).
+	unsigned long iAddressToFind = result->GetAddress() + AT_VIRTUAL_OFFSET_DBGHELPER;
+	// Displacements of line/symbol information.
+	DWORD64 displacementSymbol;
+	DWORD displacementLine;
+	// Structure to get symbol information.
+	CSymbolInfo symbol;
+	// Structure to get line information.
+	CLineInfo line;
+	// Find Symbol for given address 
+	if( ! SymFromAddr( GetCurrentProcess(), iAddressToFind , &displacementSymbol, &symbol.si ) )
+	{
+		LOG_STRING("Failed to find symbol information for given line.");
+		return AddressToFunction( result );
+	}
+	// Find line information
+	if( ! SymGetLineFromAddr64( GetCurrentProcess(), iAddressToFind, &displacementLine, &line ) )
+	{
+		// If it fails get symbol line information
+		LOG_STRING("Dbghelp:Failed to find line information for address, trying for symbol of address.");
+		if( ! SymGetLineFromAddr64( GetCurrentProcess(), symbol.si.Address, &displacementLine, &line ) )
+		{
+			LOG_STRING("Dbghelp:Failed to find line information for symbol address.");
+			return AddressToFunction( result );
+		}
+	}
+	// Set the results.
+	result->SetFileName( string( line.FileName ) );
+	result->SetFunctionName( string( symbol.si.Name ) );
+	result->SetExactLineNumber( (int) line.LineNumber );
+	result->SetAddressToLineState( CATMemoryAddress::EXACT );
+	// Return.
+	return true;
+}
+
+bool CATDbgHelper::AddressToFunction( CATMemoryAddress* result )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::AddressToFunction");
+	bool bFound = false;
+	// If map file read use it and return.
+	if ( m_bMap )
+	{
+		ULONG uCountedA = result->GetOffSetFromModuleStart();
+		for ( vector<MAP_FUNC_INFO>::iterator it = m_vMapFileFuncList.begin() ; it != m_vMapFileFuncList.end() ; it++ )
+		{
+			// Check is this the symbol where address is.
+			unsigned long iStart = it->iAddress;
+			unsigned long iEnd = it->iAddress + it->iFuncLength;
+			if ( uCountedA >= iStart 
+				&& uCountedA < iEnd )
+			{
+				result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+				result->SetFunctionName( it->sMangledName );
+				bFound = true;
+				break;
+			}
+		}
+	}
+	return bFound;
+}
+
+void CATDbgHelper::ReadMapFile( const string sMapFileName )
+{
+	LOG_FUNC_ENTRY("CATDbgHelper::ReadMapFile");
+	try {
+		ifstream in( sMapFileName.c_str() );
+		if ( ! in.good() )
+		{
+			in.close();
+			return;
+		}
+		char cLine[MAX_LINE_LENGTH];
+		do {
+			in.getline( cLine, MAX_LINE_LENGTH );
+			// Search pattern for 'image ro' symbols is ".text"
+			string sLine( cLine );
+			if ( sLine.find( ".text" ) != string::npos )
+			{
+				MAP_FUNC_INFO symbol;
+				// Pickup symbol attributes
+				// Address
+				string sAddress = CATBase::GetStringUntilNextSpace( sLine, true );
+				symbol.iAddress = CATBase::_httoi( sAddress.c_str() );
+				// Lenght
+				string sLength = CATBase::GetStringUntilNextSpace( sLine, true );
+				symbol.iFuncLength = CATBase::_httoi( sLength.c_str() );
+				// Name
+				size_t iStart = sLine.find_first_of( '(' );
+				size_t iEnd = sLine.find_last_of( ')' );
+				if ( iStart != string::npos && iEnd != string::npos )
+				{
+					symbol.sMangledName = sLine.substr( iStart+1, iEnd-iStart-1 );
+					// Add symbol to vector
+					m_vMapFileFuncList.push_back( symbol );
+				}
+			}
+		} while ( in.good() );
+		in.close();
+		m_bMap = true;
+	} catch (...) {
+		m_bMap = false;
+		LOG_STRING("DbgHelp: Error reading map file.");
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catfilereader.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Class for reading ascii files in AnalyzeTool.
+*
+*/
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catfilereader.h"
+
+// -----------------------------------------------------------------------------
+// CATFileReader::CATFileReader
+// Constructor.
+// -----------------------------------------------------------------------------
+CATFileReader::CATFileReader()
+{
+	LOG_FUNC_ENTRY("CATFileReader::CATFileReader");
+	m_cDelimiter = '\r'; // default line delimeter
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::~CATFileReader
+// Destructor.
+// -----------------------------------------------------------------------------
+CATFileReader::~CATFileReader()
+{
+	LOG_FUNC_ENTRY("CATFileReader::~CATFileReader");
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::Open
+// Open / Read file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::Open( const char* cFile )
+{
+	LOG_FUNC_ENTRY("CATFileReader::Open");
+	if ( strlen( cFile ) < 1 )
+	{
+		LOG_STRING("CATFileReader::Open empty file argument.");
+		return false;
+	}
+	try {
+		ifstream in;
+		in.open( cFile, ios::binary );
+		if ( ! in.good() )
+			return false;
+		m_stream << in.rdbuf();
+		in.close();
+	}
+	catch(...)
+	{
+		LOG_STRING("CATFileReader::Open unhandled exception.");
+		return false;
+	}
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::Close
+// Close file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::Close( void )
+{
+	LOG_FUNC_ENTRY("CATFileReader::Close");
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::GetLine
+// Get line from file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::GetLine( string& sLine )
+{
+	//LOG_FUNC_ENTRY("CATFileReader::GetLine");
+	char cLine[MAX_LINE_LENGTH];
+	if ( !m_stream.good() )
+		return false;
+	m_stream.getline( cLine, MAX_LINE_LENGTH, m_cDelimiter ); m_stream.get();
+	sLine = cLine;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::SetDelimiter
+// Set line delimiting character.
+// -----------------------------------------------------------------------------
+void CATFileReader::SetDelimiter( char cDelimiter )
+{
+	LOG_FUNC_ENTRY("CATFileReader::SetDelimiter");
+	m_cDelimiter = cDelimiter;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::GetDelimiter
+// Get current line delimiting character.
+// -----------------------------------------------------------------------------
+char CATFileReader::GetDelimiter() const
+{
+	LOG_FUNC_ENTRY("CATFileReader::GetDelimiter()");
+	return m_cDelimiter;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catromsymbol.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,656 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Reads rom symbol file and provides interface to acquire
+*               binary and function information using memory addresss.
+*
+*/
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catromsymbol.h"
+#include "../inc/catfilereader.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATMemoryAddress.h"
+
+// -----------------------------------------------------------------------------
+// RofsBinary::RofsBinary
+// Default construcor
+// -----------------------------------------------------------------------------
+RofsBinary::RofsBinary()
+{
+	LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary");
+	m_sBinary = "";
+	vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// RofsBinary::RofsBinary
+// Construcor
+// -----------------------------------------------------------------------------
+RofsBinary::RofsBinary( const string& sBinary )
+{
+	LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary");
+	m_sBinary = sBinary;
+	vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// RofsBinary::~RofsBinary
+// Destructor
+// -----------------------------------------------------------------------------
+RofsBinary::~RofsBinary()
+{
+	LOG_LOW_FUNC_ENTRY("RofsBinary::~RofsBinary");
+	for ( vector<Symbol*>::iterator it = vSymbols.begin() ; it != vSymbols.end() ; it++ )
+		delete *it;
+	vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::CATRomSymbol
+// Constructor.
+// -----------------------------------------------------------------------------
+CATRomSymbol::CATRomSymbol()
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::CATRomSymbol");
+	m_bSymbolsRead = false;
+	m_iRomEndAddress = 0;
+	m_iRomStartAddress = 0;
+	m_vRomFiles.clear();
+	m_sErrorMessage = "";
+	m_vRomCache.clear();
+	m_vRomSymbols.clear();
+	m_bShowProgressMessages = false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::~CATRomSymbol
+// Destructor.
+// -----------------------------------------------------------------------------
+CATRomSymbol::~CATRomSymbol()
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::~CATRomSymbol");
+	// Rom
+	for ( vector<Symbol*>::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ )
+	{
+		delete *it;
+	}
+	m_vRomSymbols.clear();
+	// Rofs
+	for ( vector<RofsBinary*>::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ )
+	{
+		delete *it;
+	}
+	m_vRofsBinaries.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::Open
+// This funtion should not be used anymore since
+// we support multiple rom/rofs files.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::Open( const string& /*sString*/, const unsigned long /*iLong*/)
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::Open");
+	return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::SetSymbols
+// Set symbol file(s) to be used.
+// This also checks that files exists and identifies them as rom/rofs.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::SetSymbols( const vector<string>& vSymbols )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::SetSymbols");
+	bool ok = true;
+	// Check no same symbol defined twice.
+	for( vector<string>::const_iterator it = vSymbols.begin() ;
+		it != vSymbols.end(); it++ )
+	{
+		for( vector<string>::const_iterator it2 = vSymbols.begin() ;
+			it2 != vSymbols.end(); it2++ )
+		{
+			if ( it == it2 )
+				continue;
+			if ( _stricmp( (*it).c_str(), (*it2).c_str() ) == 0 )
+			{
+				m_sErrorMessage.append( "Same symbol file defined twice (" );
+				m_sErrorMessage.append( (*it) );
+				m_sErrorMessage.append( ")\n" );
+				return false;
+			}
+		}
+	}
+	// Loop given symbol files.
+	for( vector<string>::const_iterator it = vSymbols.begin() ;
+		it != vSymbols.end(); it++ )
+	{
+		// Symbol file exists?
+		if ( ! CATBase::FileExists( (*it).c_str() ) )
+		{
+			ok = false;
+			m_sErrorMessage.append( "Symbol file does not exists (" );
+			m_sErrorMessage.append( *it );
+			m_sErrorMessage.append( ").\n");
+			continue;
+		}
+		// Identify symbol file.
+		int type = IdentifySymbolFile( *it );
+		// Depending on type move it correct vector.
+		switch( type )
+		{
+		case SYMBOL_FILE_INVALID:
+			ok = false;
+			m_sErrorMessage.append( "Symbol file with invalid content (" );
+			m_sErrorMessage.append( *it );
+			m_sErrorMessage.append( ").\n");
+			break;
+		case SYMBOL_FILE_ROM:
+			m_vRomFiles.push_back( *it );
+			break;
+		case SYMBOL_FILE_ROFS:
+			m_vRofsFiles.push_back( *it );
+			break;
+		default:
+			ok = false;
+			LOG_STRING("IdentifySymbolFile returned unknown type.");
+			break;
+		}
+	}
+	if ( ok )
+	{
+		// Read symbols.
+		if ( m_vRomFiles.size() > 0 )
+		{
+			if ( ! ReadRomFiles() )
+				ok = false;
+			else
+				m_bSymbolsRead = true;
+		}
+		if ( m_vRofsFiles.size() > 0 )
+		{
+			if ( ! ReadRofsFiles() )
+				ok = false;
+			else
+				m_bSymbolsRead = true;
+		}
+	}
+	return ok;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::IdentifySymbolFile
+// Identify given file is it rom / rofs.
+// -----------------------------------------------------------------------------
+int CATRomSymbol::IdentifySymbolFile( const string& sFile )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::IdentifySymbolFile");
+	// Set type as invalid.
+	int iType = SYMBOL_FILE_INVALID;
+	// Line counter.
+	int iLineCount = 0;
+	// Minimun line length to identify it.
+	size_t iLineMinLength = MAX_LINE_LENGTH;
+	if ( ROFS_SYMBOL_IDENTIFY_STRING.length() > ROM_SYMBOL_IDENTIFY_STRING.length() )
+		iLineMinLength = ROFS_SYMBOL_IDENTIFY_STRING.length();
+	else
+		iLineMinLength = ROM_SYMBOL_IDENTIFY_STRING.length();
+	try {
+		ifstream in;
+		in.open( sFile.c_str(), ios::in );
+		if ( ! in.good() )
+			return SYMBOL_FILE_INVALID;
+		char cLine[MAX_LINE_LENGTH];
+		do {
+			// Dont read too many lines. (File might be contain invalid data).
+			iLineCount++;
+			if ( iLineCount > IDENTIFY_MAX_LINES_READ )
+				break;
+
+			// Get line -> string.
+			in.getline( cLine, MAX_LINE_LENGTH );
+			string sLine(cLine);
+			
+			// Check its not too short.
+			if( sLine.length() < iLineMinLength )
+				continue;
+
+			// Take substring from start of line to identify it to rofs/rom.
+			if ( ! sLine.substr( 0, ROFS_SYMBOL_IDENTIFY_STRING.length() ).compare( ROFS_SYMBOL_IDENTIFY_STRING ) )
+			{
+				iType = SYMBOL_FILE_ROFS;
+				break;
+			}
+			else if ( ! sLine.substr( 0, ROM_SYMBOL_IDENTIFY_STRING.length() ).compare( ROM_SYMBOL_IDENTIFY_STRING ) )
+			{
+				iType = SYMBOL_FILE_ROM;
+				break;
+			}
+		} while ( in.good() );
+		in.close();
+	}
+	catch(...)
+	{
+		LOG_STRING("CATRomSymbol::IdentifySymbolFile unhandled exception.");
+	}
+	return iType;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRomFiles
+// Reads rom file(s) and creates symbols to vector.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRomFiles()
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::ReadRomFile");
+
+	// Clear symbols.
+	for ( vector<Symbol*>::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ )
+	{
+		delete *it;
+	}
+	m_vRomSymbols.clear();
+	
+	// Clear cache. note cache is just pointers dont delete them.
+	m_vRomCache.clear();
+
+	// Any errors?
+	bool ok = true;
+
+	for( vector<string>::iterator it = m_vRomFiles.begin();
+		it != m_vRomFiles.end() ; it++ )
+		ok = ReadRomFile( *it );
+	
+	// If size smaller than 1 it is not good rom file(s).
+	if ( m_vRomSymbols.size() < 1  || ok != true)
+		return false;
+
+	// Rom start and end addresses.
+	m_iRomStartAddress = (*m_vRomSymbols.begin())->iStartAddress;
+	m_iRomEndAddress = (*m_vRomSymbols.rbegin())->iEndAddress;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRofsFiles
+// Read rofs files.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRofsFiles()
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFiles");
+	// Clear.
+	for ( vector<RofsBinary*>::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ )
+	{
+		delete *it;
+	}
+	m_vRofsBinaries.clear();
+	
+	// Any errors?
+	bool ok = true;
+
+	for( vector<string>::iterator it = m_vRofsFiles.begin();
+		it != m_vRofsFiles.end() ; it++ )
+		ok = ReadRofsFile( *it );
+	
+	// If size smaller than 1 it is not good rofs file(s).
+	if ( m_vRofsBinaries.size() < 1  || ok != true)
+		return false;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRomFile
+// Read given rom file
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRomFile( const string& sFile )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::ReadRomfile");
+	// Open rom file.
+	CATFileReader* reader = new CATFileReader();
+	// Show progress message if flag set.
+	if ( m_bShowProgressMessages )
+		cout << AT_MSG << "Reading rom symbol file: " << sFile << "..." << endl;
+	if ( ! reader->Open( sFile.c_str() ) )
+	{
+		reader->Close();
+		delete reader;
+		return false;
+	}
+
+	// Show progress message if flag set.
+	if ( m_bShowProgressMessages )
+		cout << AT_MSG << "Parsing rom symbol file: " << sFile << "..." << endl;
+
+	// Loop thrue lines.
+	string sLine("");
+	string sBinary("");
+	while( reader->GetLine( sLine ) )
+	{
+		// From rom we just read symbols that have lenght, no need to separate them into diff binaries.
+		try {
+			if ( sLine.size() < 2 )
+			{
+				continue;
+			}
+			else if ( sLine.at(0) == '8' )
+			{
+				// Create new item.
+				Symbol* symbol = new Symbol();
+				ParseSymbolFromLine( sLine, symbol);
+				// Ignore symbols which have same start & end address (zero length).
+				if ( symbol->iStartAddress != symbol->iEndAddress )
+					m_vRomSymbols.push_back( symbol );
+				else
+					delete symbol;
+			}
+		} catch(...)
+		{
+			// Catch all possible exception here so analyze will succeed even rom file invalid.
+			m_sErrorMessage.append( "Unhandled exception parsing rom symbol file.\n" );
+			// Close and delete reader.
+			reader->Close();
+			delete reader;
+			return false;
+		}
+	}
+	// Close and delete reader.
+	reader->Close();
+	delete reader;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRofsFile
+// Read given rofs file
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRofsFile( const string& sFile )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFile");
+	// open/read rofs file.
+	CATFileReader* reader = new CATFileReader();
+	// Show progress message if flag set.
+	if ( m_bShowProgressMessages )
+		cout << AT_MSG << "Reading rofs symbol file: " << sFile << "..." << endl;
+	if ( ! reader->Open( sFile.c_str() ) )
+	{
+		reader->Close();
+		delete reader;
+		return false;
+	}
+
+	// Show progress message if flag set.
+	if ( m_bShowProgressMessages )
+		cout << AT_MSG << "Parsing rofs symbol file: " << sFile << "..." << endl;
+
+	// Loop thrue lines.
+	string sLine("");
+	string sBinary("");
+	RofsBinary* rb = NULL;
+	while( reader->GetLine( sLine ) )
+	{
+		try {
+			if ( sLine.size() < 2 )
+			{
+				continue;
+			}
+			else if ( sLine.at(0) == 'F' )
+			{
+				if ( rb != NULL )
+				{
+					// Check last binary if no symbols in it dont add it.
+					if ( rb->vSymbols.size() == 0 )
+					{
+						delete rb;
+						rb = NULL;
+					}
+					else
+						m_vRofsBinaries.push_back( rb );
+				}
+				// new binary name.
+				size_t i = sLine.rfind("\\");
+				sLine.erase(0, i+1);
+				rb = new RofsBinary( sLine );
+
+			}
+			else if ( sLine.at(0) == '0' )
+			{
+				// Cannot pickup symbols if no binary defined.
+				if ( rb == NULL )
+					continue;
+				// Create new item.
+				Symbol* symbol = new Symbol();
+				ParseSymbolFromLine( sLine, symbol);
+				// Ignore symbols which have same start & end address (zero length).
+				if ( symbol->iStartAddress != symbol->iEndAddress )
+					rb->vSymbols.push_back( symbol );
+				else
+					delete symbol;
+			}
+		} catch(...)
+		{
+			// Catch all possible exception here so analyze will succeed even rofs file invalid.
+			m_sErrorMessage.append( "Unhandled exception parsing rofs symbol file.\n" );
+			// Close and delete reader.
+			reader->Close();
+			delete reader;
+			return false;
+		}
+	}
+	// Last added binary.
+	if ( rb != NULL )
+	{
+		if ( rb->vSymbols.size() == 0 )
+		{
+			delete rb;
+			rb = NULL;
+		}
+		else
+			m_vRofsBinaries.push_back( rb );
+	}
+	// Close and delete reader.
+	reader->Close();
+	delete reader;
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ParseSymbolFromLine
+// Parses given line into given symbol.
+// -----------------------------------------------------------------------------
+void CATRomSymbol::ParseSymbolFromLine( const string& sLine, Symbol* pSymbol )
+{
+	LOG_LOW_FUNC_ENTRY("CATRomSymbol::ParseSymbolFromLine");
+	if ( pSymbol == NULL )
+		return;
+	size_t s,x;
+	string temp;
+	// address.
+	x = sLine.find( ' ' );
+	temp = sLine.substr( 0, x );
+	pSymbol->iStartAddress = CATBase::_httoi( temp.c_str() );
+	// "Erase spaces" move starting point.
+	s = x;
+	s = sLine.find_first_not_of( ' ', s );
+	// length.
+	x = sLine.find( ' ', s );
+	temp = sLine.substr(s,x-s);
+	unsigned long length = CATBase::_httoi( temp.c_str() );
+	pSymbol->iEndAddress = pSymbol->iStartAddress + length;
+	// "Erase spaces" move starting point.
+	s = x;
+	s = sLine.find_first_not_of( ' ', s);
+	// function. Function might have spaces so we find 2 spaces which indicates end of it.
+	x = sLine.find( "  ", s );
+	temp = sLine.substr( s, x-s );
+	pSymbol->sFunction = temp;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::GetError
+// Get error string if error occured in other methods.
+// -----------------------------------------------------------------------------
+string CATRomSymbol::GetError( void )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::GetError");
+	return m_sErrorMessage;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::Close
+// Close (stop using).
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::Close( void )
+{
+	LOG_FUNC_ENTRY("CATRomSymbol::Close");
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLine
+// Try locate binary and function name for given memory address.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLine( CATMemoryAddress* result )
+{
+	LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLine");
+	// Have symbols been read.
+	if ( ! m_bSymbolsRead )
+		return false;
+	// check that its lenght > 2
+	if ( result->GetAddressString().size() < 2 )
+		return false;
+	/* Check first is address in range of rom */
+	if ( result->GetAddress() < m_iRomStartAddress
+		|| result->GetAddress() > m_iRomEndAddress )
+	{
+		return AddressToLineRofs( result );		
+	}
+	return AddressToLineRom( result );
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLineRom
+// Locate function from rom address range.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLineRom( CATMemoryAddress* result )
+{
+	LOG_LOW_FUNC_ENTRY( "CATRomSymbol::AddressToLineRom" );
+	// Address to find in integer & string.
+	unsigned long iAddressToFind = result->GetAddress();
+	string sAddressToFind = result->GetAddressString();
+	
+	// Find symbol.
+	Symbol* pFound = NULL;
+
+	// Check from cache first.
+	vector<Symbol*>::iterator it;
+	for ( it = m_vRomCache.begin(); it != m_vRomCache.end(); it++ )
+	{
+		if ( iAddressToFind >= (*it)->iStartAddress
+			&& (*it)->iEndAddress > iAddressToFind )
+		{
+			pFound = *it;
+			break;
+		}
+	}
+	
+	if ( pFound == NULL )
+	{
+		// From all symbols.
+		bool reverse = false;
+		int offSetFromStart = iAddressToFind - m_iRomStartAddress;
+		int offSetFromEnd = m_iRomEndAddress - iAddressToFind;
+		if ( offSetFromEnd < offSetFromStart ) 
+			reverse = true;
+		
+		if ( reverse )
+		{
+			// Iterate vector in reverse.
+			vector<Symbol*>::reverse_iterator it;
+			for ( it = m_vRomSymbols.rbegin(); it != m_vRomSymbols.rend(); ++it )
+			{
+				if ( iAddressToFind >= (*it)->iStartAddress
+					&& (*it)->iEndAddress > iAddressToFind )
+				{
+					pFound = *it;
+					break;
+				}
+			}
+		}
+		else
+		{
+			// Iterate vector normal direction.
+			vector<Symbol*>::iterator it;
+			for ( it = m_vRomSymbols.begin(); it != m_vRomSymbols.end(); it++ )
+			{
+				if ( iAddressToFind >= (*it)->iStartAddress
+					&& (*it)->iEndAddress > iAddressToFind )
+				{
+					pFound = *it;
+					break;
+				}
+			}
+		}
+	}
+
+	// Set result if found.
+	if ( pFound != NULL )
+	{
+		result->SetFunctionName( pFound->sFunction );
+		result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+		// Add found symbols pointer to cache.
+		m_vRomCache.push_back( pFound );
+		return true;
+	}
+	return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLineRofs
+// Locate function from rofs address range.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLineRofs( CATMemoryAddress* result)
+{
+	LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLineRofs");
+	// Check that binary name is defined in memory address.
+	string sBinary = result->GetModuleName();
+	if ( sBinary.empty() )
+		return false;
+	// Try find that named module.
+	vector<RofsBinary*>::iterator rofs = m_vRofsBinaries.begin();
+	while( rofs != m_vRofsBinaries.end() )
+	{
+		if ( (*rofs)->m_sBinary.compare( sBinary ) == 0 )
+			break;
+		rofs++;
+	}
+	if ( rofs == m_vRofsBinaries.end() )
+		return false;
+
+	// Offset what we are looking from binary
+	unsigned long offSet = result->GetAddress();
+	offSet -= result->GetModuleStartAddress();
+	for( vector<Symbol*>::iterator it = (*rofs)->vSymbols.begin() ;
+		it != (*rofs)->vSymbols.end(); it++ )
+	{
+		if ( (*it)->iStartAddress <= offSet && offSet < (*it)->iEndAddress )
+		{
+			result->SetFunctionName( (*it)->sFunction );
+			result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+			return true;
+		}
+	}
+	return false;
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/helps.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,180 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Contains help texts for CLE.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+
+//Function declarations
+void print_help( void );
+void print_syntax_examples( void );
+
+/**
+* Print help info.
+*/
+void print_help( void )
+{
+	cout<< "AnalyzeTool v";
+	cout<< ATOOL_VERSION;
+	cout<< " - ";
+	cout<< ATOOL_DATE;
+	cout<< "\n";
+	cout<< "Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).\nAll rights reserved.\n\n";
+	cout<< "Usage:\n";
+	cout<< "atool -e [optional parameters] abld [abld parameters]\n";
+	cout<< "      -me [optional parameters] abld [abld parameters]\n";
+	cout<< "      -mi [optional parameters] [-f data-file] sbs [sbs parameters]\n";
+	cout<< "      -a data-file [output-file] [-s symbol-file] [-l#]\n";
+	cout<< "      -p data-file output-file\n";
+	cout<< "      -c\n";
+	cout<< "      -v\n";
+	cout<< "      -help\n";
+	cout<< "\n";
+	cout<< "Mandatory parameter to choose:\n";
+	cout<< " -e              Build project for analysis using external data gathering.\n";
+	cout<< " -me             Build project for analysis using monitored external\n";
+	cout<< "                 data gathering.\n";
+	cout<< " -mi             Build project for analysis using monitored internal\n";
+	cout<< "                 data gathering.\n";
+	cout<< " abld...         Use SBS v.1 build system with defined build command,\n";
+	cout<< "                 which includes supported platform and build type.\n";
+	cout<< " sbs...          Use SBS v.2 (Raptor) build system with defined sbs build\n";
+	cout<< "                 command, which includes supported platform and build type.\n";
+	cout<< " -a              Analyze report file.\n";
+	cout<< " -c              Clear AnalyzeTool changes, temporary files and releasable(s).\n";
+	cout<< " -p              Parse trace file to data file.\n";
+	cout<< " -help           Show full help including syntax examples.\n";
+	cout<< " -v              Print version info.\n";
+	cout<< "\n";
+
+	cout<< "Optional parameters:\n";
+	cout<< " -acs size       Specifies the call stack size gathered when memory\n";
+	cout<< "                 is allocated. Size can be between 0-256.\n";
+	cout<< " -fcs size       Specifies the call stack size gathered when memory is freed.\n";
+	cout<< "                 Size can be between 0-256.\n";
+	cout<< " -f data file    Specifies the filename for monitored internal data gathering\n";
+	cout<< "                 (50 chars max). Cannot contain path.\n";
+	cout<< " output-file     Specifies the results data file name.\n";
+	cout<< " -l              Logging level of analyze report(0,1,2,3), default 3.\n";
+	cout<< " -s symbol-file  Specifies rom/rofs symbol file(s) to be used in analyze.\n";
+	cout<< "                 Multiple -s options can be given.\n";
+	cout<< " -nobuild        Instruments the project.\n";
+	//cout<< "  -show_debug       Print debug messages to console.\n";
+	//cout<< "  -show_debug_all	  Print debug messages to console (all).\n";
+	//cout<< "  -show_dbgview     Print debug messages to windows debug api.\n";
+	//cout<< "  -show_dbgview_all Print debug messages to windows debug api (all).\n";
+
+	/*
+	* Old style parameters, just for notes.
+	printf("Usage:\n");
+	printf("atool -m [mmp-file] [mode] [data-file] [-variant variant-name] [build] [-sbs2] [-e]\n");
+	printf("      -i [mmp-file] [mode] [data-file] [-variant variant-name] [build] [-sbs2] [-e]\n");
+	printf("      -a [mmp-file | target-name] data-file [-s symbol-file]\n");
+	printf("         [output-file] [-l#]\n");
+	printf("      -p data-file [output-file]\n");
+	printf("      -c\n");
+	//printf("      -u\n");
+	printf("      -v\n");
+	printf("      -help\n");
+	printf("\n");
+	printf("Mandatory option to choose:\n");
+	printf("  -m           Build project for analysis.\n");
+	printf("  -i           Instrument project.\n");
+	printf("  -a           Analyze report file.\n");
+	//printf("  -u           Create listing & map files.\n");
+	printf("  -c           Clear AnalyzeTool changes and temporary files.\n");
+	printf("  -p           Parse trace file.\n");
+	printf("  -help        Show full help including syntax examples.\n");
+	printf("\n");
+
+	printf("Optional options:\n");
+	printf("  mmp-file     Specifies one of the component from bld.inf which is used.\n");
+	printf("  target-name  Specifies the target name of binary to which create\n");
+	printf("               analyze report.\n");
+	printf("  mode         Logging mode (trace or S60), default trace.\n");
+	printf("  data-file    Specifies the user defined data file name (50 chars max).\n");
+	printf("  build        Build target (udeb or urel), default udeb.\n");
+	printf("  output-file  Specifies the results data file name.\n");
+	printf("  -l           Logging level of analyze report(0,1,2,3), default 3.\n");
+	printf("  -variant     Specifies Symbian binary variant to be used.\n");
+	printf("  variant-name Specifies the variant name to be used.\n");
+	printf("  -s           Specifies rom symbol file be used in analyze.\n");
+	printf("  symbol-file  Full path to rom symbol file used in analyze.\n");
+	printf("  -sbs2        Use Symbian Build System v.2.\n");
+	printf("  -winscw      Build project for emulator (winscw platform).\n");
+	printf("  -v           Print version info.\n");
+	*/
+}
+
+void print_syntax_examples( void )
+{
+//Helper line showing width of 80 chars.
+//80cout<< "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
+	cout<< endl;
+	cout<< "Building syntax examples:" << endl;
+	cout<< "Cmd   Description" << endl;
+	
+	cout<< "atool -e abld build armv5 udeb" << endl;
+	cout<< "      Hooks every component from bld.inf. Using external data gathering," << endl;
+	cout<< "      udeb build type and armv5 platform." << endl;
+
+	cout<< "atool -mi -acs 5 sbs -c winscw_udeb" << endl;
+	cout<< "      Hooks every component from bld.inf. Using Symbian Build System v.2" << endl;
+	cout<< "      Using monitored internal data gathering, call stack size of 5" << endl;
+	cout<< "      in allocations, udeb build type and winscw platform." << endl;
+	
+	cout<< "atool -me abld build armv5 udeb foobar" << endl;
+	cout<< "      Hooks only foobar.mmp component from bld.inf. Using monitored" << endl;
+	cout<< "      external data gathering, udeb build type and armv5 platform." << endl;
+	
+	cout<< "atool -e -acs 0 -fcs 0 abld build armv5.default udeb" << endl;
+	cout<< "      Hooks every component from bld.inf. Using default binary variant," << endl;
+	cout<< "      external data gathering, 0 sized callstacks in allocation(s)/free(s)," << endl;
+	cout<< "      udeb build type and armv5 platform." << endl;
+	
+	cout<< "atool -e sbs -b bld.inf -c armv5_udeb" << endl;
+	cout<< "      Hooks every component from bld.inf. Using Symbian Build System v.2" << endl;
+	cout<< "      , external data gathering, udeb build type and armv5 platform." << endl;
+	
+	cout<< "atool -me sbs -s system.xml --config=winscw_udeb" << endl;
+	cout<< "      Hooks every layer defined in system.xml system model. Using Symbian Build" << endl;
+	cout<< "      System v.2, external data gathering, udeb build type and winscw platform." << endl;
+
+	cout<< endl;
+	cout<< "Instrumenting syntax examples:" << endl;
+	cout<< "Cmd   Description" << endl;
+	cout<< "atool -e -nobuild abld build winscw udeb" << endl;
+	cout<< "      Instruments every component from bld.inf. Using external data gathering,"<<endl;
+	cout<< "      udeb build target and winscw platform." << endl;
+    cout<< "   After project is instrumented, it needs to compiled using same platform and" << endl;
+	cout<< "   build type as given to instrumenting. Use -c parameter to remove changes." << endl;
+
+	cout<< endl;
+	cout<< "Analyzing syntax examples:" << endl;
+	cout<< "Cmd   Description" << endl;
+	cout<< "atool -a foo.dat" << endl;
+	cout<< "      Create analyze report from foo.dat device data file." << endl;
+	cout<< "atool -a foo.trace" << endl;
+	cout<< "      Create analyze report from foo.trace raw data file." << endl;
+	cout<< "atool -a foo.dat -s my_rom.symbol -s my_rofs1.symbol" << endl;
+	cout<< "      Create analyze report from foo.dat using also rom and rofs symbol files." << endl;
+	
+	cout<< endl;
+	cout<< "Parsing syntax examples:" << endl;
+	cout<< "Cmd   Description" << endl;
+	cout<< "atool -p foo.trace foo.dat" << endl;
+	cout<< "      Parse foo.trace raw data file to foo.dat device data file." << endl;
+	}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/librarychecks.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Contains functions to check AT libraries.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+// Function declarations
+bool CheckATLibrariesArmv5( string sEpocRoot );
+bool CheckATLibrariesArmv5Abiv2( string sEpocRoot );
+bool CheckATLibrariesWinscw( string sEpocRoot );
+
+// Error msg to user if missing lib
+const char cMissingAToolLibs[] = "\nCan not find AnalyzeTool libraries from current SDK\n\nInstall libraries first\n";
+
+// List of libraries what AnalyzeTool needs when compiled applications on armv5 platform
+const string cAToolLibsArmv5[] = {
+	"epoc32\\RELEASE\\armv5\\LIB\\AToolMemoryHook.lib",
+	"epoc32\\RELEASE\\armv5\\udeb\\AtoolStaticLib.lib",
+	"epoc32\\RELEASE\\armv5\\urel\\AtoolStaticLib.lib"
+};
+
+// List of libraries what AnalyzeTool needs when compiled applications on armv5 platform (using sbs2 / ABIV2 binaries)
+const string cAToolLibsArmv5Abiv2[] = {
+	"epoc32\\RELEASE\\armv5\\LIB\\AToolMemoryHook.dso",
+	"epoc32\\RELEASE\\armv5\\udeb\\AtoolStaticLib.lib",
+	"epoc32\\RELEASE\\armv5\\urel\\AtoolStaticLib.lib"
+};
+
+// List of libraries what AnalyzeTool needs when compiled applications on winscw platform
+const string cAToolLibsWinscw[] = {
+	"epoc32\\RELEASE\\winscw\\udeb\\AToolMemoryHook.lib",
+	"epoc32\\RELEASE\\winscw\\udeb\\AtoolStaticLib.lib",
+	"epoc32\\RELEASE\\winscw\\urel\\AtoolStaticLib.lib"
+};
+
+/**
+* CheckATLibrariesArmv5
+* Checks that armv5 libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesArmv5(string sEpocRoot )
+{
+	LOG_FUNC_ENTRY("CheckATLibrariesArmv5");
+
+	// check that epocroot is set
+	if ( sEpocRoot.length() <= 0 )
+	{
+		LOG_FUNC_EXIT("CheckATLibrariesArmv5 Error, EpocRoot not set");
+		return false;
+	}
+
+	// add trailing '\' if root path is missing it
+	if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+		sEpocRoot.append( "\\" );
+
+	// return boolean value
+	bool bReturn = true;
+
+	int arraySize = sizeof( cAToolLibsArmv5 ) / sizeof( string );
+	for ( int i=0 ; i < arraySize ; i++ )
+	{
+		// append epocroot to file
+		string sFileToCheck = sEpocRoot;
+		sFileToCheck.append( cAToolLibsArmv5[i] );
+		// check does it exists
+		if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+		{
+			bReturn = false;
+			cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+			LOG_STRING("Missing library file: " << sFileToCheck);
+		}
+	}
+
+	if ( ! bReturn )
+	{
+		// print error msg to user
+		cout << cMissingAToolLibs;
+
+	}
+	return bReturn;
+}
+
+/**
+* CheckATLibrariesArmv5Abiv2
+* Checks that armv5 abiv2 libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesArmv5Abiv2(string sEpocRoot )
+{
+	LOG_FUNC_ENTRY("CheckATLibrariesArmv5Abiv2");
+
+	// check that epocroot is set
+	if ( sEpocRoot.length() <= 0 )
+	{
+		LOG_FUNC_EXIT("CheckATLibrariesArmv5Abiv2 Error, EpocRoot not set");
+		return false;
+	}
+
+	// add trailing '\' if root path is missing it
+	if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+		sEpocRoot.append( "\\" );
+
+	// return boolean value
+	bool bReturn = true;
+
+	int arraySize = sizeof( cAToolLibsArmv5Abiv2 ) / sizeof( string );
+	for ( int i=0 ; i < arraySize ; i++ )
+	{
+		// append epocroot to file
+		string sFileToCheck = sEpocRoot;
+		sFileToCheck.append( cAToolLibsArmv5Abiv2[i] );
+		// check does it exists
+		if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+		{
+			bReturn = false;
+			cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+			LOG_STRING("Missing library file: " << sFileToCheck);
+		}
+	}
+
+	if ( ! bReturn )
+	{
+		// print error msg to user
+		cout << cMissingAToolLibs;
+
+	}
+	return bReturn;
+}
+
+/**
+* CheckATLibrariesWinscw
+* Checks that winscw libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesWinscw(string sEpocRoot )
+{
+	LOG_FUNC_ENTRY("CheckATLibrariesWinscw");
+
+	// check that epocroot is set
+	if ( sEpocRoot.length() <= 0 )
+	{
+		LOG_FUNC_EXIT("CheckATLibrariesArmv5Abiv2 Error, EpocRoot not set");
+		return false;
+	}
+
+	// add trailing '\' if root path is missing it
+	if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+		sEpocRoot.append( "\\" );
+
+	// return boolean value
+	bool bReturn = true;
+
+	int arraySize = sizeof( cAToolLibsWinscw ) / sizeof( string );
+	for ( int i=0 ; i < arraySize ; i++ )
+	{
+		// append epocroot to file
+		string sFileToCheck = sEpocRoot;
+		sFileToCheck.append( cAToolLibsWinscw[i] );
+		// check does it exists
+		if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+		{
+			bReturn = false;
+			cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+			LOG_STRING("Missing library file: " << sFileToCheck);
+		}
+	}
+
+	if ( ! bReturn )
+	{
+		// print error msg to user
+		cout << cMissingAToolLibs;
+
+	}
+	return bReturn;
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/stdafx.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "../inc/stdafx.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/utility.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Miscellaneous utility functions.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATProject.h"
+
+//Analyze report logging level.
+#define MAX_LOG_LEVEL 3
+
+//Function declarations.
+bool CheckSBS2Folder( void );
+
+/**
+* Helper function which checks does current dir contain atool_temp\build folder which
+* is used in sbs2 support
+*/
+bool CheckSBS2Folder( void )
+{
+	LOG_FUNC_ENTRY("CheckSBS2Folder");
+	if ( CATBase::DirectoryExists( RAPTOR_MAKEFILE_DIR ) )
+		return true;
+	return false;
+}
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/version.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,258 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Show / Check atool version.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+//Function declarations.
+int showVersionInfo( void );
+int showCoreVersionInfo( void );
+bool readCoreVersionInfo( const string& sFile, string& sVersion );
+string findAnalyzeToolHeader( void );
+int showDbgHelpVersionInfo( bool showVersion );
+int getDllVersion( LPCTSTR libName, WORD *majorVersion, WORD *minorVersion, WORD *buildNumber, WORD *revisionNumber );
+
+//External GetEpocRoot function
+extern bool GetEpocRoot( string &sEpocRoot );
+
+void convertWriteTimeToLocalTime( FILETIME ftWrite, LPSTR lpszString );
+
+int showCoreVersionInfo( void )
+{
+	LOG_FUNC_ENTRY( "version.cpp::showCoreVersionInfo" );
+	// Try find header from environment where to locate version info.
+	string sHeaderFile = findAnalyzeToolHeader();
+	if ( sHeaderFile.empty() )
+		return 0;
+	string sVersion("");
+	if ( readCoreVersionInfo( sHeaderFile, sVersion ) )
+	{
+		cout << "AnalyzeTool SDK binaries version: " 
+			<< sVersion
+			<< endl;
+	}
+	return 0;
+}
+
+
+/**
+* Find analyzetool.h header file
+* @return string containing full path to file or empty string if not found.
+*/
+string findAnalyzeToolHeader( void )
+{
+	LOG_FUNC_ENTRY( "version.cpp::findAnalyzeToolHeader" );
+	string sEpocRoot;
+	if ( ! CATBase::GetEpocRoot( sEpocRoot ) )
+		return string("");
+	int iC = sizeof( AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER ) / sizeof ( string );
+	for( int i = 0 ; i < iC ; i++ )
+	{
+		string sCheck( sEpocRoot );
+		sCheck.append( AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER[i] );
+		if ( CATBase::FileExists( sCheck.c_str() ) )
+			return sCheck;
+	}
+	return string("");
+}
+/**
+* Read core version string.
+* @param sVersion string will contain version info if funtion returns true.
+* @return true if successful.
+*/
+bool readCoreVersionInfo( const string& sFile, string& sVersion )
+{
+	LOG_FUNC_ENTRY( "version.cpp::readCoreVersionInfo" );
+	try {
+		ifstream in;
+		in.open( sFile.c_str() );
+		if ( ! in.good() )
+			return false;
+		char cBuff[MAX_LINE_LENGTH];
+		while ( in.good() )
+		{
+			in.getline( cBuff, MAX_LINE_LENGTH );
+			string s( cBuff );
+			if ( s.find( AT_CORE_VERSION_NUMBER_TAG ) != string::npos )
+			{
+				// Find spot after first space (ignore first 3 chars).
+				size_t t =  s.find_first_of( ' ', 3 )+1;
+				sVersion = s.substr( t, s.size()-t );
+				return true;
+			}
+		}
+	}
+	catch(...)
+	{
+		LOG_STRING(AT_MSG << "Exception reading core version info.");
+	}
+	return false;
+}
+
+/**
+* Print version information of atool.exe binary.
+*/
+int showVersionInfo( void )
+{
+	LOG_FUNC_ENTRY( "version.cpp::showVersionInfo" );
+	string sTemp( "Version: " );
+	sTemp.append( ATOOL_VERSION );
+	sTemp.append( "\n" );
+	//Print atool version
+	printf( sTemp.c_str() );
+
+	//atool.exe:s path + filename
+	char buffer[MAX_PATH];
+
+	GetModuleFileName( NULL, buffer, MAX_PATH );
+
+	printf( "Path: %s\n", buffer );
+
+	WIN32_FIND_DATA FindFileData;
+	HANDLE hFind;
+	//Get file handle
+	hFind = FindFirstFile( buffer, &FindFileData );
+
+	if( hFind == INVALID_HANDLE_VALUE )
+	{
+		printf( "Can not find file:%s", buffer );
+		return 0;
+	}
+
+	convertWriteTimeToLocalTime( FindFileData.ftLastWriteTime , buffer );
+	printf( "Modified: %s\n", buffer );
+
+	// Show core version information.
+	showCoreVersionInfo();
+	return 0;
+}
+
+// Convert the last-write time to local time.
+void convertWriteTimeToLocalTime( FILETIME ftWrite, LPSTR lpszString )
+{
+	LOG_FUNC_ENTRY( "version.cpp::convertWriteTimeToLocalTime" );
+	SYSTEMTIME stUTC, stLocal;
+    // Convert the last-write time to local time.
+    FileTimeToSystemTime(&ftWrite, &stUTC);
+    SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
+
+    // Build a string showing the date and time.
+    wsprintf(lpszString, "%02d/%02d/%d %02d:%02d:%02d",
+        stLocal.wDay, stLocal.wMonth, stLocal.wYear,
+        stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
+}
+
+/**
+* Print version information of dbghelp.dll.
+*/
+int showDbgHelpVersionInfo( bool showVersion )
+{
+	LOG_FUNC_ENTRY( "version.cpp::showDbgHelpVersionInfo" );
+
+	WORD majorVersion;
+	WORD minorVersion;
+	WORD buildNumber;
+	WORD revisionNumber;
+
+	if(getDllVersion( _T(DBGHELP_DLL_NAME), &majorVersion, &minorVersion, &buildNumber, &revisionNumber))
+	{
+		//Check if current dll version is lower than latest version
+		if((majorVersion < DBGHELP_VERSION_MAJ) ||
+			(majorVersion == DBGHELP_VERSION_MAJ && minorVersion < DBGHELP_VERSION_MIN) ||
+			(majorVersion == DBGHELP_VERSION_MAJ && minorVersion == DBGHELP_VERSION_MIN && buildNumber < DBGHELP_VERSION_BUILD) ||
+			(majorVersion == DBGHELP_VERSION_MAJ && minorVersion == DBGHELP_VERSION_MIN && buildNumber == DBGHELP_VERSION_BUILD && revisionNumber < DBGHELP_VERSION_REVIS))
+		{
+			cout << "WARNING: Version of your dbghelp.dll is "
+					<< majorVersion << "."
+					<< minorVersion << "."
+					<< buildNumber << "."
+					<< revisionNumber << ".\n";
+
+			cout << "Source code pinpointing for winscw may not work properly with this version."
+				<< endl
+				<< "Please, update it to at least version "
+				<< DBGHELP_VERSION_MAJ << "." 
+				<< DBGHELP_VERSION_MIN << "." 
+				<< DBGHELP_VERSION_BUILD << "." 
+				<< DBGHELP_VERSION_REVIS << ".\n"
+				<< "dbghelp.dll file is included in Debugging Tools from Microsoft. "
+				<< "You can download and install it from\n"
+				<< "http://www.microsoft.com/whdc/devtools/debugging/\n";
+
+			return 1;
+		}
+		else
+		{
+			if( showVersion )
+			{
+				cout << "Version of your dbghelp.dll is "
+					<< majorVersion << "."
+				    << minorVersion << "."
+				    << buildNumber << "."
+				    << revisionNumber << "."
+				    << endl;
+				cout << "No need for update.\n";
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+* Get dll version.
+* @param libName library name.
+* @param majorVersion will contain major version if funtion returns true.
+* @param minorVersion will contain minor version if funtion returns true.
+* @param buildNumber will contain build number if funtion returns true.
+* @param revisionNumber will contain revision number if funtion returns true.
+* @return true if successful.
+*/
+int getDllVersion( LPCTSTR  libName, WORD *majorVersion, WORD *minorVersion, WORD *buildNumber, WORD *revisionNumber ) 
+{
+	LOG_FUNC_ENTRY( "version.cpp::getDllVersion" );
+
+	DWORD dwHandle, dwLen;
+	UINT BufLen;
+	LPTSTR lpData;
+	VS_FIXEDFILEINFO *pFileInfo;
+	dwLen = GetFileVersionInfoSize( libName, &dwHandle );
+	if (!dwLen)
+		return 0;
+	
+	lpData = (LPTSTR) malloc (dwLen);
+	if (!lpData)
+		return 0;
+	
+	if( !GetFileVersionInfo( libName, dwHandle, dwLen, lpData ) )
+	{
+		free (lpData);
+		return 0;
+	}
+	
+	if( VerQueryValue( lpData, _T("\\"), (LPVOID *) &pFileInfo, (PUINT)&BufLen ) )
+	{
+		*majorVersion = HIWORD(pFileInfo->dwFileVersionMS);
+		*minorVersion = LOWORD(pFileInfo->dwFileVersionMS);
+		*buildNumber = HIWORD(pFileInfo->dwFileVersionLS);
+		*revisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
+		return 1;
+	 }
+	free (lpData);
+	return 0;
+}
+
+//EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/bwins/atoolmemoryhooku.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,10 @@
+EXPORTS
+	?Alloc@RAnalyzeToolAllocator@@UAEPAXH@Z @ 1 NONAME ; void * RAnalyzeToolAllocator::Alloc(int)
+	?Alloc@RAnalyzeToolMainAllocator@@UAEPAXH@Z @ 2 NONAME ; void * RAnalyzeToolMainAllocator::Alloc(int)
+	?Exit@CustomUser@@SAXH@Z @ 3 NONAME ; void CustomUser::Exit(int)
+	?InstallAllocator@CustomUser@@CAAAVRAllocator@@HABV?$TBuf@$0BAA@@@KKKK@Z @ 4 NONAME ; class RAllocator & CustomUser::InstallAllocator(int, class TBuf<256> const &, unsigned long, unsigned long, unsigned long, unsigned long)
+	?Panic@CustomUser@@SAXABVTDesC16@@H@Z @ 5 NONAME ; void CustomUser::Panic(class TDesC16 const &, int)
+	?SetCritical@CustomUser@@SAHW4TCritical@User@@@Z @ 6 NONAME ; int CustomUser::SetCritical(enum User::TCritical)
+	?SetProcessCritical@CustomUser@@SAHW4TCritical@User@@@Z @ 7 NONAME ; int CustomUser::SetProcessCritical(enum User::TCritical)
+	?SetupThreadHeap@CustomUser@@SAHHAAUSStdEpocThreadCreateInfo@@ABV?$TBuf@$0BAA@@@KKABV?$TBuf@$0BE@@@KKV?$TRefByValue@$$CBVTDesC16@@@@ZZ @ 8 NONAME ; int CustomUser::SetupThreadHeap(int, struct SStdEpocThreadCreateInfo &, class TBuf<256> const &, unsigned long, unsigned long, class TBuf<20> const &, unsigned long, unsigned long, class TRefByValue<class TDesC16 const >, ...)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/eabi/atoolmemoryhooku.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,16 @@
+EXPORTS
+	_ZN10CustomUser11SetCriticalEN4User9TCriticalE @ 1 NONAME
+	_ZN10CustomUser15SetupThreadHeapEiR24SStdEpocThreadCreateInfoRK4TBufILi256EEmmRKS2_ILi20EEmm11TRefByValueIK7TDesC16Ez @ 2 NONAME
+	_ZN10CustomUser16InstallAllocatorEiRK4TBufILi256EEmmmm @ 3 NONAME
+	_ZN10CustomUser18SetProcessCriticalEN4User9TCriticalE @ 4 NONAME
+	_ZN10CustomUser4ExitEi @ 5 NONAME
+	_ZN10CustomUser5PanicERK7TDesC16i @ 6 NONAME
+	_ZTI20CLibraryEventHandler @ 7 NONAME ; #<TI>#
+	_ZTI21RAnalyzeToolAllocator @ 8 NONAME ; #<TI>#
+	_ZTI25RAnalyzeToolMainAllocator @ 9 NONAME ; #<TI>#
+	_ZTI27RAnalyzeToolMemoryAllocator @ 10 NONAME ; #<TI>#
+	_ZTV20CLibraryEventHandler @ 11 NONAME ; #<VT>#
+	_ZTV21RAnalyzeToolAllocator @ 12 NONAME ; #<VT>#
+	_ZTV25RAnalyzeToolMainAllocator @ 13 NONAME ; #<VT>#
+	_ZTV27RAnalyzeToolMemoryAllocator @ 14 NONAME ; #<VT>#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/group/atoolmemoryhook.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for AToolMemoryHook.
+*
+*/
+
+#include <platform_paths.hrh>
+#include "../../symbian_version.hrh"
+
+TARGET        atoolmemoryhook.dll
+TARGETTYPE    dll
+UID           0x1000008d 0x2001242F
+CAPABILITY    ALL -TCB
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+EPOCALLOWDLLDATA
+#endif
+
+SMPSAFE
+
+SOURCEPATH    ../src
+
+SOURCE        analyzetooleventhandler.cpp
+SOURCE        codeblock.cpp
+SOURCE        threadstack.cpp
+SOURCE        customuser.cpp
+SOURCE        analyzetoolmemoryallocator.cpp
+SOURCE        analyzetoolmainallocator.cpp
+SOURCE        analyzetoolallocator.cpp
+SOURCE        analyzetoolfastlog.cpp
+
+SOURCEPATH    ../../storageserver/server/src
+SOURCE        atdriveinfo.cpp
+
+USERINCLUDE   ../inc
+USERINCLUDE   ../../inc
+USERINCLUDE   ../../storageserver/inc
+USERINCLUDE   ../../storageserver/server/inc
+
+#ifdef WINSCW
+APP_LAYER_SYSTEMINCLUDE
+#endif
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY       efsrv.lib 
+LIBRARY       euser.lib
+LIBRARY       atoolstorageserverclnt.lib
+LIBRARY       flogger.lib
+LIBRARY       charconv.lib 
+LIBRARY       platformenv.lib 
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+MACRO	USE_CLEANER_DLL
+#endif
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_MMPFILES
+atoolmemoryhook.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/analyzetoolmemoryhooktest.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolallocator.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,247 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class RAnalyzeToolAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLALLOCATOR_H
+#define ANALYZETOOLALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "codeblock.h"
+#include "threadstack.h"
+#include "analyzetoolmemoryallocator.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+#include <analyzetool/atcommon.h>
+
+// CLASS DECLARATION
+
+/**
+*  Class which overloads the RAlloctor functions and provides access to 
+*  the overloaded functions  
+*/
+class RAnalyzeToolAllocator : public RAnalyzeToolMemoryAllocator
+    {
+
+    public:
+
+        /**
+        * C++ default constructor.
+        * @param aNotFirst Is this first thread using this heap
+        * @param aStorageServer A reference to the 
+        *                       <code>RATStorageServer</code> which is 
+        *                       used to store kernel events
+        * @param aCodeblocks A reference to array of code segments
+        * @param aMutex A reference to mutex for schedule access to the 
+        *                   shared resources
+        * @param aProcessId A reference to the observed process id
+        * @param aAnalyzeTool Reference to device driver
+        * @param aStorageServerOpen Variable to check if Storage server is connected
+        * @param aLogOption The logging option for storage server
+        * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+        * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+        */
+        RAnalyzeToolAllocator( TBool aNotFirst,
+                               RATStorageServer& aStorageServer, 
+                               RArray<TCodeblock>& aCodeblocks, 
+                               RMutex& aMutex, 
+                               TUint aProcessId,
+                               RAnalyzeTool& aAnalyzeTool,
+                               TBool aStorageServerOpen,
+                               TUint32 aLogOption,
+                               TUint32 aAllocCallStackSize,
+                               TUint32 aFreeCallStackSize );
+        /**
+        * Destructor.
+        */                     
+        ~RAnalyzeToolAllocator();
+
+        /**
+        * Allocates a cell of specified size from the heap.
+        * @param aSize The size of the cell to be allocated from the heap. 
+        * @return TAny* A pointer to the allocated cell.
+        */
+        TAny* Alloc( TInt aSize );
+
+        /**
+        * Frees the specified cell and returns it to the heap.
+        * @param aPtr A pointer to a cell to be freed.
+        */
+        void Free( TAny* aPtr );
+
+        /**
+        * Increases or decreases the size of an existing cell.
+        * @param aPtr A pointer to the cell to be reallocated.
+        * @param aSize The new size of the cell. This may be bigger 
+        *              or smaller than the size of the original cell.
+        * @param aMode Flags controlling the reallocation.
+        * @return TAny* A pointer to the reallocated cell. This may be the 
+        *               same as the original pointer supplied through aCell.
+        */
+        //lint --e{1735} suppress "Virtual function has default parameter"
+        TAny* ReAlloc( TAny* aPtr, TInt aSize, TInt aMode = 0 );
+        
+        /**
+        * Gets the length of the available space in the specified 
+        * allocated cell.
+        * @param aCell A pointer to the allocated cell.
+        * @return TInt The length of the available space in the allocated cell.
+        */
+        TInt AllocLen( const TAny* aCell ) const;
+
+    #ifndef __KERNEL_MODE__
+
+        /**
+        * Opens this heap for shared access. Opening the heap increases 
+        * the heap's access count by one.
+        */
+        TInt Open();
+        
+        /**
+        * Closes this shared heap. Closing the heap decreases the heap's 
+        * access count by one.
+        */
+        void Close();
+
+        /**
+        * The function frees excess committed space from the top of the heap.
+        * The size of the heap is never reduced below the minimum size 
+        * specified during creation of the heap.
+        * @return TInt The space reclaimed. If no space can be reclaimed, 
+                       then this value is zero.
+        */
+        TInt Compress();
+
+        /**
+        * Frees all allocated cells on this heap. 
+        */
+        void Reset();
+
+        /**
+        * Gets the number of cells allocated on this heap, and 
+        * the total space allocated to them.
+        * @param aTotalAllocSize On return, contains the total 
+        *                        space allocated to the cells.
+        * @return TInt The number of cells allocated on this heap.
+        */
+        TInt AllocSize( TInt& aTotalAllocSize ) const;
+        
+        /**
+        * Gets the total free space currently available on the heap and the 
+        * space available in the largest free block. The space available 
+        * represents the total space which can be allocated. Note that 
+        * compressing the heap may reduce the total free space available 
+        * and the space available in the largest free block.
+        * @param aBiggestBlock On return, contains the space available 
+        *                      in the largest free block on the heap.
+ 
+        * @return TInt The total free space currently available on the heap.
+
+        */
+        TInt Available( TInt& aBiggestBlock ) const;
+        
+    #endif
+
+        /**
+        * Invocates specified debug funtionality.
+        * @param aFunc The debug function
+        * @param a1 Debug function specific paramenter.
+        * @param a2 Debug function specific paramenter.
+        * @return TInt Returns KErrNone, if successful otherwise one 
+        *              of the other system-wide error codes.
+        */
+        //lint --e{1735} suppress "Virtual function has default parameter"
+        TInt DebugFunction( TInt aFunc, TAny* a1 = NULL, TAny* a2 = NULL );
+
+    protected:
+
+        /**
+        * Extension function
+        * @param aExtensionId The extension id
+        * @param a0 Extension specific paramenter.
+        * @param a1 Extension specific paramenter.
+        * @return TInt Returns KErrNone, if successful otherwise one 
+        *              of the other system-wide error codes. 
+        */
+        TInt Extension_( TUint aExtensionId, TAny*& a0, TAny* a1 );
+
+    public: // from RAnalyzeToolMemoryAllocator
+        
+        /**
+        * Installs the RTraceAllocator allocator
+        */
+        void Uninstall();
+        
+        /**
+        * Shares the heap
+        */
+        void ShareHeap();
+
+    private:
+    
+        /**
+        * Find the current thread which is using the heap
+        * @param aStackStart A reference where the stack start is stored
+        * @return TBool ETrue if a thread can be found, EFalse otherwise
+        */
+        TBool FindCurrentThreadStack( TUint32& aStackStart );
+
+    private: 
+    
+        /* Handle to the storage server*/
+        RATStorageServer& iStorageServer;
+
+        /* A reference to codeblocks of the observed process */            
+        RArray<TCodeblock>& iCodeblocks;
+
+        /* The mutex for serializing access to the shared resources */
+        RMutex& iMutex;
+
+        /* The process id */
+        TUint iProcessId;
+
+        /* Array for storing the callstack */
+        TFixedArray<TUint32, KATMaxCallstackLength> iCallStack;
+
+        /* Array for storing the reallocation callstack */
+        TFixedArray <TUint32, KATMaxCallstackLength> iReCallStack;
+
+        /* Array for storing the reallocation callstack */	
+        TFixedArray<TUint32, KATMaxFreeCallstackLength> iFreeCallStack;
+                
+        /* Array of threads using this heap */
+        RArray<TThreadStack> iThreadArray;
+
+        RAnalyzeTool& iAnalyzeTool;
+
+        /* A flag for indicating that the RATStorageServer is open */
+        TBool iStorageServerOpen;
+
+        /* Log option */
+        TUint32 iLogOption;
+        
+        /* Max items on stored call stack when memory allocated */
+        TUint32 iAllocMaxCallStack;
+        
+        /* Max items on stored call stack when memory freed */
+        TUint32 iFreeMaxCallStack;
+        
+    };
+
+#endif // ANALYZETOOLALLOCATOR_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetooleventhandler.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class CLibraryEventHandler.
+*
+*/
+
+
+#ifndef ANALYZETOOLEVENTHANDLER_H
+#define ANALYZETOOLEVENTHANDLER_H
+
+// INCLUDES
+#include <e32cmn.h>
+#include "codeblock.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+
+// FORWARD DECLARATIONS
+class MAnalyzeToolEventhandlerNotifier;
+
+// CLASS DECLARATION
+
+/**
+*  Class for receiving library load/unlaod events from the kernel   
+*/
+class CLibraryEventHandler : public CActive
+    {
+    
+    public: 
+
+        /**
+        * C++ default constructor.
+        * @param aAnalyzeTool A reference to the <code>RAnalyzeTool</code> 
+                 which is used to observe kernel events 
+        * @param aCodeblocks A reference to array of code segments
+        * @param aStorageServer A reference to the 
+        *                       <code>RATStorageServer</code> which is 
+        *                       used to store kernel events
+        * @param aProcessId A reference to the observed process id
+        * @param aMutex A reference to mutex to schedule access to the 
+        *                   shared resources
+        * @param aNotifier A reference to notifier object which is used to 
+        * 					inform killed threads
+        * @param aLogOption Current used log option on allocator.
+        */
+        CLibraryEventHandler( RAnalyzeTool& aAnalyzeTool, 
+                RArray<TCodeblock>& aCodeblocks, 
+                RATStorageServer& aStorageServer, 
+                TUint aProcessId,
+                RMutex& aMutex,
+                MAnalyzeToolEventhandlerNotifier& aNotifier,
+                TUint32 aLogOption );
+
+        /**
+        * Destructor.
+        */
+        ~CLibraryEventHandler();
+
+        /* Start receiving events from the kernel */
+        void Start();
+        
+        /**
+        * Returns eventhandler's state.
+        * @return TBool ETrue if eventhandler is started, EFalse otherwise
+        */
+        TBool IsStarted();
+
+    protected: // Functions from base classes
+        
+        /**
+        * Process active object's task
+        */
+        void RunL();
+
+        /**
+        * Cancels active object's task
+        */
+        void DoCancel();
+ 
+    private: // Member variables
+
+        /* Handle to the analyze tool device driver*/
+        RAnalyzeTool& iAnalyzeTool; 
+
+        /* A reference to codeblocks of the observed process */
+        RArray<TCodeblock>& iCodeblocks;
+
+        /* Handle to the storage server*/
+        RATStorageServer& iStorageServer;
+
+        /* The observered process id */ 
+        TUint iProcessId;
+
+        /* The library info */
+        TLibraryEventInfo iLibraryInfo;
+
+        /* The mutex for serializing access to the shared resources */
+        RMutex& iMutex;
+        
+        /* Inform if handler is started */
+        TBool iStarted;
+        
+        /* A reference to event handler notifier */
+        MAnalyzeToolEventhandlerNotifier& iNotifier;
+
+        /* Current used log option */
+        TUint32 iLogOption;
+    };
+
+#endif // ANALYZETOOLEVENTHANDLER_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetooleventhandlernotifier.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class MAnalyzeToolEventhandlerNotifier
+*
+*/
+
+
+#ifndef ANALYZETOOLEVENTHANDLERNOTIFIER_H
+#define ANALYZETOOLEVENTHANDLERNOTIFIER_H
+
+//  INCLUDES
+#include <e32base.h>
+
+// CLASS DECLARATION
+
+/**
+*  MAnalyzeToolEventhandlerNotifier class
+*  An interface class for informing killed thread.
+*/
+class MAnalyzeToolEventhandlerNotifier
+    {
+    public: // New functions
+           
+        /**
+        * Inform when thread killed.
+        * @param aThreadId - Killed thread Id.
+        */
+        virtual void RemoveKilledThread( const TUint aThreadId ) = 0;
+
+    };
+
+#endif // ANALYZETOOLEVENTHANDLERNOTIFIER_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolfastlog.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __ANALYZETOOLFASTLOG_H__
+#define __ANALYZETOOLFASTLOG_H__
+
+// INCLUDES
+#include    <e32base.h>
+#include    <analyzetool/atcommon.h>
+#include    <analyzetool/analyzetooltraceconstants.h>
+
+// Function prototypes.
+
+/**
+ * TBD
+ * @param aProcessName The name of the new process started. The length of this
+ *   descriptor must not be greater than KMaxProcessName.
+ * @param aProcessId The ID of the process started.
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogProcessStarted( const TDesC8& aProcessName,
+                                 TUint aProcessId,
+                                 TUint32 aIsDebug );
+
+/**
+ * TBD 
+ * @param aProcessId The ID number of the process ended.
+ * @param aHandleLeakCount Number of handles open.
+ * @return KErrNone, if successful; otherwise one of the other
+ *   system-wide error codes.
+ */
+GLREF_C TInt ATFastLogProcessEnded( TUint aProcessId, 
+                                TUint aHandleLeakCount );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aDllName The name of the new DLL loaded. The length of this descriptor
+ *   must not be greater than KMaxLibraryName.
+ * @param aStartAddress The start address of the DLL loaded.
+ * @param aEndAddress The end address of the DLL loaded.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogDllLoaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+                                TUint32 aEndAddress );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aDllName The name of the DLL to be unloaded. The length of this
+ *   descriptor must not be greater than KMaxLibraryName.
+ * @param aStartAddress The start address of the DLL to be unloaded.
+ * @param aEndAddress The end address of the DLL to be unloaded.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogDllUnloaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+                                       TUint32 aEndAddress );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aMemAddress The memory location where memory has been allocated.
+ * @param aCallstack An array including the current call stack.
+ * @param aSize The size of the newly allocated memory chunk.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogMemoryAllocated( TUint aProcessId, TUint32 aMemAddress,
+                                  TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+                                  TInt aSize );
+        
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aMemAddress The memory location where memory has been deallocated.
+ * @param aFreeCallstack An array including the current call stack.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogMemoryFreed( TUint aProcessId, TUint32 aMemAddress, 
+                              TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack );
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLMAINALLOCATOR_H
+#define ANALYZETOOLMAINALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "codeblock.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+#include <analyzetool/atcommon.h>
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetooleventhandlernotifier.h"
+
+// FORWARD DECLARATIONS
+class CLibraryEventHandler;
+
+// CLASS DECLARATION
+
+/**
+*  Class which overloads the RAlloctor functions and provides access to 
+*  the overloaded functions  
+*/
+class RAnalyzeToolMainAllocator : public RAnalyzeToolMemoryAllocator, 
+								  public MAnalyzeToolEventhandlerNotifier
+    {
+
+    public:
+
+        /**
+        * C++ default constructor.
+        * @param aNotFirst Is this first thread using this heap
+        * @param aFileName The name of the log file
+        * @param aLogOption The logging option for storage server
+        * @param aIsDebug Determines whether a binary is UDEB or UREL
+        * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+        * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+        */
+        RAnalyzeToolMainAllocator( TBool aNotFirst,
+                const TFileName aFileName,
+                TUint32 aLogOption, TUint32 aIsDebug,
+                TUint32 aAllocCallStackSize,
+                TUint32 aFreeCallStackSize );
+
+        /**
+        * Destructor.
+        */
+        ~RAnalyzeToolMainAllocator();
+
+        /**
+        * Allocates a cell of specified size from the heap.
+        * @param aSize The size of the cell to be allocated from the heap. 
+        * @return TAny* A pointer to the allocated cell.
+        */
+        TAny* Alloc( TInt aSize );
+
+        /**
+        * Frees the specified cell and returns it to the heap.
+        * @param aPtr A pointer to a cell to be freed.
+        */
+        void Free( TAny* aPtr );
+
+        /**
+        * Increases or decreases the size of an existing cell.
+        * @param aPtr A pointer to the cell to be reallocated.
+        * @param aSize The new size of the cell. This may be bigger 
+        *              or smaller than the size of the original cell.
+        * @param aMode Flags controlling the reallocation.
+        * @return TAny* A pointer to the reallocated cell. This may be the 
+        *               same as the original pointer supplied through aCell.
+        */
+        TAny* ReAlloc( TAny* aPtr, TInt aSize, TInt aMode = 0 );
+        
+        /**
+        * Gets the length of the available space in the specified 
+        * allocated cell.
+        * @param aCell A pointer to the allocated cell.
+        * @return TInt The length of the available space in the allocated cell.
+        */
+        TInt AllocLen(const TAny* aCell) const;
+
+    #ifndef __KERNEL_MODE__
+
+        /**	
+        * Opens this heap for shared access. Opening the heap increases 
+        * the heap's access count by one.
+        */
+        TInt Open();
+        
+        /**
+        * Closes this shared heap. Closing the heap decreases the heap's 
+        * access count by one.
+        */  	
+        void Close();
+
+        /**
+        * The function frees excess committed space from the top of the heap.
+        * The size of the heap is never reduced below the minimum size 
+        * specified during creation of the heap.
+        * @return TInt The space reclaimed. If no space can be reclaimed, 
+                       then this value is zero.
+        */
+        TInt Compress();
+
+        /**
+        * Frees all allocated cells on this heap. 
+        */
+        void Reset();
+
+        /**
+        * Gets the number of cells allocated on this heap, and 
+        * the total space allocated to them.
+        * @param aTotalAllocSize On return, contains the total 
+        *						 space allocated to the cells.
+        * @return TInt The number of cells allocated on this heap.
+        */
+        TInt AllocSize( TInt& aTotalAllocSize ) const;
+        
+        /**
+        * Gets the total free space currently available on the heap and the 
+        * space available in the largest free block. The space available 
+        * represents the total space which can be allocated. Note that 
+        * compressing the heap may reduce the total free space available 
+        * and the space available in the largest free block.
+        * @param aBiggestBlock On return, contains the space available 
+        *                      in the largest free block on the heap.
+ 
+        * @return TInt The total free space currently available on the heap.
+
+        */
+        TInt Available( TInt& aBiggestBlock ) const;
+
+	#endif
+        
+        /**
+        * Invocates specified debug funtionality.
+        * @param aFunc The debug function
+        * @param a1 Debug function specific paramenter.
+        * @param a2 Debug function specific paramenter.
+        * @return TInt Returns KErrNone, if successful otherwise one 
+        *              of the other system-wide error codes.
+        */
+        TInt DebugFunction( TInt aFunc, TAny* a1 = NULL, TAny* a2 = NULL );
+        
+        // From MAnalyzeToolEventhandlerNotifier
+        
+        /**
+		* Remove killed thread from threads array.
+		* @param aThreadId - Thread Id
+		*/
+		void RemoveKilledThread( const TUint aThreadId );
+		
+    protected:
+
+        /**
+        * Extension function
+        * @param aExtensionId The extension id
+        * @param a0 Extension specific paramenter.
+        * @param a1 Extension specific paramenter.
+        * @return TInt Returns KErrNone, if successful otherwise one 
+        *              of the other system-wide error codes. 
+        */
+        TInt Extension_( TUint aExtensionId, TAny*& a0, TAny* a1 );
+
+    public: // from RAnalyzeToolMemoryAllocator
+        
+        /**
+        * Installs the RTraceAllocator allocator
+        */
+        void Uninstall();
+        
+        /**
+        * Shares the heap
+        */
+        void ShareHeap();
+
+    public: // inlines
+    
+        /**
+        * Acquires the open RATStorageServer handle
+        * @return RATStorageServer& The open RATStorageServer handle
+        */
+        inline RATStorageServer& StorageServer();
+        
+        /**
+        * Acquires the codeblocks of the process
+        * @return RArray<TCodeblock>& The process codeblocks
+        */
+        inline RArray<TCodeblock>& Codeblocks();
+        
+        /**
+        * Acquires the mutex used to access shared objects
+        * @return RMutex& A reference to open mutex
+        */
+        inline RMutex& Mutex();
+        
+        /**
+        * Acquires the current process id
+        * @return TInt The process id
+        */
+        inline TInt ProcessId();
+
+        /**
+		* Acquires the logical channel handle
+		* @return RAnalyzeTool A reference to logical channel
+		*/
+        inline RAnalyzeTool& AnalyzeTool();
+ 
+         /**
+        * Acquires information if storage server is open
+        * @return TBool iStorageServerOpen
+        */
+        inline TBool StorageServerOpen();
+                
+        /**
+        * Acquires the log option type 
+        * @return TUint32 iLogOption
+        */        
+        inline TUint32 LogOption();
+        
+        /**
+        * Acquires the max size of call stack when memory allocated
+        * @return TUint32 iAllocMaxCallStack
+        */        
+        inline TUint32 AllocMaxCallStack();
+        
+        /**
+         * Acquires the max size of call stack when memory freed
+         * @return TUint32 iFreeMaxCallStack
+         */
+        inline TUint32 FreeMaxCallStack();
+
+    private: // private functions
+
+        /**
+        * Log the process initial information
+        * @param aFileName The name of the log file
+        * @param aLogOption The logging option for storage serve
+        * @param aIsDebug Determines whether a binary is UDEB or UREL
+        */
+        void LogProcessInformation( const TFileName aFileName, TUint32 aLogOption,
+                                                                TUint32 aIsDebug );
+
+        /**
+        * Find the current thread which is using the heap
+        * @param aStackStart A reference where the stack start is stored
+        * @return TBool ETrue if a thread can be found, EFalse otherwise
+        */
+        TBool FindCurrentThreadStack( TUint32& aStackStart );
+        
+        /**
+        * Installs the eventhandler, if possible
+        */
+        void InstallEventHandler();
+
+    private: // member variables
+            
+        /* Handle to the RATStorageServer */
+        RATStorageServer iStorageServer;
+
+        /* Handle to the RAnalyzeTool */		
+        RAnalyzeTool iAnalyzeTool;           
+        
+        /* A flag for indicating that the RAnalyzeTool is open */
+        TBool iAnalyzeToolOpen;
+
+        /* A flag for indicating that the device driver is loaded */
+        TBool iDeviceDriverLoaded;
+        
+        /* The codeblocks of the process */
+        RArray<TCodeblock> iCodeblocks;
+
+        /* The handler for kerner events */
+        CLibraryEventHandler* iEventHandler;
+
+        /* The mutex for serializing access to the shared resources */
+        mutable RMutex iMutex;	
+        	
+        /* Array for storing the callstack */	
+        TFixedArray <TUint32, KATMaxCallstackLength> iCallStack;
+
+        /* Array for storing the reallocation callstack */	
+        TFixedArray <TUint32, KATMaxCallstackLength> iReCallStack;
+
+        /* Array for storing the reallocation callstack */	
+        TFixedArray<TUint32, KATMaxFreeCallstackLength> iFreeCallStack;
+                
+        /* Array of threads using this heap */
+        RArray<TThreadStack> iThreadArray;
+
+        /* A flag for indicating that the RATStorageServer is open */
+        TBool iStorageServerOpen;
+        
+        /* Log option */
+        TUint32 iLogOption;
+
+        /* The process id */
+        TUint iProcessId;	
+        
+        /* Max items on stored call stack when memory allocated */
+        TUint32 iAllocMaxCallStack;
+        
+        /* Max items on stored call stack when memory freed */
+        TUint32 iFreeMaxCallStack;
+        
+    };
+
+// INLINES
+#include "analyzetoolmainallocator.inl"
+
+#endif // ANALYZETOOLMAINALLOCATOR_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,109 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definition for the inline functions of RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#include "analyzetoolmemoryallocator.h"
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::StorageServer()
+// Acquires reference to open RATStorageServer
+// -----------------------------------------------------------------------------
+//
+inline RATStorageServer& RAnalyzeToolMainAllocator::StorageServer()
+    {
+    return iStorageServer;
+    }
+  
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Codeblocks()
+// Acquires reference to process used codeblocks
+// -----------------------------------------------------------------------------
+//  
+inline RArray<TCodeblock>& RAnalyzeToolMainAllocator::Codeblocks()
+    {
+    return iCodeblocks;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Mutex()
+// Acquires reference to mutex which is used to share resources
+// -----------------------------------------------------------------------------
+//  
+inline RMutex& RAnalyzeToolMainAllocator::Mutex()
+    {
+    return iMutex;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ProcessId()
+// Acquires the process id
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeToolMainAllocator::ProcessId()
+    {
+    return iProcessId;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AnalyzeTool()
+// Acquires the logical channel handle
+// -----------------------------------------------------------------------------
+//
+inline RAnalyzeTool& RAnalyzeToolMainAllocator::AnalyzeTool()
+    {
+    return iAnalyzeTool;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::StorageServerOpen()
+// Acquires the iStorageServerOpen variable
+// -----------------------------------------------------------------------------
+//
+inline TBool RAnalyzeToolMainAllocator::StorageServerOpen()
+    {
+    return iStorageServerOpen;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::LogOption()
+// Acquires the iLogOption variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::LogOption()
+    {
+    return iLogOption;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocMaxCallStack()
+// Acquires the iAllocMaxCallStack variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::AllocMaxCallStack()
+    {
+    return iAllocMaxCallStack;
+    }
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::FreeMaxCallStack()
+// Acquires the iFreeMaxCallStack variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::FreeMaxCallStack()
+    {
+    return iFreeMaxCallStack;
+    }
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLMEMORYALLOCATOR_H
+#define ANALYZETOOLMEMORYALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "threadstack.h"
+#include "../../symbian_version.hrh"
+
+// CONSTANTS
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+    #ifndef __WINS__
+    const TInt KDummyHandle = -1000;
+    #endif
+#endif
+
+// CLASS DECLARATION
+
+/**
+*  Abstract class for basic RAnalyzeToolMemoryAllocator funtions
+*/
+class RAnalyzeToolMemoryAllocator : public RAllocator
+    {
+    public:
+    
+        /**
+        * C++ default constructor.
+        * @param aNotFirst Is this first thread using this heap
+        */   
+        RAnalyzeToolMemoryAllocator( TBool aNotFirst );
+        
+        /**
+        * Destructor.
+        */  
+        //lint -e{1510} suppress "base class 'RAllocator' has no destructor"    
+        virtual ~RAnalyzeToolMemoryAllocator();
+        
+        /**
+        * Uninstall the RAnalyzeToolMemoryAllocator
+        */
+        virtual void Uninstall() = 0;
+        
+        /**
+        * Shares the heap for another thread
+        */
+        virtual void ShareHeap() = 0;
+
+    protected:
+
+        /**
+         * Switch original allocator in use.
+         * Switches original allocator in use if not already.
+         */
+        void SwitchOriginalAllocator();
+        
+        /**
+         * Checks is the given address in loaded code memory area.
+         */
+        inline bool IsAddressLoadedCode( TUint32& aAddress );
+        
+        /* The original thread RAllocator */
+        RAllocator* iAllocator;
+        
+        /* Is this the first thread using this heap */
+        TBool iNotFirst;   
+
+        /* Memorymodel */
+        TUint32 iMemoryModel;
+        
+    };
+
+// INLINES
+#include "analyzetoolmemoryallocator.inl"
+
+#endif // ANALYZETOOLMEMORYALLOCATOR_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definition for the inline functions of RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+
+#include <analyzetool/atcommon.h>
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::IsAddressLoadedCode()
+// Checks is the given address in loaded code memory area.
+// -----------------------------------------------------------------------------
+//
+inline bool RAnalyzeToolMemoryAllocator::IsAddressLoadedCode( TUint32& aAddress )
+    {
+    // Debug log strings in this function are not used because
+    // this is called so many times.
+    /*
+     * TMemModelAttributes models.
+     * EMemModelTypeDirect      // direct memory model on hardware
+     * EMemModelTypeMoving=1    // moving memory model on hardware
+     * EMemModelTypeMultiple=2  // multiple memory model on hardware
+     * EMemModelTypeEmul=3      // emulation using single host process
+     * Flexible ?
+     */
+    switch( iMemoryModel )
+        {
+        case EMemModelTypeMultiple:
+            // Use low & high limits which define rofs loading->rom area
+            // in multiple memory model.
+            if ( aAddress < KATMultipleMemoryModelLowLimit 
+              || aAddress > KATMultipleMemoryModelHighLimit )
+                return false;
+            return true;
+        default:
+            return true;
+        }
+    }
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolpanics.pan	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Panic codes and definition of a panic function for the Memory Hook
+*
+*/
+
+
+#ifndef ANALYZETOOLPANICS_PAN_H
+#define ANALYZETOOLPANICS_PAN_H
+
+_LIT( KAnalyzeToolName, "AnalyzeTool" );
+
+/** AnalyzeTool application panic codes */
+enum TAnalyzeToolPanics
+    {
+    ENoMemory = 1,
+    EFailedToCreateHeap,
+    ECantOpenHandle,
+    ECantLoadDevice,
+    ECantAppendToTheArray,
+    ECantFindRightThread,
+    ECantConnectStorageServer,
+    ECantShareStorageServer,
+    ECantCreateMutex,
+    ECantLoadDeviceDriver,
+    ECantConnectDeviceDriver
+    // add further panics here
+    };
+
+inline void AssertPanic(TAnalyzeToolPanics aReason)
+    {
+    User::Panic( KAnalyzeToolName, aReason );
+    }
+
+#endif // ANALYZETOOLPANICS_PAN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/codeblock.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class TCodeblock.
+*
+*/
+
+
+#ifndef CODEBLOCK_H
+#define CODEBLOCK_H
+
+// INCLUDES
+#include <u32std.h>
+
+/**
+*  Stores information of process loaded code segments
+*/
+class TCodeblock
+    {
+    
+    public: // Constructors
+        
+        /**
+        * C++ default constructor.
+        * @param aRunAddress Start address of the memory block. 
+        * @param aSize The size of the memory block.
+        * @param aName The name of the library
+        */
+        TCodeblock( TLinAddr aRunAddress, TUint32 aSize, TBuf8<KMaxLibraryName>& aName );
+
+    public: // New functions
+
+        /**
+        * Checks if the given address is in this memory block area
+        * @param aAddress A address to be checked. 
+        * @return TBool Returns ETrue if the given address is in this
+        *               memory block area, EFalse otherwise
+        */
+        TBool CheckAddress( TUint32 aAddress );
+
+        /**
+        * Matches if the given parameters represents this memory block 
+        * @param aName The name of the library
+        * @return TBool Returns ETrue if the given parameters represents
+        *               this memory block, EFalse otherwise
+        */
+        TBool Match( TBuf8<KMaxLibraryName>& aName );
+        
+    private: // Member variables
+
+        /* Start address of the memory block */
+        TLinAddr iStartAddress;
+
+        /* End address of the memory block */
+        TLinAddr iEndAddress;
+
+        /* End address of the memory block */
+        TBuf8<KMaxLibraryName> iName;
+    };
+
+#endif // CODEBLOCK_H
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/customuser.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,207 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class CustomUser containing overloaded User static functions.
+*
+*/
+
+
+#ifndef CUSTOMUSER_H
+#define CUSTOMUSER_H
+
+// INCLUDES
+#include <u32std.h>
+
+// CONSTANTS
+const TInt KATVersionLength = 20;
+const TInt KATDefaultLogOption = 0;
+const TInt KATDefaultDebug = 1;
+const TInt KATDefaultAllocCallStackSize = 40;
+const TInt KATDefaultFreeCallStackSize = 0;
+    
+// TYPEDEFS
+typedef TBuf<KATVersionLength> TATVersion;
+
+// Argument list for SetupThreadHeap function parameters. (currently not used)
+// When needed, update the argument type directly inside _LIT macro.
+_LIT( KATArgumentList, "%i%i" ); //etc. 
+
+// CLASS DECLARATION
+
+/**
+*  Class which overloads the User functions and provides access to 
+*  the overloaded functions  
+*/
+class CustomUser
+    {
+    public: // Enumerations
+        enum TATOptions
+            {
+            /** Acquiring the log filename */
+            ELogFileName = 1,   
+            /** Acquiring the version number */
+            EVersion,
+            /** Acquiring logging option */
+            ELogOption,
+            /** Acquiring UDEB/UREL information */  
+            EDebug,
+            /** Acquiring max allocation call stack size */
+            EAllocCallStackSize,
+            /** Acquiring max free call stack size */
+            EFreeCallStackSize
+            };
+        
+    public:
+
+        /**
+        * Overloaded version of User::Exit()
+        * Terminates the current thread, specifying a reason. All child 
+        * threads are terminated and all resources are cleaned up.If the 
+        * current thread is the main thread in a process, the process is
+        * also terminated.
+        * @param aReason The reason code.
+        */
+        IMPORT_C static void Exit( TInt aReason );
+
+        /**
+        * Overloaded version of User::Panic()
+        * Panics the current thread, specifying a category name and panic
+        * number. Keep the length of the category name small;
+        * a length of 16 is ideal.
+        * @param aCategory A reference to the descriptor containing the text 
+        * that defines the category for this panic.
+        * @param aReason The panic number. 
+        */   
+        IMPORT_C static void Panic( const TDesC& aCategory, TInt aReason );
+
+        /**
+        * Overloaded version of UserHeap::SetupThreadHeap()
+        * Setups the threads heap.
+        * @param aNotFirst Is this first thread using specified heap
+        * @param aInfo Specifies the thread heap properties
+        * @param aFileName The name of the log file
+        * @param aLogOption The logging option for storage server
+        * @param aIsDebug Determines whether a binary is UDEB or UREL
+        * @param aVersion Atool version number
+        * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+        * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+        * @param aFmt A descriptor containing the format string
+        * @return TInt KErrNone, if the insertion is successful, otherwise 
+        * one of the system wide error codes.
+        */   
+        IMPORT_C static TInt SetupThreadHeap( 
+                             TBool aNotFirst, 
+                             SStdEpocThreadCreateInfo& aInfo,
+                             const TFileName& aFileName,
+                             TUint32 aLogOption, TUint32 aIsDebug,
+                             const TATVersion& aVersion,
+                             TUint32 aAllocCallStackSize,
+                             TUint32 aFreeCallStackSize,
+                             TRefByValue<const TDesC> aFmt, ... );
+                             
+        /**
+        * Overloaded version of UserHeap::SetCritical()
+        * Sets up or changes the effect that termination of the current 
+        * thread has, either on its owning process, or on the whole system.
+        * The precise effect of thread termination is defined by the following
+        *  specific values of the TCritical enum:
+        * ENotCritical
+        * EProcessCritical
+        * EProcessPermanent
+        * ESystemCritical
+        * ESystemPermanent
+        * Notes: The enum value EAllThreadsCritical cannot be set using this
+        * function. It is associated with a process, not a thread, and, if 
+        * appropriate, should be set using User::SetProcessCritical().
+        * The states associated with ENotCritical, EProcessCritical, 
+        * EProcessPermanent, ESystemCritical and ESystemPermanent are all 
+        * mutually exclusive, i.e. the thread can only be in one of these 
+        * states at any one time.
+        * @param aCritical The state to be set.
+        * @return TInt KErrNone, if successful; KErrArgument, if 
+        * EAllThreadsCritical is passed - this is a state associated with a 
+        * process, and you use User::SetProcessCritical() to set it.
+        */ 
+        IMPORT_C static TInt SetCritical( User::TCritical aCritical );
+        
+        /**
+        * Overloaded version of UserHeap::SetCritical()
+        * Sets up or changes the effect that termination of subsequently 
+        * created threads will have, either on the owning process, 
+        * or on the whole system. It is important to note that we are not
+        * referring to threads that have already been created, but threads
+        * that will be created subsequent to a call to this function.
+        * The precise effect of thread termination is defined by the following
+        * specific values of the TCritical enum:
+        * ENotCritical
+        * EAllThreadsCritical
+        * ESystemCritical
+        * ESystemPermanent
+        * Notes:
+        * The enum values EProcessCritical and EProcessPermanent cannot be set
+        * using this function. They are states associated with a thread, not a
+        * process, and, if appropriate, should be set using 
+        * User::SetCritical(). The states associated with ENotCritical, 
+        * EAllThreadsCritical, ESystemCritical and ESystemPermanent are all 
+        * mutually exclusive, i.e. the process can only be in one of these 
+        * states at any one time.
+        * @param aCritical The state to be set.
+        * @return TInt KErrNone, if successful; KErrArgument, if either 
+        * EProcessCritical or EProcessPermanent is passed - these are states
+        * associated with a thread, and you use User::SetCritical() 
+        * to set them.
+        */ 
+        IMPORT_C static TInt SetProcessCritical( User::TCritical aCritical );
+                
+    private: // Private functions
+        
+        /**
+        * Factory function for creating RAllocator instances.
+        * @param aNotFirst Is this first thread using specified heap
+        * @param aLogOption The logging option for storage server
+        * @param aFileName The name of the logging file
+        * @param aIsDebug Determines whether a binary is UDEB or UREL
+        * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+        * @param aFreecallStackSize Max number of stored callstack items when memory freed
+        * @return RAllocator& A reference to created allocator
+        */  
+        static RAllocator& InstallAllocator( TBool aNotFirst,
+                                             const TFileName& aFileName,
+                                             TUint32 aLogOption, TUint32 aIsDebug,
+                                             TUint32 aAllocCallStackSize,
+                                             TUint32 aFreeCallStackSize );
+        
+		/**
+		* Check atool version
+		* @param aVersion - Atool version number.
+		* @param aToolVersion The atool version number
+		* @return KErrNone if correct version found, otherwise one of the system wide 
+		* error codes.
+		*/
+        static TInt CheckVersion( const TATVersion& aVersion, TDes& aToolVersion ); 
+        
+		/**
+		* Function for showing incorrect version information (file or debug channel).
+		* @param aLogOption The logging option
+		* @param aFileName The name of the log file
+		* @param aToolVersion The atool version number
+		*/
+        static void ReportIncorrectVersion( const TUint32 aLogOption, 
+											const TFileName& aFileName,
+											const TDes& aToolVersion );
+        
+    };
+
+#endif // CUSTOMUSER_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/threadstack.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class TThreadStack.
+*
+*/
+
+
+#ifndef THREADSTACK_H
+#define THREADSTACK_H
+
+// INCLUDES
+#include <u32std.h>
+
+// CLASS DECLARATION
+
+/**
+*  Stores thread id and the start of the thread's callstack
+*/
+class TThreadStack
+    {
+    public:
+    
+        /**
+        * C++ default constructor.
+        * @param aId The thread id
+        * @param aStackStart The start of thread's stack
+        */
+        TThreadStack( TThreadId aId, TUint32 aStackStart );
+        
+        /**
+        * Checks if this is the current thread and if this is the current
+        * thread assings value to the given parameter
+        * @param aStackStart& A reference to stack start
+        * @return TBool The start of thread's stack
+        */
+        TBool ThreadStackStart( TUint32& aStackStart );
+       
+        /**
+        * Checks if this the the current thread
+        * @param aThreadId A thread id
+        * @return TBool ETrue it this is the current thread, EFalse otherwise
+        */ 
+        TBool Match( const TUint aThreadId = 0 );
+        
+    private: // Member variables
+    
+        /* The id of the thread */
+        TThreadId iId;
+        
+        /* The start addess of this thread */
+        TUint32 iStackStart;
+    };
+
+
+#endif // THREADSTACK_H
+
+// End of File
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/sis/analyzetoolmemoryhook.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,34 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeToolMemoryHook"},(0xEDF5A8B1),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 1 File to install
+"\epoc32\release\armv5\urel\atoolmemoryhook.dll"-"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll"   -"!:\sys\bin\atoolcleaner.dll"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolallocator.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1014 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class RAnalyzeToolAllocator.
+*
+*/
+
+
+#include "analyzetoolallocator.h"
+#include "analyzetoolmemoryallocator.h"
+#include "atlog.h"
+#include "analyzetoolpanics.pan"
+#include "analyzetoolfastlog.h"
+#include <e32svr.h>
+
+// CONSTANTS
+
+// Length of the callstack address
+const TUint32 KAddressLength = 4;
+
+// Thread count
+const TInt KThreadCount = 1;
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::RAnalyzeToolAllocator()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolAllocator::RAnalyzeToolAllocator( TBool aNotFirst, 
+                                              RATStorageServer& aStorageServer, 
+                                              RArray<TCodeblock>& aCodeblocks, 
+                                              RMutex& aMutex,
+                                              TUint aProcessId,
+                                              RAnalyzeTool& aAnalyzeTool,
+                                              TBool aStorageServerOpen,
+                                              TUint32 aLogOption,
+                                              TUint32 aAllocCallStackSize,
+                                              TUint32 aFreeCallStackSize ) :
+    RAnalyzeToolMemoryAllocator( aNotFirst ),
+    iStorageServer( aStorageServer ), 
+    iCodeblocks( aCodeblocks ), 
+    iMutex( aMutex ),
+    iProcessId( aProcessId ),
+    iThreadArray( KATMaxCallstackLength ),
+    iAnalyzeTool( aAnalyzeTool ),
+    iStorageServerOpen( aStorageServerOpen ),
+    iLogOption( aLogOption ),
+    iAllocMaxCallStack( aAllocCallStackSize ),
+    iFreeMaxCallStack( aFreeCallStackSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::RAnalyzeToolAllocator()" );
+    
+    // Append thread to array of the users of this allocator
+    TThreadParamsBuf params;
+    params().iThreadId = RThread().Id().operator TUint();
+    TInt error = iAnalyzeTool.ThreadStack( params );
+    if ( KErrNone == error )
+        {
+        LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+        LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
+        error = iThreadArray.Append( TThreadStack( RThread().Id(), 
+                             params().iStackAddress + params().iStackSize ) );
+        }
+    
+    __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) ); 
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::~RAnalyzeToolAllocator()" );
+    
+    // Close the thread array 
+    iThreadArray.Close();
+    }
+    
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Uninstall()
+// Uninstalls the current allocator
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Uninstall()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Uninstall()" );
+
+    // Switch back to the original allocator
+    SwitchOriginalAllocator();
+    
+    // Check if this is shared allocator between threads
+    if ( iThreadArray.Count() > KThreadCount )
+        {
+        // Close the shared allocator
+        Close();
+        return;
+        }
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+    #ifndef __WINS__ 
+    // Remove dummy Tls handle
+    UserSvr::DllFreeTls( KDummyHandle );
+    #endif
+#endif
+    
+    // Since this is the last thread using this allocator it can be deleted
+    delete this;
+    }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Alloc() WINS version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+UEXPORT_C TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Alloc memory from the original allocator
+    TAny* p = iAllocator->Alloc( aSize );
+    
+    LOGSTR3( "ATMH RAnalyzeToolAllocator::Alloc() - aSize: %i, address: %x", 
+             aSize,  (TUint32) p );
+    
+    // Don't collect call stack and log data
+    // if storage server not open or logging mode not fast.
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        // Reset the callstack
+        iCallStack.Reset();
+    
+        // Find the current thread callstack start address
+        TUint32 stackstart( 0 );
+        TBool found( FindCurrentThreadStack( stackstart ) );
+        LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+        
+        TUint32 _sp;
+        __asm
+            {
+            mov [_sp], esp
+            }
+        
+        // Get codeblocks count
+        TInt blocksCount( iCodeblocks.Count() );
+        TInt error( KErrNone );
+        TUint arrayCounter = 0;
+        
+        for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+            {
+            TUint32 addr = (TUint32) *( (TUint32*) i );
+            if ( ! IsAddressLoadedCode( addr ) )
+                continue;
+            for ( TInt j = 0; j < blocksCount; j++ )
+                {
+                if ( iCodeblocks[j].CheckAddress( addr ) )
+                    {
+                    // To avoid recursive call to ReAlloc specifying granularity
+                    // Add address to the callstack
+                    iCallStack[arrayCounter] = ( addr );
+                    arrayCounter++;
+                    break;
+                    }
+                }
+            if ( arrayCounter == KATMaxCallstackLength ||
+                 arrayCounter == iAllocMaxCallStack )
+                {
+                LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                break;
+                }
+            }
+        // Log the memory allocation information
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Using fast mode.
+            ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+            }
+        else
+            {
+            // Using storage server.
+            error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+                                                       iCallStack,
+                                                       aSize );
+            if ( KErrNone != error )
+                {
+                LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                switch ( error )
+                    {
+                    case KErrNoMemory:
+                    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
+                    if ( iStorageServerOpen )
+                        {
+                        iStorageServerOpen = EFalse;
+                        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
+                        iStorageServer.Close();
+                        }
+                    break;
+                    }
+                }
+            }
+        }
+    // Release the mutex
+    iMutex.Signal();
+    
+    return p;
+    }
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Alloc() ARMV5 version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Alloc memory from the original allocator
+    TAny* p = iAllocator->Alloc( aSize );
+    
+    // Don't collect call stack and log data
+    // if storage server not open or logging mode not fast.
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        // Reset the callstack
+        iCallStack.Reset(); 
+        
+        // Find the current thread callstack start address
+        TUint32 stackstart( 0 );
+        TBool found( FindCurrentThreadStack( stackstart ) );
+        LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+        
+        // Get codeblocks count
+        TInt blocksCount( iCodeblocks.Count() );
+        TInt error( KErrNone );
+        TUint arrayCounter = 0;
+        
+        for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+            {
+            TUint32 addr = (TUint32) *( (TUint32*) i );
+            if ( ! IsAddressLoadedCode( addr ) )
+                continue;
+            for ( TInt j = 0; j < blocksCount; j++ )
+                {
+                if ( iCodeblocks[j].CheckAddress( addr ) )
+                    {
+                    // To avoid recursive call to ReAlloc specifying granularity
+                    // Add address to the callstack
+                    iCallStack[arrayCounter] = ( addr );
+                    arrayCounter++;
+                    break;
+                    }
+                }
+            if ( arrayCounter == KATMaxCallstackLength ||
+                 arrayCounter == iAllocMaxCallStack )
+                {
+                LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                break;
+                }
+            }
+        // Log the memory allocation information
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Fast mode.
+            ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+            }
+        else
+            {
+            // Using storage server.
+            error = iStorageServer.LogMemoryAllocated( (TUint32) p, 
+                                                        iCallStack, 
+                                                        aSize );
+            if ( KErrNone != error )
+                {
+                LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                switch ( error )
+                    {
+                    case KErrNoMemory:
+                    LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - KErrNoMemory case"  );
+                    if ( iStorageServerOpen )
+                        {
+                        iStorageServerOpen = EFalse;
+                        LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - close iStorageServer"  );
+                        iStorageServer.Close();
+                        }
+                    break;
+                    }
+                }
+            }
+        }
+ 
+    // Release the mutex
+    iMutex.Signal(); 
+    
+    // Return the allocatated memory
+    return p;
+    }
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Free()
+// Frees the allocated memory
+// -----------------------------------------------------------------------------
+//
+TAny RAnalyzeToolAllocator::Free( TAny* aPtr )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Don't collect or log data if storage server not open or logging mode not fast.
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        // Reset the callstack
+        iFreeCallStack.Reset();
+        
+        // Check if trace logging mode because free call stack is not used in other log options.
+        if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+                && iFreeMaxCallStack > 0 )
+            {
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 );
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            TUint32 _sp;
+            
+            #ifdef __WINS__
+                __asm
+                    {
+                    mov [_sp], esp
+                    }
+            #else
+                _sp = __current_sp();
+            #endif
+            
+            // Get codeblocks count
+            TInt blocksCount( iCodeblocks.Count() );
+            TUint arrayCounter = 0;
+        
+            for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                if ( ! IsAddressLoadedCode( addr ) )
+                    continue;
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iFreeCallStack[arrayCounter] = addr;
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                if ( arrayCounter == KATMaxFreeCallstackLength ||
+                     arrayCounter == iFreeMaxCallStack )
+                    {
+                    break;
+                    }
+                }
+            LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
+            }
+        
+        // Log freed memory.
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Using fast mode.
+            ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+            }
+        else
+            {
+            // Using storage server.
+            TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
+            if ( err != KErrNone )
+                {
+                LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
+                }
+            }
+        }
+    
+    // Free the memory using original allocator
+    iAllocator->Free( aPtr ); 
+    
+    LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr );
+    
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Open()
+// Opens this heap for shared access. Opening the heap increases 
+// the heap's access count by one.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Open()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()");
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Share the memory using original allocator
+    TInt error = iAllocator->Open();
+    
+    // If everything is OK add thread to the array which use this allocator
+    if ( KErrNone == error )
+        {
+        TThreadParamsBuf params;
+        params().iThreadId = RThread().Id().operator TUint();
+        error = iAnalyzeTool.ThreadStack( params );
+
+        __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+        if ( KErrNone == error )
+            {
+            LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+            LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
+            iThreadArray.Append( TThreadStack( RThread().Id(), 
+                    params().iStackAddress + params().iStackSize ) );
+            }
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the error code
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Close()
+// Closes this shared heap. Closing the heap decreases the heap's 
+// access count by one.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Close()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Close the memory using original allocator
+    iAllocator->Close();
+    
+    TInt count = iThreadArray.Count();
+    
+    // Iterate through array of threads to remove current thread
+    for ( TInt i = 0; i < count; i++ )
+        {
+        // Check if this is current thread
+        if ( iThreadArray[ i ].Match() )
+            {
+            // Remove the thread
+            iThreadArray.Remove( i );
+            break;
+            }
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Realloc the memory using original allocator
+    TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+    
+    // NULL addresses are not in a process under test
+    if ( ptr && !( aMode & ENeverMove ) )
+        {
+        LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
+                (TUint32)aPtr, (TUint32)ptr );
+        LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
+                aSize, aMode );
+
+        // Don't collect or log data if storage server not open or logging mode fast.
+        if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+            {
+            // Reset the callstack
+            iReCallStack.Reset(); 
+
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 ); 
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            
+            // Get current sp
+            TUint32 _sp( 0 );
+            __asm
+                {
+                mov [_sp], esp
+                }
+            
+            // Get codeblocks count
+            TInt blocksCount( iCodeblocks.Count() );
+            TInt error( KErrNone );
+            TUint arrayCounter = 0;
+            
+            for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                if ( ! IsAddressLoadedCode( addr ) )
+                    continue;
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iReCallStack[arrayCounter] = addr;
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                if ( arrayCounter == KATMaxCallstackLength || 
+                     arrayCounter == iAllocMaxCallStack )
+                    {
+                    LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                    break;
+                    }
+                }
+            
+            // No need to report free if the aPtr was NULL
+            if ( aPtr != NULL )
+                {
+                // Reset the free callstack
+                iFreeCallStack.Reset();
+                
+                // if trace logging mode(s) we also log call stack in free.
+                if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+                        && iFreeMaxCallStack > 0 )
+                    {
+                    for ( TInt i = 0; i < arrayCounter; i++ )
+                        {
+                        if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+                            {
+                            break;
+                            }
+                        iFreeCallStack[i] = iReCallStack[i];
+                        }
+                    }
+                
+                // Try to remove old address from the storage server's
+                // leak array. If found it's removed from the array because system frees
+                // old address directly in the RHeap in ReAlloc case.
+                if ( iLogOption == EATLogToTraceFast )
+                    {
+                    ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+                    }
+                else
+                    {
+                    iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+                    }
+                }
+            
+            // Log the memory allocation information
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                // Using fast mode.
+                ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iFreeCallStack, aSize);
+                }
+            else
+                {
+                // Using storage server.
+                error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
+                                                            iReCallStack, 
+                                                            aSize );
+                if ( KErrNone != error )
+                    {
+                    LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
+                    switch ( error )
+                        {
+                        case KErrNoMemory:
+                        LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
+                        if ( iStorageServerOpen )
+                            {
+                            iStorageServerOpen = EFalse;
+                            LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
+                            iStorageServer.Close();
+                            }
+                        break;
+                        }
+                    }
+                }
+            }
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return pointer to the reallocated cell
+    return ptr; 
+    }
+
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Realloc the memory using original allocator
+    TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+
+    // NULL addresses are not in a process under test
+    if ( ptr && !( aMode & ENeverMove ) )
+        {
+        LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
+                (TUint32)aPtr, (TUint32)ptr );
+        LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
+                aSize, aMode );
+
+        // Don't collect or log data if storage server not open or logging mode fast.
+        if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+            {
+            // Reset the callstack
+            iReCallStack.Reset(); 
+
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 ); 
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            
+            // Get codeblocks count
+            TInt blocksCount( iCodeblocks.Count() );
+            TInt error( KErrNone );
+            TUint arrayCounter = 0;
+            
+            for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                if ( ! IsAddressLoadedCode( addr ) )
+                    continue;
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iReCallStack[arrayCounter] = ( addr );
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                if ( arrayCounter == KATMaxCallstackLength || 
+                     arrayCounter == iAllocMaxCallStack )
+                    {
+                    LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                    break;
+                    }
+                }
+            
+            // No need to report free if the aPtr was NULL
+            if ( aPtr != NULL )
+                {
+                // Reset the free callstack
+                iFreeCallStack.Reset();
+                
+                // if trace logging mode(s) we also log call stack with free.
+                if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+                        && iFreeMaxCallStack > 0 )
+                    {
+                    for ( TInt i = 0; i < arrayCounter; i++ )
+                        {
+                        if ( i == iFreeCallStack.Count() )
+                            {
+                            break;
+                            }
+                        iFreeCallStack[i] = iReCallStack[i];
+                        }
+                    }
+                
+                // Try to remove old address from the storage server's
+                // leak array. If found it's removed from the array because system frees
+                // old address directly in the RHeap in ReAlloc case.
+                if ( iLogOption == EATLogToTraceFast )
+                    {
+                    ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+                    }
+                else
+                    {
+                    iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+                    }
+                }
+        
+            // Log the memory allocation information
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                // Using fast mode.
+                ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+                }
+            else
+                {
+                // Using storage server.
+                error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, 
+                                                            iReCallStack, 
+                                                            aSize );
+                if ( KErrNone != error )
+                    {
+                    LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
+                    switch ( error )
+                        {
+                        case KErrNoMemory:
+                        LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case"  );
+                        if ( iStorageServerOpen )
+                            {
+                            iStorageServerOpen = EFalse;
+                            LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer"  );
+                            iStorageServer.Close();
+                            }
+                        break;
+                        }
+                    }
+                }
+            }
+        }
+
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return pointer to the reallocated cell
+    return ptr; 
+    }
+
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Compress()
+// The function frees excess committed space from the top of the heap.
+// The size of the heap is never reduced below the minimum size 
+// specified during creation of the heap.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Compress()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Compress the memory using original allocator
+    TInt compress = iAllocator->Compress();
+
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return the space reclaimed
+    return compress;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Reset()
+// Frees all allocated cells on this heap. 
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Reset()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Reset the memory using original allocator
+    iAllocator->Reset();
+
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::AllocSize()
+// Gets the number of cells allocated on this heap, and 
+// the total space allocated to them.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt size = iAllocator->AllocSize( aTotalAllocSize );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the number of cells allocated on this heap.
+    return size;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Available()
+// Gets the total free space currently available on the heap and the 
+// space available in the largest free block. The space available 
+// represents the total space which can be allocated. Note that 
+// compressing the heap may reduce the total free space available 
+// and the space available in the largest free block.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt available = iAllocator->Available( aBiggestBlock );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the total free space currently available on the heap
+    return available;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::AllocLen()
+// Gets the length of the available space in the specified 
+// allocated cell.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" ); 
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt len = iAllocator->AllocLen( aCell );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the length of the available space in the allocated cell.
+    return len;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::DebugFunction()
+// Invocates specified debug funtionality.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
+    {
+    LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Invocate debug funtion using original allocator
+    TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
+    
+    switch( aFunc )
+		{  
+		case EMarkEnd:
+			{
+			// Disables the __UHEAP_MARKEND macro
+			LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
+			if ( debug > 0 )
+				{
+				LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
+				// Because there is leaks the alloc panic will occur but
+				// lets return a zero to pretend that everything is OK
+				debug = 0;
+				}
+			}
+		break;
+		
+		default:
+			{
+			}
+		break;
+		}
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return information of the debug function success
+    return debug;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Extension_()
+// Extension function
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0, 
+    TAny* a1 ) 
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Invocate extension funtion using original allocator
+    TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return information of the extension function success
+    return ext;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ShareHeap()
+// Share heap with other thread
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::ShareHeap()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" );
+    
+    // Call the overwrited Open function
+    Open();
+    }
+    
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::FindCurrentThreadStack()
+// Find the current thread which is using the heap
+// -----------------------------------------------------------------------------
+//
+TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart )
+    {
+    LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )", 
+            iThreadArray.Count() );
+    
+    // Flag for indicating that right thread has been found
+    TBool found( EFalse );
+    // If threre is only one thread it must be the right thread
+    if ( iThreadArray.Count() == KThreadCount )
+        {
+        if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+            {
+            // This MUST BE the right thread
+            //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+            }
+        else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+            {
+            found = ETrue;
+            }
+        }
+    else
+        {
+        // Iterate through array to find right thread
+        TInt count( iThreadArray.Count() );
+        
+        for ( TInt i = 0; i < count; i++ )
+            {
+            // Check if this is the right thread
+            if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
+                {
+                // Right thread found. Mark the flag
+                found = ETrue;
+                break;
+                }
+            }
+        // If right thread was not found the panic must be raised
+        if ( !found )
+            {
+            //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+            }
+        }
+    return found;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetooleventhandler.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,230 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CLibraryEventHandler.
+*
+*/
+
+
+// INCLUDE FILES
+#include "atlog.h"
+#include "analyzetooleventhandler.h"
+#include "analyzetooleventhandlernotifier.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolfastlog.h"
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::~CLibraryEventHandler()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CLibraryEventHandler::~CLibraryEventHandler()
+    {
+    LOGSTR1( "ATMH CLibraryEventHandler::~CLibraryEventHandler()" );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::RunL()
+// Process active object's task
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::RunL()
+    {
+    LOGSTR1( "ATMH CLibraryEventHandler::RunL()" );
+
+    if ( KErrNone != iStatus.Int() )
+        {
+        LOGSTR2( "ATMH RunL error: %i",  iStatus.Int() );
+        return;
+        }
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Check that this is observed process 
+    if ( iLibraryInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
+        {
+        LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::ELibraryAdded" );
+        if ( iLibraryInfo.iProcessId == iProcessId )
+            {
+            TInt error( KErrNone );
+
+            // Log library load event.
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                LOGSTR1( "ATMH CLibraryEventHandler::RunL() - ATFastLog.LogDllLoaded() " );
+                ATFastLogDllLoaded( iProcessId,
+                        iLibraryInfo.iLibraryName, 
+                        iLibraryInfo.iRunAddress,
+                        iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+                }
+            else
+                {
+                LOGSTR1( "ATMH CLibraryEventHandler::RunL() - iStorageServer.LogDllLoaded() " );
+                error = iStorageServer.LogDllLoaded( 
+                        iLibraryInfo.iLibraryName, 
+                        iLibraryInfo.iRunAddress,
+                        iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+                LOGSTR2( "ATMH StorageServer error: %i",  error );
+                }
+            if ( KErrNone == error )
+                {
+                iCodeblocks.Append( TCodeblock( iLibraryInfo.iRunAddress, 
+                        iLibraryInfo.iSize, 
+                        iLibraryInfo.iLibraryName ) );
+                }
+            }
+        }
+    else if ( iLibraryInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
+        {
+        LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::ELibraryRemoved " );
+        TInt count = iCodeblocks.Count();
+        LOGSTR2( "ATMH count of code blocks: %i",  count );
+        for ( TInt i = 0; i < count; i++ )
+            {
+            if ( iCodeblocks[ i ].Match( iLibraryInfo.iLibraryName ) )
+                {
+                TBuf8<KMaxLibraryName> libraryName;
+                libraryName.Copy( iLibraryInfo.iLibraryName );
+                
+                // Log library unloaded event
+                if ( iLogOption == EATLogToTraceFast )
+                    {
+                    LOGSTR1( "ATMH CLibraryEventHandler::RunL() - ATFastLogDllUnloaded() " );
+                    ATFastLogDllUnloaded( iProcessId,
+                            libraryName,
+                            iLibraryInfo.iRunAddress, 
+                            iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+                    }
+                else
+                    {
+                    LOGSTR1( "ATMH CLibraryEventHandler::RunL() - iStorageServer.LogDllUnloaded() " );
+                    #ifdef LOGGING_ENABLED
+                    TInt error = iStorageServer.LogDllUnloaded( 
+                            libraryName/*iLibraryInfo.iLibraryName*/, 
+                            iLibraryInfo.iRunAddress, 
+                            iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+    
+                    LOGSTR2( "ATMH StorageServer error: %i",  error );
+                    #else
+                    iStorageServer.LogDllUnloaded( 
+                                                libraryName/*iLibraryInfo.iLibraryName*/, 
+                                                iLibraryInfo.iRunAddress, 
+                                                iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+                    #endif
+                    }
+                iCodeblocks.Remove( i );
+                break;
+                }
+            }
+        }
+    else if ( iLibraryInfo.iEventType == TLibraryEventInfo::EKillThread )
+		{
+		LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::EKillThread" );
+	  
+		iNotifier.RemoveKilledThread( iLibraryInfo.iThreadId );
+    	}
+    
+    Start();
+    
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::DoCancel()
+// Cancels active object's task
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::DoCancel()
+    {
+    LOGSTR1( "ATMH CLibraryEventHandler::DoCancel()" );
+    // Cancel the subscription of the library events
+    if ( IsActive() )
+        {
+        iStarted = EFalse;
+        
+        iAnalyzeTool.CancelLibraryEvent();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::Start()
+// Creates CActiveScheduler and variables for the child thread
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::Start()
+    {
+    LOGSTR1( "ATMH CLibraryEventHandler::Start()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+
+    if ( !IsAdded() )
+        {
+        CActiveScheduler::Add( this );
+        }
+
+    // Cancel current subscribetion
+    if ( IsActive() )
+        {
+        iStarted = EFalse;
+        Cancel();
+        }
+
+    iStatus = KErrNone;
+    iAnalyzeTool.LibraryEvent( iStatus, iLibraryInfo );
+    SetActive();
+    
+    iStarted = ETrue;
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::CLibraryEventHandler()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLibraryEventHandler::CLibraryEventHandler( RAnalyzeTool& aAnalyzeTool, 
+	RArray<TCodeblock>& aCodeblocks, RATStorageServer& aStorageServer, 
+	TUint aProcessId, RMutex& aMutex, 
+	MAnalyzeToolEventhandlerNotifier& aNotifier,
+	TUint32 aLogOption ) 
+ :	CActive( EPriorityNormal ),
+    iAnalyzeTool( aAnalyzeTool ),
+    iCodeblocks( aCodeblocks ),
+    iStorageServer( aStorageServer ),
+    iProcessId( aProcessId ),
+    iMutex( aMutex ),
+    iStarted( EFalse ),
+    iNotifier( aNotifier ),
+    iLogOption( aLogOption )
+    {
+    LOGSTR1( "ATMH CLibraryEventHandler::CLibraryEventHandler()" );
+    }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::IsStarted()
+// Returns eventhandler's state.
+// -----------------------------------------------------------------------------
+//
+TBool CLibraryEventHandler::IsStarted()
+    {
+    LOGSTR2( "ATMH CLibraryEventHandler::IsStarted(%i)", iStarted );
+    
+    return iStarted;
+    }
+    
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolfastlog.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,298 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <e32debug.h> // RDebug
+#include <analyzetool/analyzetooltraceconstants.h>
+#include "analyzetoolfastlog.h"
+#include "atlog.h"
+
+// Local time function.
+TInt64 CurrentTime()
+    {
+    LOGSTR1( "ATFL CurrentTime()" );
+    TTime time;
+    time.UniversalTime();
+    return time.Int64() - KMicroSecondsAt1970;
+    }
+
+TInt ATFastLogProcessStarted( const TDesC8& aProcessName,
+                                 TUint aProcessId,
+                                 TUint32 aIsDebug )
+    {
+    LOGSTR1( "ATFL ATFastLogProcessStarted()" );
+    // Convert process name to 16-bit descriptor.
+    TBuf<KMaxProcessName> processName;
+    processName.Copy( aProcessName );
+    // Buffer to trace.
+    TBuf<KProcessStartBufLength> buffer;
+    // Format process name and id.
+    buffer.Format( KProcessStart16, &processName, aProcessId );
+    // Timestamp.
+    buffer.AppendNum( CurrentTime(), EHex ) ;
+    // Append udeb/urel information to the process start.
+    buffer.Append( KSpaceTrace );  
+    buffer.AppendNum( aIsDebug, EHex );
+    // Append version number.
+    buffer.Append( KSpaceTrace );  
+    buffer.AppendNum( KATTraceVersion, EHex );
+    // Log to trace.
+    RDebug::Print( KTraceMessage, aProcessId ,&buffer );
+    return KErrNone;
+    }
+
+TInt ATFastLogProcessEnded( TUint aProcessId, 
+                            TUint aHandleLeakCount )
+    {
+    LOGSTR1( "ATFL ATFastLogProcessEnded()" );
+    // Handle leaks.
+    if ( aHandleLeakCount > 0 )
+        {
+        // Buffer to trace.
+        TBuf<KHandleLeakBufLength> buffer2;
+        buffer2.Format( KHandleLeak16, &KUnknownModule16, aHandleLeakCount );
+        // Trace it.
+        RDebug::Print( KTraceMessage, aProcessId, &buffer2 );
+        }
+    // Process end trace.
+    TBuf<KProcessEndBufLength> buffer;
+    buffer.Format( KProcessEnd16, aProcessId );
+    buffer.AppendNum( CurrentTime(), EHex);
+    buffer.Append( KNewLineTrace );
+    RDebug::Print( KTraceMessage, aProcessId, &buffer );
+    return KErrNone;
+    }
+
+TInt ATFastLogDllLoaded( TUint aProcessId, 
+                                        const TDesC8& aDllName,
+                                        TUint32 aStartAddress,
+                                        TUint32 aEndAddress )
+    {
+    LOGSTR1( "ATFL ATFastLogDllLoaded()" );
+    // Timestamp.
+    TInt64 time = CurrentTime();
+    // Convert dll name to 16-bit descriptor.
+    TBuf<KMaxLibraryName> dll;
+    dll.Copy( aDllName );
+    // Buffer to trace.
+    TBuf<KDllLoadBufLength> buffer;
+    buffer.Format( KDllLoad16, &dll, time, aStartAddress, aEndAddress );
+    RDebug::Print( KTraceMessage, aProcessId, &buffer );
+    return KErrNone;
+    }
+
+TInt ATFastLogDllUnloaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+                                       TUint32 aEndAddress )
+    {
+    LOGSTR1( "ATFL ATFastLogDllUnloaded()" );
+    // Timestamp.
+    TInt64 time = CurrentTime();
+    // Convert dll name to 16-bit descriptor.
+    TBuf<KMaxLibraryName> dll;
+    dll.Copy( aDllName );
+    // Buffer to trace.
+    TBuf<KDllLoadBufLength> buffer;
+    buffer.Format( KDllUnload16, &dll, time, aStartAddress, aEndAddress );
+    RDebug::Print( KTraceMessage, aProcessId, &buffer );   
+    return KErrNone;
+    }
+
+TInt ATFastLogMemoryAllocated( TUint aProcessId, TUint32 aMemAddress,
+                                  TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+                                  TInt aSize )
+    {
+    LOGSTR1( "ATFL ATFastLogMemoryAllocated()" );
+    // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count> 
+    // <Call stack address> <Call stack address> ...
+    
+    // Timestamp.
+    TInt64 time = CurrentTime();
+    
+    // Trace buffer and pointer to it.
+    TBufC<KMemAllocBufLength> buffer;
+    TPtr ptr( buffer.Des() );
+    // Append the tag implying a memory allocation line in the data file
+    ptr.Append( KMemoryAllocHeader );
+    
+    // Append the start address of this allocation in the 32-bit (max 8 characters)
+    // hexadecimal text format.
+    ptr.AppendNum( aMemAddress, EHex );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    ptr.Append( KSpaceTrace );
+    ptr.AppendNum( time, EHex );
+    
+    // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+    // text format.
+    ptr.Append( KSpaceTrace );
+    ptr.AppendNum( aSize, EHex );
+    
+    // Search call stack for address count.
+    TInt addrCount(0);
+    for ( TInt j = 0; j < aCallstack.Count() ; j++ )
+        {
+        if ( aCallstack.At(j) == 0 )
+            break;
+        addrCount++;
+        }
+    // Current position in call stack.
+    TInt addrPos( 0 );
+    
+    // Append address count.
+    ptr.Append( KSpaceTrace );
+    ptr.AppendNum( addrCount, EHex );
+            
+    // Calculate last item length
+    TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
+            KSpaceLength + KNewlineLength );
+    
+    TUint packetNumber( 1 );
+    
+    // Go through all call stack's memory addresses associated with
+    // this memory allocation 
+    for ( TInt j = 0; j < addrCount; j++ )
+        {
+        // ALLOCF <Memory address> <Time stamp> <Packet number> 
+        // <Call stack address> <Call stack address> ...
+        if ( ptr.Length() <= 0 )
+            {               
+            // Create alloc fragment message header
+            ptr.Append( KMemoryAllocFragment );
+            ptr.AppendNum( aMemAddress, EHex );
+            ptr.Append( KSpaceTrace );
+            ptr.AppendNum( time, EHex );
+            ptr.Append( KSpaceTrace );        
+            ptr.AppendNum( packetNumber, EHex );
+            // Increase packet number
+            packetNumber++;
+            }
+      
+        // Append call stack address.
+        ptr.AppendFormat( KHexaNumberTrace, aCallstack.At( addrPos ) );
+        
+        // Move the call stack position.
+        addrPos++;
+        
+        // Check if buffer max length exceed
+        if ( lastItemLength + ptr.Length() >= KMemAllocBufLength )
+            {
+            ptr.Append( KNewLineTrace );
+            // Log through debug channel 
+            RDebug::Print( KTraceMessage, aProcessId, &buffer );
+            // Empty trace buffer
+            ptr.Delete( 0, ptr.MaxLength() );
+            }
+        }
+    // Send last message if exists.
+    if ( ptr.Length() > 0 )
+        {
+        ptr.Append( KNewLineTrace );
+        RDebug::Print( KTraceMessage, aProcessId, &buffer);
+        }
+    return KErrNone;
+    }
+
+
+TInt ATFastLogMemoryFreed( TUint aProcessId, TUint32 aMemAddress, 
+                              TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack )
+    {
+    LOGSTR1( "ATFL ATFastLogMemoryFreed()" );
+    // FREEH <Memory address> <Time tamp> <Call stack address count> <Call stack address>
+    // <Call stack address> ...
+    
+    // Timestamp.
+    TInt64 time = CurrentTime();
+    
+    // Trace buffer and pointer to it.
+    TBufC<KMemFreedBufLength> buffer;
+    TPtr ptr( buffer.Des() );
+ 
+    // Append the tag implying a memory allocation line in the data file
+    ptr.Append( KMemoryFreedHeader );
+    
+    // Append the start address of this allocation in the 32-bit (max 8 characters)
+    // hexadecimal text format.
+    ptr.AppendNum( aMemAddress, EHex );
+    
+    // Append timestamp;
+    ptr.Append( KSpaceTrace );
+    ptr.AppendNum( time, EHex);
+    
+    // Search call stack for address count.
+    TInt addrCount(0);
+    for ( TInt j = 0; j < aFreeCallstack.Count() ; j++ )
+        {
+        if ( aFreeCallstack.At(j) == 0 )
+            break;
+        addrCount++;
+        }
+    // Current position in call stack.
+    TInt addrPos( 0 );
+    
+    // Append address count.
+    ptr.Append( KSpaceTrace );
+    ptr.AppendNum( addrCount, EHex );
+            
+    // Calculate last item length
+    TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
+            KSpaceLength + KNewlineLength );
+    
+    TUint packetNumber( 1 );
+    
+    // Go through all call stack's memory addresses associated with
+    // this memory allocation 
+    for ( TInt j = 0; j < addrCount; j++ )
+        {
+        // ALLOCF <Memory address> <Time stamp> <Packet number> 
+        // <Call stack address> <Call stack address> ...
+        if ( ptr.Length() <= 0 )
+            {               
+            // Create alloc fragment message header
+            ptr.Append( KMemoryFreedFragment );
+            ptr.AppendNum( aMemAddress, EHex );
+            ptr.Append( KSpaceTrace );
+            ptr.AppendNum( packetNumber, EHex );
+            // Increase packet number
+            packetNumber++;
+            }
+      
+        // Append call stack address.
+        ptr.AppendFormat( KHexaNumberTrace, aFreeCallstack.At( addrPos ) );
+        
+        // Move the call stack position.
+        addrPos++;
+        
+        // Check if buffer max length exceed
+        if ( lastItemLength + ptr.Length() >= KMemFreedBufLength )
+            {
+            ptr.Append( KNewLineTrace );
+            // Log through debug channel 
+            RDebug::Print( KTraceMessage, aProcessId, &buffer );
+            // Empty trace buffer
+            ptr.Delete( 0, ptr.MaxLength() );
+            }
+        }
+    // Send last message if exists.
+    if ( ptr.Length() > 0 )
+        {
+        ptr.Append( KNewLineTrace );
+        RDebug::Print( KTraceMessage, aProcessId, &buffer);
+        }
+    return KErrNone;   
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolmainallocator.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1509 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#include "analyzetoolmainallocator.h"
+#include "atlog.h"
+#include "analyzetooleventhandler.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "analyzetoolfastlog.h"
+#include <e32svr.h>
+
+
+// CONSTANTS
+
+// The name of the memoryhook dll
+_LIT8( KMemoryHook, "AToolMemoryHook.dll" );
+
+// The name of the storage server dll
+_LIT8( KStorageServer, "AToolStorageServerClnt.dll" );
+
+// Length of the callstack address
+const TUint32 KAddressLength = 4;
+
+// Thread count
+const TInt KThreadCount = 1;
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator( TBool aNotFirst, 
+    const TFileName aFileName, TUint32 aLogOption, TUint32 aIsDebug,
+    TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize ) :
+    RAnalyzeToolMemoryAllocator( aNotFirst ),
+    iAnalyzeToolOpen( EFalse ),
+    iDeviceDriverLoaded( EFalse ),
+    iCodeblocks( KATMaxCallstackLength ),
+    iThreadArray( KATMaxCallstackLength ),
+    iLogOption( aLogOption ),
+    iProcessId( RProcess().Id().operator TUint() ),
+    iAllocMaxCallStack( aAllocCallStackSize ),
+    iFreeMaxCallStack( aFreeCallStackSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()" );
+
+    // Basic error variable used in method.
+    TInt error( KErrNone );
+    
+    // Connect to the storage server if logging mode not fast trace.
+    if ( iLogOption != EATLogToTraceFast )
+        {
+        error = iStorageServer.Connect();
+
+        LOGSTR2( "ATMH Opening RATStorageServer error %i", error );
+    
+        if ( KErrNone == error )
+            {
+            iStorageServerOpen = ETrue;
+            }
+        else
+            {
+            iStorageServerOpen = EFalse;
+            }
+    
+        if ( KErrNone == error )
+            {
+            // Make the storage server handle shared between threads
+            error = iStorageServer.ShareAuto();
+            }
+    
+        LOGSTR2( "ATMH Sharing RATStorageServer error %i", error );
+        }
+    
+    // Create mutex for schedule access to shared resources
+    error = iMutex.CreateLocal();
+
+    __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantCreateMutex ) );
+
+    LOGSTR2( "ATMH Creating mutex error %i", error );
+
+    // Load the kernel side device driver
+    error = User::LoadLogicalDevice( KAnalyzeToolLddName );
+
+    if ( error != KErrNone && error != KErrAlreadyExists )
+        {
+        __ASSERT_ALWAYS( EFalse, AssertPanic( ECantLoadDeviceDriver ) );
+        }
+    else
+        {
+        iDeviceDriverLoaded = ETrue;
+        }
+
+    LOGSTR2( "ATMH Loading device driver error %i", error );
+
+    // Open handle to the kernel sidedevice driver
+    error = iAnalyzeTool.Open();
+
+    __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantConnectDeviceDriver ) );
+
+    if ( KErrNone == error )
+        {
+        iAnalyzeToolOpen = ETrue;
+        }
+
+    LOGSTR2( "ATMH Opening RAnalyzeTool handle %i error", error );
+
+    // Set memory model by asking kernel side device driver
+    if ( iAnalyzeToolOpen )
+        {
+        TATMemoryModelBuf model;
+        if ( KErrNone == iAnalyzeTool.GetMemoryModel( model ) )
+            {
+            iMemoryModel = model().iMemoryModel;
+            LOGSTR2( "ATMH AnalyzeTool MemoryModel: %i", iMemoryModel );
+            }
+        else
+            LOGSTR2( "ATMH AnalyzeTool GetMemoryModel error: %i", error );
+        }
+    
+    // Retrieve the initial process information
+    LogProcessInformation( aFileName, aLogOption, aIsDebug );
+
+    // Create handler for receiving kernel events
+    iEventHandler = new CLibraryEventHandler( iAnalyzeTool,
+                                              iCodeblocks,
+                                              iStorageServer,
+                                              iProcessId,
+                                              iMutex, 
+                                              *this,
+                                              aLogOption);
+
+    __ASSERT_ALWAYS( iEventHandler != NULL, AssertPanic( ENoMemory ) );
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()" );
+
+    TUint handleLeakCount( 0 );
+    if ( iAnalyzeToolOpen && iThreadArray.Count() > 0 )
+        {
+        TProcessHandleInfoBuf params;
+        params().iProcessId = iProcessId;
+        TInt error( iAnalyzeTool.GetProcessHandleInfo( params ) );
+        handleLeakCount = params().iThreadHandleCount;
+        }
+
+    // Close handle for process memory blocks
+    iCodeblocks.Close();
+
+    // Delete the eventhandler
+    delete iEventHandler;
+
+    // The count of device driver users
+    TClientCountBuf count;
+
+    // Check the flag
+    if ( iAnalyzeToolOpen )
+        {
+        TInt error  = iAnalyzeTool.ClientCount( count );
+        LOGSTR2( "ATMH closing analyze tool handle error: %i", error );
+        iAnalyzeTool.Close();
+        }
+
+    // Check the flag
+    if ( iDeviceDriverLoaded )
+        {
+        LOGSTR2( "ATMH device driver client count: %i", count().iClientCount );
+
+        // Check if there is another user for device driver
+        if ( count().iClientCount <= 1 )
+            {
+            // There was no other users -> unload the device driver
+            TInt error = User::FreeLogicalDevice( KAnalyzeToolLddName );
+            LOGSTR2( "ATMH Unloading ldd error: %i", error );
+            }
+        }
+    
+    // Close the thread array
+    iThreadArray.Close();
+
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            LOGSTR1( "ATMH ATFastLogProcessEnded()" );
+            ATFastLogProcessEnded( iProcessId, handleLeakCount );
+            }
+        else
+            {
+            iStorageServerOpen = EFalse;
+            // Inform that process has ended and close the handle
+            LOGSTR1( "ATMH iStorageServer.LogProcessEnded()" );
+            iStorageServer.LogProcessEnded( iProcessId, handleLeakCount );
+            // Close the handle
+            iStorageServer.Close();
+            }
+        }
+    
+    // Close the mutex
+    iMutex.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ShareHeap()
+// Share heap with other thread
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::ShareHeap()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ShareHeap()" );
+
+    // Call the overwrited Open function
+    Open();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Uninstall()
+// Uninstalls the current allocator
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Uninstall()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    TMainThreadParamsBuf params;
+    params().iProcessId = iProcessId;
+    iAnalyzeTool.MainThreadAlloctor( params );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Check if this is shared allocator between threads
+    if ( iThreadArray.Count() > KThreadCount && !params().iAlone )
+        {
+        // Close the shared allocator
+        Close();
+        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall() - Close called" );
+        return;
+        }
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+    #ifndef __WINS__ 
+    // Remove dummy Tls handle
+    UserSvr::DllFreeTls( KDummyHandle );
+    #endif
+#endif
+    
+    // Since this is the last thread using this allocator it can be deleted
+    delete this;
+    }
+
+#ifdef __WINS__
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Alloc() WINS version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+UEXPORT_C TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Alloc memory from the original allocator
+    TAny* p = iAllocator->Alloc( aSize );
+
+    LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x", 
+            aSize,  (TUint32) p );
+
+    // Don't collect or log data if storage server not open or logging mode fast.
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        TInt error( KErrNone );
+        
+        // Check if eventhandler is started already
+        if ( !iEventHandler->IsStarted() )
+            {
+            // Install the eventhandler if needed
+            InstallEventHandler();
+            }
+        
+        // Reset the callstack
+        iCallStack.Reset();
+
+        // If we don't want any call stack to be saved skip the next part
+        if( iAllocMaxCallStack > 0 )
+            {
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 );
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            
+            // Returns the value of the stack pointer at the 
+            // current point in your program.
+            TUint32 _sp;
+            __asm
+                {
+                mov [_sp], esp
+                }
+            
+            // Get process loaded code segments count
+            TInt blocksCount( iCodeblocks.Count() );
+            TUint arrayCounter = 0;
+            
+            // Iterate through callstack to find wanted callstack addresses
+            // - Start: current stack address
+            // - Stop: stack start address(Run-address of user stack)
+            // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+            for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                
+                // Checks is the given address in loaded code memory area.
+                if ( !IsAddressLoadedCode( addr ) )
+                    continue;
+                
+                // Iterate through array of code blocks to check if address is in code segment area 
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    // Checks if the given address is in this memory block area
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iCallStack[arrayCounter] = ( addr );
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                
+                // Checks if the wanted callstack items are gathered
+                if ( arrayCounter == KATMaxCallstackLength ||
+                     arrayCounter == iAllocMaxCallStack )
+                    {
+                    LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                    break;
+                    }
+                } 
+            }
+
+        // Log the memory allocation information
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Using fast mode.
+            ATFastLogMemoryAllocated( iProcessId, (TUint32) p , iCallStack, aSize );
+            }
+        else
+            {
+            // Using storage server.
+            error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+                                                       iCallStack,
+                                                       aSize );
+            if ( KErrNone != error )
+                {
+                switch ( error )
+                    {
+                    case KErrNoMemory:
+                        {
+                        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
+                        // Check if eventhandler is active
+                        if ( iEventHandler->IsActive() )
+                            {
+                            // Cancel iEventHandler because not needed anymore
+                            iEventHandler->Cancel();
+                            }
+                        if ( iStorageServerOpen )
+                            {
+                            // Close storage server
+                            iStorageServerOpen = EFalse;
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
+                            iStorageServer.Close();
+                            }
+                        break;
+                        }
+                    default:
+                        {
+                        LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                        break;
+                        }
+                    }
+                }
+            }
+        }
+    // Release the mutex
+    iMutex.Signal();
+
+    return p;
+    }
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Alloc() ARMV5 version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()"  );
+
+    // acquire the mutex
+    iMutex.Wait();
+
+    // Alloc memory from the original allocator
+    TAny* p = iAllocator->Alloc( aSize );
+
+    LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x", 
+            aSize,  (TUint32) p );
+
+    TInt error( KErrNone );
+    
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        // Check if eventhandler is active already
+        // IsActive might return false value if a tested software has created many
+        // threads which install own CActiveScheduler.
+        if ( !iEventHandler->IsStarted() )
+            {
+            // Install the eventhandler if needed
+            InstallEventHandler();
+            }
+        
+        // Reset the callstack
+        iCallStack.Reset();
+        
+        // If we don't want any call stack to be saved skip the next part
+        if( iAllocMaxCallStack > 0 )
+            {
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 );
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            
+            // Get process loaded code segments count
+            TInt blocksCount( iCodeblocks.Count() );            
+            TUint arrayCounter = 0;
+            
+            // Iterate through callstack to find wanted callstack addresses
+            // - Start: current stack address(__current_sp(): Returns the value of the 
+            //      stack pointer at the current point in your program.)
+            // - Stop: stack start address(Run-address of user stack)
+            // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+            for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                
+                // Checks is the given address in loaded code memory area.
+                if ( !IsAddressLoadedCode( addr ) )
+                    continue;
+                
+                // Iterate through array of code blocks to check if address is in code segment area 
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    // Checks if the given address is in this memory block area
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iCallStack[arrayCounter] = ( addr );
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                
+                // Checks if the wanted callstack items are gathered
+                if ( arrayCounter == KATMaxCallstackLength ||
+                     arrayCounter == iAllocMaxCallStack )
+                    {
+                    LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                    break;
+                    }
+                }
+            }
+        // Log the memory allocation information
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Using fast mode.
+            ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+            }
+        else
+            {
+            // Using storage server.
+            error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+                                                       iCallStack,
+                                                       aSize );
+            if ( KErrNone != error )
+                {
+                switch ( error )
+                    {
+                    case KErrNoMemory:
+                        {
+                        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case"  );
+                        // Check if eventhandler is active
+                        if ( iEventHandler->IsActive() )
+                            {
+                            // Cancel ieventhandler because not needed anymore
+                            iEventHandler->Cancel();
+                            }
+                        if ( iStorageServerOpen )
+                            {
+                            // Close storage server
+                            iStorageServerOpen = EFalse;
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer"  );
+                            iStorageServer.Close();
+                            }
+                        break;
+                        }
+                    default:
+                        {
+                        LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                        break;
+                        }
+                    }
+                }
+            }
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return the allocatated memory
+    return p;
+    }
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Free()
+// Frees the allocated memory
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Free( TAny* aPtr )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Free()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+        {
+        // Reset the callstack
+        iFreeCallStack.Reset();
+        
+        // Check if trace logging mode
+        // Also if we don't want any call stack to be stored skip the next part
+        if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+                && iFreeMaxCallStack > 0 )
+            {
+            // Find the current thread callstack start address
+            TUint32 stackstart( 0 );
+            TBool found( FindCurrentThreadStack( stackstart ) );
+            LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+            TUint32 _sp;
+            
+            // Returns the value of the stack pointer at the 
+            // current point in your program.
+            #ifdef __WINS__
+                __asm
+                    {
+                    mov [_sp], esp
+                    }
+            #else
+                _sp = __current_sp();
+            #endif
+            
+            // Get process loaded code segments count
+            TInt blocksCount( iCodeblocks.Count() );
+            TUint arrayCounter = 0;
+            
+            // Iterate through callstack to find wanted callstack addresses
+            // - Start: current stack address
+            // - Stop: stack start address(Run-address of user stack)
+            // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)            
+            for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                {
+                TUint32 addr = (TUint32) *( (TUint32*) i );
+                // Checks is the given address in loaded code memory area.
+                if ( ! IsAddressLoadedCode( addr ) )
+                    continue;
+                
+                // Iterate through array of code blocks to check if address is in code segment area 
+                for ( TInt j = 0; j < blocksCount; j++ )
+                    {
+                    // Checks if the given address is in this memory block area
+                    if ( iCodeblocks[j].CheckAddress( addr ) )
+                        {
+                        // To avoid recursive call to ReAlloc specifying granularity
+                        // Add address to the callstack
+                        iFreeCallStack[arrayCounter] = addr;
+                        arrayCounter++;
+                        break;
+                        }
+                    }
+                // Checks if the wanted callstack items are gathered
+                if ( arrayCounter == KATMaxFreeCallstackLength ||
+                     arrayCounter == iFreeMaxCallStack )
+                    {
+                    break;
+                    }
+                }
+            LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
+            }
+        // Log the memory free information.
+        if ( iLogOption == EATLogToTraceFast )
+            {
+            // Using fast mode.
+            ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+            }
+        else
+            {
+            // Using storage server.
+            TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
+            if ( err != KErrNone )
+                {
+                LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
+                }
+            }
+        }
+    
+    // Free the memory using original allocator
+    iAllocator->Free( aPtr );
+
+    LOGSTR2( "ATMH RAnalyzeToolMainAllocator::Free() - aPtr: %x", (TUint32)aPtr );
+
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Open()
+// Opens this heap for shared access. Opening the heap increases
+// the heap's access count by one.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Open()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Open() " );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Share the memory using original allocator
+    TInt error = iAllocator->Open();
+
+    // If everything is OK add thread to the array which use this allocator
+    if ( KErrNone == error )
+        {
+        TThreadParamsBuf params;
+        params().iThreadId = RThread().Id().operator TUint();
+        error = iAnalyzeTool.ThreadStack( params );
+
+        __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+        if ( KErrNone == error )
+            {
+            LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+            LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
+            iThreadArray.Append( TThreadStack( RThread().Id(),
+                    params().iStackAddress + params().iStackSize ) );
+            }
+        }
+
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return the error code
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Close()
+// Closes this shared heap. Closing the heap decreases the heap's
+// access count by one.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Close()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Close the memory using original allocator
+    iAllocator->Close();
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - allocator closed" );
+    TInt count = iThreadArray.Count();
+
+    // Iterate through array of threads to remove current thread
+    for ( TInt i = 0; i < count; i++ )
+        {
+        // Check if this is current thread
+        if ( iThreadArray[ i ].Match() )
+            {
+            // Remove the thread
+            iThreadArray.Remove( i );
+            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - thread removed" );
+            break;
+            }
+        }
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - about to mutex signal" );
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Realloc the memory using original allocator
+    TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+    
+    // NULL addresses are not in a process under test
+    if ( ptr && !( aMode & ENeverMove ) )
+        {
+        LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
+                (TUint32)aPtr, (TUint32)ptr );
+        LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i", 
+                aSize, aMode );
+      
+        // Don't collect or log data if storage server not open or logging mode is not fast.
+        if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+            {
+            TInt error( KErrNone );
+            TUint arrayCounter = 0;
+            
+            // Reset the callstack
+            iReCallStack.Reset();
+            
+            // If we don't want any call stack to be saved skip the next part
+            if( iAllocMaxCallStack > 0 )
+                {
+                // Find the current thread callstack start address
+                TUint32 stackstart( 0 );
+                TBool found( FindCurrentThreadStack( stackstart ) );
+                LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
+    
+                // Returns the value of the stack pointer at the 
+                // current point in your program.
+                TUint32 _sp( 0 );
+                __asm
+                    {
+                    mov [_sp], esp
+                    }
+                
+                // Get process loaded code segments count
+                TInt blocksCount( iCodeblocks.Count() );
+                
+                // Iterate through callstack to find wanted callstack addresses
+                // - Start: current stack address
+                // - Stop: stack start address(Run-address of user stack)
+                // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)                
+                for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                    {
+                    TUint32 addr = (TUint32) *( (TUint32*) i );
+                    // Checks is the given address in loaded code memory area.
+                    if ( ! IsAddressLoadedCode( addr ) )
+                        continue;
+                    
+                    // Iterate through array of code blocks to check if address is in code segment area 
+                    for ( TInt j = 0; j < blocksCount; j++ )
+                        {
+                        // Checks if the given address is in this memory block area
+                        if ( iCodeblocks[j].CheckAddress( addr ) )
+                            {
+                            // To avoid recursive call to ReAlloc specifying granularity
+                            // Add address to the callstack
+                            iReCallStack[arrayCounter] = addr;
+                            arrayCounter++;
+                            break;
+                            }
+                        }
+                    // Checks if the wanted callstack items are gathered
+                    if ( arrayCounter == KATMaxCallstackLength || 
+                         arrayCounter == iAllocMaxCallStack )
+                        {
+                        LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                        break;
+                        }
+                    }
+                }
+            
+            // No need to report free if the aPtr was NULL
+            if ( aPtr != NULL )
+                {
+                // Reset the free callstack
+                iFreeCallStack.Reset();
+                
+                // Check that logging mode is trace/trace fast so we use free call stack 
+                // and call stack size bigger than zero
+                if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast ) && iFreeMaxCallStack > 0 )
+                    {
+                    for ( TInt i = 0; i < arrayCounter; i++ )
+                        {
+                        if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+                            {
+                            break;
+                            }
+                        iFreeCallStack[i] = iReCallStack[i];
+                        }
+                    }
+                // Try to remove old address from the storage server's
+                // leak array. If found. it's removed from the array because system frees
+                // old address directly in the RHeap in ReAlloc case.
+                if ( iLogOption == EATLogToTraceFast )
+                    {
+                    ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+                    }
+                else
+                    {
+                    iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+                    }
+                }
+            // Log the memory allocation information
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                // Using fast logging mode.
+                ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+                }
+            else
+                {
+                // Using storage server.
+                error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+                                                           iReCallStack,
+                                                           aSize );
+                if ( KErrNone != error )
+                    {
+                    switch ( error )
+                        {
+                        case KErrNoMemory:
+                            {
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case"  );
+                            // Check if eventhandler is active
+                            if ( iEventHandler->IsActive() )
+                                {
+                                // Cancel iEventHandler because not needed anymore
+                                iEventHandler->Cancel();
+                                }
+                            if ( iStorageServerOpen )
+                                {
+                                // Close storage server
+                                iStorageServerOpen = EFalse;
+                                LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer"  );
+                                iStorageServer.Close();
+                                }
+                            break;
+                            }
+                        default:
+                            {
+                            LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                            break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return pointer to the reallocated cell
+    return ptr;
+    }
+
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Realloc the memory using original allocator
+    TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+    
+    TInt error( KErrNone );
+    TUint arrayCounter = 0;
+    
+    // NULL addresses are not in a process under test
+    if ( ptr && !( aMode & ENeverMove ) )
+        {
+        LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
+                (TUint32)aPtr, (TUint32)ptr );
+        LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i", 
+                aSize, aMode );
+ 
+        // Don't collect or log data if storage server not open or logging mode is not fast.
+        if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+            {
+            // Reset the callstack
+            iReCallStack.Reset();
+            
+            // If we don't want any call stack to be saved skip the next part
+            if( iAllocMaxCallStack > 0 )
+                {
+                // Find the current thread callstack start address
+                TUint32 stackstart( 0 );
+                TBool found( FindCurrentThreadStack( stackstart ) );
+                LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
+                
+                // Get process loaded code segments count
+                TInt blocksCount( iCodeblocks.Count() );
+                
+                // Iterate through callstack to find wanted callstack addresses
+                // - Start: current stack address(__current_sp(): Returns the value of the 
+                //      stack pointer at the current point in your program.)
+                // - Stop: stack start address(Run-address of user stack)
+                // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+                for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+                    {
+                    TUint32 addr = (TUint32) *( (TUint32*) i );
+                    
+                    // Checks is the given address in loaded code memory area.
+                    if ( !IsAddressLoadedCode( addr ) )
+                        continue;
+                                
+                    // Iterate through array of code blocks to check if address is in code segment area 
+                    for ( TInt j = 0; j < blocksCount; j++ )
+                        {
+                        // Checks if the given address is in this memory block area
+                        if ( iCodeblocks[j].CheckAddress( addr ) )
+                            {
+                            // To avoid recursive call to ReAlloc specifying granularity
+                            // Add address to the callstack
+                            iReCallStack[arrayCounter] = ( addr );
+                            arrayCounter++;
+                            break;
+                            }
+                        }
+                    // Checks if the wanted callstack items are gathered
+                    if ( arrayCounter == KATMaxCallstackLength || 
+                         arrayCounter == iAllocMaxCallStack )
+                        {
+                        LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+                        break;
+                        }
+                    }
+                }
+            
+            // No need to report free if the aPtr was NULL
+            if ( aPtr != NULL )
+                {
+                // Reset the free callstack
+                iFreeCallStack.Reset();
+                
+                // Check that logging mode is trace/trace fast so we use free call stack 
+                // and call stack size bigger than zero
+                if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+                        && iFreeMaxCallStack > 0 )
+                    {
+                    for ( TInt i = 0; i < arrayCounter; i++ )
+                        {
+                        if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+                            {
+                            break;
+                            }
+                        iFreeCallStack[i] = ( iReCallStack[i] );
+                        }
+                    }
+                
+                // Try to remove old address from the storage server's
+                // leak array. If found. it's removed from the array because system frees
+                // old address directly in the RHeap in ReAlloc case.
+                if ( iLogOption == EATLogToTraceFast )
+                    {
+                    ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+                    }
+                else
+                    {
+                    iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+                    }
+                }
+            
+            // Log the memory allocation information
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                // Using fast logging mode.
+                ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+                }
+            else
+                {
+                // Using storage server.
+                error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+                                                        iReCallStack,
+                                                        aSize );
+                if ( KErrNone != error )
+                    {
+                    switch ( error )
+                        {
+                        case KErrNoMemory:
+                            {
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case"  );
+                            // Check if eventhandler is active
+                            if ( iEventHandler->IsActive() )
+                                {
+                                // Cancel iEventHandler because not needed anymore
+                                iEventHandler->Cancel();
+                                }
+                            if ( iStorageServerOpen )
+                                {
+                                // Close storage server
+                                iStorageServerOpen = EFalse;
+                                LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer"  );
+                                iStorageServer.Close();
+                                }
+                            break;
+                            }
+                        default:
+                            {
+                            LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+                            break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return pointer to the reallocated cell
+    return ptr;
+    }
+
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Compress()
+// The function frees excess committed space from the top of the heap.
+// The size of the heap is never reduced below the minimum size
+// specified during creation of the heap.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Compress()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Compress()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Compress the memory using original allocator
+    TInt compress = iAllocator->Compress();
+
+    // Release the mutex
+    iMutex.Signal();
+
+    // Return the space reclaimed
+    return compress;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Reset()
+// Frees all allocated cells on this heap.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Reset()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Reset()" );
+
+    // Acquire the mutex
+    iMutex.Wait();
+
+    // Reset the memory using original allocator
+    iAllocator->Reset();
+
+    // Release the mutex
+    iMutex.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocSize()
+// Gets the number of cells allocated on this heap, and
+// the total space allocated to them.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::AllocSize( TInt& aTotalAllocSize ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocSize()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt size = iAllocator->AllocSize( aTotalAllocSize );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the number of cells allocated on this heap.
+    return size;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Available()
+// Gets the total free space currently available on the heap and the
+// space available in the largest free block. The space available
+// represents the total space which can be allocated. Note that
+// compressing the heap may reduce the total free space available
+// and the space available in the largest free block.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Available( TInt& aBiggestBlock ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Available()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt available = iAllocator->Available( aBiggestBlock );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the total free space currently available on the heap
+    return available;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocLen()
+// Gets the length of the available space in the specified
+// allocated cell.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::AllocLen( const TAny* aCell ) const
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocLen()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Acquire the memory information using original allocator
+    TInt len = iAllocator->AllocLen( aCell );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return the length of the available space in the allocated cell.
+    return len;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::DebugFunction()
+// Invocates specified debug funtionality.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
+    {
+    LOGSTR2( "ATMH RAnalyzeToolMainAllocator::DebugFunction() %i", aFunc );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Invocate debug funtion using original allocator
+    TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
+    
+    switch( aFunc )
+        {  
+        case EMarkEnd:
+            {
+            // Disables the __UHEAP_MARKEND macro
+            LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
+            if ( debug > 0 )
+                {
+                LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
+                // Because there is leaks the alloc panic will occur but
+                // lets return a zero to pretend that everything is OK
+                debug = 0;
+                }
+            }
+        break;
+        
+        default:
+            {
+            }
+        break;
+        }
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return information of the debug function success
+    return debug;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::RemoveKilledThread()
+// Remove killed thread from threads array.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::RemoveKilledThread( const TUint aThreadId  )
+    {
+    LOGSTR2( "ATMH RAnalyzeToolMainAllocator::RemoveKilledThread(%i)", 
+            aThreadId );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Iterate through array of threads to remove current thread
+    TInt count( iThreadArray.Count() );
+    LOGSTR2( "ATMH > iThreadArray.Count() %i", count );
+    
+    for ( TInt i = 0; i < count; i++ )
+        {
+        // Check if this is current thread
+        if ( iThreadArray[ i ].Match( aThreadId ) )
+            {
+            // Remove the thread
+            iThreadArray.Remove( i );
+            LOGSTR1( "ATMH > thread removed" );
+            break;
+            }
+        }
+
+    // Release the mutex
+    iMutex.Signal();
+    }
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Extension_()
+// Extension function
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Extension_( TUint aExtensionId, TAny*& a0,
+    TAny* a1)
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Extension_()" );
+    
+    // Acquire the mutex
+    iMutex.Wait();
+    
+    // Invocate extension funtion using original allocator
+    TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
+    
+    // Release the mutex
+    iMutex.Signal();
+    
+    // Return information of the extension function success
+    return ext;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::LogProcessInformation()
+// Retrieve and log the process initial information
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::LogProcessInformation( const TFileName aFileName,
+    TUint32 aLogOption, TUint32 aIsDebug )
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation()" );
+    
+    // Create local variable and retrieve the process information
+    TProcessIdentityParamsBuf params;
+    params().iProcessId = iProcessId;
+    params().iThreadId = RThread().Id().operator TUint();
+    TInt error = iAnalyzeTool.GetProcessInfo( params );
+    
+    LOGSTR2( "ATMH GetProcessInfo %i error", error );
+    
+    if ( KErrNone == error )
+        {
+        LOGSTR2( "ATMH Process %i", iProcessId );
+
+        // Store stack start address
+        LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+        LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
+
+        // Append thread to array of the users of this allocator
+        error = iThreadArray.Append(
+        TThreadStack( RThread().Id(), params().iStackAddress + params().iStackSize) );
+
+        __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+        // Log process information
+        if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+            {
+            if ( iLogOption == EATLogToTraceFast )
+                {
+                // Using fast logging mode.
+                LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogProcessStarted() #1" );
+                ATFastLogProcessStarted( params().iProcessName, iProcessId, aIsDebug );                
+                }
+            else
+                {
+                // Using storage server.
+                LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #1" );
+                error = iStorageServer.LogProcessStarted(
+                        aFileName,
+                        params().iProcessName,
+                        iProcessId, 
+                        aLogOption, 
+                        aIsDebug );
+                }
+            }
+
+        LOGSTR2( "ATMH LogProcessStarted error %i", error );
+
+        // Iterate through process codesegments
+        for( TInt i = 0; i < params().iCodesegCount; i++ )
+            {
+            // Create local variable and retrieve codesegment info
+            TCodesegInfoBuf codeinfo;
+            codeinfo().iProcessId = iProcessId;
+            codeinfo().iIndex = i;
+            error = iAnalyzeTool.GetCodesegInfo( codeinfo );
+
+            LOGSTR2( "ATMH GetCodesegInfo error %i", error );
+            if ( KErrNone == error )
+                {
+                // Don't log AnalyzeTool libraries
+                if ( 0 != codeinfo().iFullName.CompareC( KMemoryHook ) &&
+                     0 != codeinfo().iFullName.CompareC( KStorageServer ) )
+                    {
+                    // Log the loaded codesegment(s)
+                    if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+                        {
+                        if ( iLogOption == EATLogToTraceFast )
+                            {
+                            // Using fast logging mode.
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogDllLoaded() #2" );
+                            ATFastLogDllLoaded( iProcessId,
+                                    codeinfo().iFullName,
+                                    codeinfo().iRunAddress,
+                                    codeinfo().iRunAddress + codeinfo().iSize );
+                            }
+                        else
+                            {
+                            // Using storage server.
+                            LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #2" );
+                            error = iStorageServer.LogDllLoaded(
+                                    codeinfo().iFullName,
+                                    codeinfo().iRunAddress,
+                                    codeinfo().iRunAddress + codeinfo().iSize );
+                            }
+                        }
+
+                    LOGSTR2( "ATMH LogDllLoaded error %i", error );
+
+                    // Check that everything is OK
+                    if ( KErrNone == error )
+                        {
+                        // Append the codesegment to the array
+                        error = iCodeblocks.Append(
+                                        TCodeblock( codeinfo().iRunAddress,
+                                        codeinfo().iSize,
+                                        codeinfo().iFullName ) );
+                        LOGSTR2( "ATMH Append error %i", error );
+                        }
+                    }
+                }
+            }
+
+        // Iterate through process dynamic codesegments
+        for ( TInt i = 0; i < params().iDynamicCount; i++ )
+            {
+            // Create local variable and retrieve codesegment info
+            TLibraryInfoBuf info;
+            info().iProcessId = iProcessId;
+            info().iIndex = i;
+            error = iAnalyzeTool.GetLibraryInfo( info );
+            LOGSTR2( "ATMH GetLibraryInfo error %i", error );
+            if ( KErrNone == error )
+                {
+                // Log the loaded dynamic codesegment(s)
+                if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+                    {
+                    if ( iLogOption == EATLogToTraceFast )
+                        {
+                        // Using fast logging mode.
+                        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - - ATFastLogDllLoaded()#3" );
+                        ATFastLogDllLoaded( iProcessId,
+                                info().iLibraryName,
+                                info().iRunAddress,
+                                info().iRunAddress + info().iSize );
+                        }
+                    else
+                        {
+                        // Using storage server.
+                        LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #3" );
+                        error = iStorageServer.LogDllLoaded(
+                                info().iLibraryName,
+                                info().iRunAddress,
+                                info().iRunAddress + info().iSize );
+                        }
+                    }
+
+
+                LOGSTR2( "ATMH LogDllLoaded error %i", error );
+
+                if ( KErrNone == error )
+                    {
+                    // Append the codesegment to the array
+                    error = iCodeblocks.Append(
+                            TCodeblock( info().iRunAddress, 
+                                        info().iSize, info().iLibraryName ) );
+                    LOGSTR2( "ATMH Append error %i", error );
+                    }
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::FindCurrentThreadStack()
+// Find the current thread which is using the heap
+// -----------------------------------------------------------------------------
+//
+TBool RAnalyzeToolMainAllocator::FindCurrentThreadStack( TUint32& aStackStart )
+    {
+    LOGSTR2( "ATMH RAnalyzeToolMainAllocator::FindCurrentThreadStack(), count( %i )",
+            iThreadArray.Count() );
+    
+    // Flag for indicating that right thread has been found
+    TBool found( EFalse );
+    // If threre is only one thread it must be the right thread
+    if ( iThreadArray.Count() == KThreadCount )
+        {
+        if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+            {
+            // This MUST BE the right thread
+            //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+            }
+        else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+            {
+            found = ETrue;
+            }
+        }
+    else
+        {
+        // Iterate through array to find right thread
+        TInt count = iThreadArray.Count();
+
+        for ( TInt i = 0; i < count; i++ )
+            {
+            // Check if this is the right thread
+            if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
+                {
+                // Right thread found. Mark the flag
+                found = ETrue;
+                break;
+                }
+            }
+        // If right thread was not found the panic must be raised
+        if ( !found )
+            {
+            //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+            }
+        }
+    return found;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::InstallEventHandler()
+// Installs the eventhandler, if possible
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::InstallEventHandler()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMainAllocator::InstallEventHandler()" );
+    
+    // Active eventhalder is not active, trying to start it
+    if ( NULL != CActiveScheduler::Current() )
+        {
+        iEventHandler->Start();
+        }
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolmemoryallocator.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator( TBool aNotFirst ) :
+    RAllocator(),
+    iNotFirst( aNotFirst )/*,
+    iStorageServerOpen( EFalse )*/
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator()" );
+    
+    // Acquire the original allocator
+    iAllocator = &User::Allocator(); 
+    
+    // Set memory model zero
+    iMemoryModel = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()" );
+    
+    // Call switching orinigal allocator back.
+    // Just in case, if uninstall was not called.
+    SwitchOriginalAllocator();
+    }
+    
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()
+// Switches original allocator in use if not already.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()
+    {
+    LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()" );
+    
+    if ( iAllocator != &User::Allocator() )
+        {
+        User::SwitchAllocator( iAllocator );
+        }
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/codeblock.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class TCodeblock.
+*
+*/
+
+
+#include "codeblock.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TCodeblock::TCodeblock
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TCodeblock::TCodeblock( TLinAddr aRunAddress, 
+                        TUint32 aSize, 
+                        TBuf8<KMaxLibraryName>& aName ) :
+                        iStartAddress( aRunAddress ),
+                        iEndAddress( aRunAddress + aSize )
+    {
+    LOGSTR3( "ATMH TCodeblock::TCodeblock() %x - %x", iStartAddress, iEndAddress );
+    iName.Copy( aName );
+    }
+
+// -----------------------------------------------------------------------------
+// TCodeblock::CheckAddress
+// Checks if the given address is in this memory block area
+// -----------------------------------------------------------------------------
+//
+TBool TCodeblock::CheckAddress( TUint32 aAddress )
+    {
+    if ( iStartAddress <= aAddress && aAddress <= iEndAddress )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// TCodeblock::Match
+// Matches if the given parameters represents this memory block 
+// -----------------------------------------------------------------------------
+//
+TBool TCodeblock::Match( TBuf8<KMaxLibraryName>& aName )
+    {
+    LOGSTR1( "ATMH TCodeblock::Match()" );
+    return ( 0 == iName.CompareF( aName ) ) ? ETrue : EFalse;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/customuser.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,518 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CustomUser.
+*
+*/
+
+#include <f32file.h>
+#include <utf.h>
+#include "customuser.h"
+#include "analyzetoolmainallocator.h"
+#include "analyzetoolallocator.h"
+#include "atlog.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "atstorageservercommon.h"
+#include "atdriveinfo.h"
+#include <analyzetool/analyzetooltraceconstants.h>
+
+#ifdef USE_CLEANER_DLL
+// Global variable to detect dll attach & detach in process.
+// Note! This is initialized after SetupThreadHeap so its not usable there.
+// This is used to store the main thread id and track when the process ends
+// to load the cleaner dll with call back feature to cleanup allocator at the
+// last possible phase.
+#include <analyzetool/analyzetoolcleaner.h>
+
+// CONSTANTS
+const TInt KAToolCleanerOrdinal = 1;
+
+class TAnalyzeToolGlobalTracker : public TAnalyzeToolCleanerBase
+    {
+public:
+    /* Main thread id */
+    TThreadId iMainId;
+    
+    /* Inform if panic occured */
+    TBool iPanic;
+    
+    // -----------------------------------------------------------------------------
+    // TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker()
+    // C++ default constructor 
+    // -----------------------------------------------------------------------------
+    //
+    TAnalyzeToolGlobalTracker()
+        {
+        LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker()" );
+        
+        iPanic = EFalse; // no panic occured
+        iMainId = RThread().Id(); // set main thread id
+        LOGSTR2( "ATMH TAnalyzeToolGlobalTracker() > Main id set: %d", 
+                iMainId.operator TUint() );
+        }
+    
+    // -----------------------------------------------------------------------------
+    // TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker()
+    // Destructor.
+    // -----------------------------------------------------------------------------
+    //
+    ~TAnalyzeToolGlobalTracker()
+        {
+        LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker()" );
+        
+        // We dont load dll if panic has happened (uninstallation has been done).
+        if ( iPanic )
+            {
+            LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > Panic set not loading cleaner dll." );
+            return;
+            }
+        
+        LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > about to load cleaner dll" );
+        // Load cleaner library and set a call back to our cleanup
+        RLibrary lib;
+        TInt error( lib.Load( KATCleanerDllName ) );
+        if ( error == KErrNone )
+            {
+            // Set address to point to ourself
+            TLibraryFunction func = lib.Lookup( KAToolCleanerOrdinal ); // Ordinal 1 of the dll
+            ATCLEANERTABLE* cleaner = (ATCLEANERTABLE*) func(); // Use function to get address
+            cleaner->At( 0 ) = (TUint32) this; // Set address
+            LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll loaded and call back set" );
+            }
+        else
+            {
+            // Error loading cleanup dll
+            LOGSTR2( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll load error(%i) uninstalling allocator now!", 
+                    error );
+            Cleanup();
+            }
+        }
+    
+    // -----------------------------------------------------------------------------
+    // TAnalyzeToolGlobalTracker::Cleanup()
+    // 
+    // -----------------------------------------------------------------------------
+    //
+    void Cleanup()
+        {
+        LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::Cleanup() - allocator uninstall" );
+        
+        // Uninstall allocator
+        ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+        }
+    
+    };
+
+// Global variable definition.
+TAnalyzeToolGlobalTracker gGlobalTracker;
+#endif
+
+// CONSTANTS
+// When needed, update the version number directly inside _LIT macro.
+// Constant for the atool API(staticlib) version.
+_LIT( KAtoolApiVersion, "1.7.5" );
+
+// Version number buffer length
+const TInt KAtoolVersionNumberLength = 10;
+
+// Wrong version error code
+const TInt KAtoolVersionError = -1999;
+
+// Version number separator
+_LIT( KVersionSeparator, ";" );
+
+// Incorrect version error strings 
+_LIT( KIncorrectText, "ERROR_OCCURED INCORRECT_ATOOL_VERSION [API v.%S][ATOOL v.%S]" );
+_LIT( KIncorrectTextTrace, "PCSS " );
+
+// -----------------------------------------------------------------------------
+// CustomUser::Panic()
+// Overloaded User::Panic() function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CustomUser::Panic( const TDesC& aCategory, TInt aReason )
+    {
+    LOGSTR3( "ATMH CustomUser::Panic() %S %i", &aCategory, aReason );
+    
+#ifdef USE_CLEANER_DLL
+    // Set global tracker that panic has happened.
+    gGlobalTracker.iPanic = ETrue;
+#endif
+    
+    // Uninstall thread's RAllocator
+    ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+       
+    // Call the "real" User::Panic()
+    User::Panic( aCategory, aReason );
+    }
+
+// -----------------------------------------------------------------------------
+// CustomUser::Exit()
+// Overloaded User::Exit() function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CustomUser::Exit( TInt aReason )
+    {
+    LOGSTR3( "ATMH CustomUser::Exit() %i %i", aReason, RThread().Id().Id() );
+    
+    if ( aReason != KAtoolVersionError )
+    	{
+#ifdef USE_CLEANER_DLL
+        // Only uninstall allocator if its not the process main/first thread.
+        LOGSTR3( "ATMH CustomUser::Exit() - Thread id: %d - Main Id: %d",
+                RThread().Id().operator TUint(), gGlobalTracker.iMainId.operator TUint() );
+        
+        if ( RThread().Id() != gGlobalTracker.iMainId )
+            {
+            LOGSTR2("ATMH CustomUser::Exit() - Calling allocator uninstall in thread: %d" , RThread().Id().operator TUint() );
+            ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+            }
+#else
+    	// Uninstall thread's RAllocator
+    	( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+    	LOGSTR1( "ATMH CustomUser::Exit() - about to User::Exit" );
+#endif
+    	}
+    
+    // Call the "real" User::Exit()
+    User::Exit( aReason );
+    }
+
+// -----------------------------------------------------------------------------
+// CustomUser::SetCritical()
+// Overloaded User::SetCritical() function which returns
+// KErrNone, if successful; KErrArgument, if EAllThreadsCritical is 
+// passed - this is a state associated with a process, and you use 
+// User::SetProcessCritical() to set it.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetCritical( User::TCritical aCritical )
+    {
+    LOGSTR1( "ATMH CustomUser::SetCritical()" );
+    // Check the given User::TCritical type
+    if ( aCritical == User::EAllThreadsCritical )
+        {
+        return KErrArgument;
+        }
+    else
+        {
+        return KErrNone;
+        }
+    }
+  
+// -----------------------------------------------------------------------------
+// CustomUser::SetProcessCritical()
+// Overloaded User::SetProcessCritical() function
+// KErrNone, if successful; KErrArgument, if either EProcessCritical or 
+// EProcessPermanent is passed - these are states associated with a 
+// thread, and you use User::SetCritical() to set them.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetProcessCritical( User::TCritical aCritical )
+    {
+    LOGSTR1( "ATMH CustomUser::SetProcessCritical()" );
+     // Check the given User::TCritical type 
+    if ( aCritical == User::EProcessCritical || 
+         User::EProcessPermanent == aCritical )
+        {
+        return KErrArgument;
+        }
+    else
+        {
+        return KErrNone;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CustomUser::SetupThreadHeap()
+// Overloaded UserHeap::SetupThreadHeap function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetupThreadHeap( TBool aNotFirst, 
+    SStdEpocThreadCreateInfo& aInfo, const TFileName& aFileName,
+    TUint32 aLogOption, TUint32 aIsDebug, const TATVersion& aVersion,
+    TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize,
+    TRefByValue<const TDesC> aFmt, ... )
+    {
+    LOGSTR1( "ATMH CustomUser::SetupThreadHeap()" );
+    LOGSTR2( "ATMH > Thread id(%d)", RThread().Id().operator TUint() );
+    
+    // Add handling of the argument list here.
+        
+    TInt ret( KErrNone );    
+    // Check version number
+    TBuf<KAtoolVersionNumberLength> atoolVer;
+    if ( CheckVersion( aVersion, atoolVer ) != KErrNone )
+    	{
+    	LOGSTR1( "ATMH > Wrong API version > Inform user and Exit." );
+    	ReportIncorrectVersion( aLogOption, aFileName, atoolVer );
+    	return KAtoolVersionError;
+    	}
+    
+    // Check is this shared heap
+    if ( aInfo.iAllocator == NULL )
+        {
+        LOGSTR1( "ATMH creating a new heap" );
+        // RAllocator is NULL so heap is not shared, creating a new heap
+        ret = UserHeap::SetupThreadHeap( aNotFirst, aInfo );
+        __ASSERT_ALWAYS( KErrNone == ret, AssertPanic( EFailedToCreateHeap ) );
+        
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+    #ifndef __WINS__
+        // Set dummy Tls value
+        TAny* dummyPtr( NULL );
+        TInt setErr( UserSvr::DllSetTls( KDummyHandle, dummyPtr ) );
+        LOGSTR2( "ATMH > Set Tls err(%i)", setErr );
+    #endif
+#endif
+        // Install the RAllocator
+        aInfo.iAllocator = &InstallAllocator( aNotFirst, aFileName, aLogOption, aIsDebug,
+                aAllocCallStackSize, aFreeCallStackSize );
+        }
+    else
+        {
+        LOGSTR1( "ATMH sharing the heap" );
+        // The heap is shared. Acquire pointer to the original heap
+        RAnalyzeToolMemoryAllocator* allocator = 
+			(RAnalyzeToolMemoryAllocator*) aInfo.iAllocator;
+        // Share the heap
+        allocator->ShareHeap();
+        // Switch thread heap 
+        User::SwitchAllocator( allocator );
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CustomUser::InstallAllocator
+// Installs the RAllocator
+// -----------------------------------------------------------------------------
+//
+//lint -e{429} suppress "Custodial pointer 'allocator' has not been freed or returned"
+EXPORT_C RAllocator& CustomUser::InstallAllocator( TBool aNotFirst, 
+	const TFileName& aFileName, TUint32 aLogOption, TUint32 aIsDebug,
+	TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize )
+    {
+    LOGSTR1( "ATMH CustomUser::InstallAllocator()" );
+    
+    // Open handle to the device driver
+    RAnalyzeTool analyzetool;
+    TInt error = analyzetool.Open();
+    
+    // Check if the device driver has already loaded
+    if ( KErrNone == error )
+        {
+        LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned KErrNone" );
+        // The device driver has already loaded
+        // Get pointer to the main thread allocator
+        TMainThreadParamsBuf params;
+        params().iProcessId = RProcess().Id().operator TUint();
+        error = analyzetool.MainThreadAlloctor( params );
+
+        __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantOpenHandle ) );
+        
+        // Close handle to the device driver
+        analyzetool.Close();
+        
+        // Is this the first thread of the program
+        if ( params().iAlone )
+            {
+            LOGSTR1( "ATMH CustomUser::InstallAllocator() - first thread of the program" );
+            // Only one thread in the program. Must be main thread
+            RAnalyzeToolMainAllocator* allocator = 
+				new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption,
+				                               aIsDebug, aAllocCallStackSize, aFreeCallStackSize );
+            
+            __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+            
+            // Change threads allocator
+            User::SwitchAllocator( allocator );
+            
+            // Return reference to the RAllocator
+            return *allocator;
+            }
+        // This is not the first thread. A new thread with a new heap created
+        else
+            {
+            LOGSTR1( "ATMH CustomUser::InstallAllocator() - create a new allocator for the new thread" );
+            // Create new RAllocator with handles from the main thread
+            RAnalyzeToolAllocator* allocator = new RAnalyzeToolAllocator( 
+                    aNotFirst,
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServer(), 
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->Codeblocks(), 
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->Mutex(), 
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->ProcessId(), 
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->AnalyzeTool(),
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServerOpen(),
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->LogOption(),
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->AllocMaxCallStack(),
+                    ((RAnalyzeToolMainAllocator*)params().iAllocator)->FreeMaxCallStack() );
+
+            __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+            
+            // Change threads allocator
+            User::SwitchAllocator( allocator );
+            
+            // Return reference to the RAllocator
+            return *allocator;
+            }
+        }
+    // The device driver does not exists so this must be the first thread
+    else
+        {
+        LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned error, creating DD" );
+        RAnalyzeToolMainAllocator* allocator = 
+			new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption, aIsDebug,
+			        aAllocCallStackSize, aFreeCallStackSize );
+        
+        __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+        
+        // Change threads allocator
+        User::SwitchAllocator( allocator );
+
+        // Return reference to the RAllocator
+        return *allocator;
+        }
+    } 
+    
+// -----------------------------------------------------------------------------
+// CustomUser::CheckVersion
+// Check atool version
+// -----------------------------------------------------------------------------
+//
+TInt CustomUser::CheckVersion( const TATVersion& aVersion, TDes& aToolVersion )
+    { 
+    LOGSTR2( "ATMH CustomUser::CheckVersion(), aVersion( %S )", &aVersion );
+    
+    TFileName version;
+    version.Copy( aVersion );
+    TBuf<KAtoolVersionNumberLength> apiVer;
+    	
+    // Find separator place
+    TInt findplace( version.Find( KVersionSeparator() ) );
+    // Parse API version first [x.x.x;x.x.x]
+    if ( findplace >= 0 && findplace <= apiVer.MaxLength() )
+		{
+		apiVer.Copy( version.Mid( 0, findplace ) ); 
+		version.Delete( 0, findplace + KVersionSeparator().Length() );
+		}
+ 
+    if ( version.Length() <= aToolVersion.MaxLength() )
+    	{
+    	aToolVersion.Copy( version );
+    	if ( aToolVersion.Compare( KAtoolApiVersion ) == KErrNone &&
+    		 apiVer.Length() == 0 )
+    		{
+    		// Support 1.5.0 version (Version info: [1.5.0])
+    		apiVer.Copy( version );
+    		}
+    	}
+    
+    LOGSTR3( "ATMH > API version( %S ), ATOOL version( %S )", 
+    		&apiVer, &aToolVersion );
+        
+    // Check version numbers 
+    if ( apiVer.Compare( KAtoolApiVersion ) == KErrNone )
+    	{
+    	return KErrNone;
+    	}
+    return KErrCancel;    
+    }
+
+// -----------------------------------------------------------------------------
+// CustomUser::ReportIncorrectVersion
+// Function for showing incorrect version information
+// -----------------------------------------------------------------------------
+//
+void CustomUser::ReportIncorrectVersion( const TUint32 aLogOption,
+	const TFileName& aFileName, const TDes& aToolVersion )
+	{
+	LOGSTR2( "ATMH CustomUser::ReportIncorrectVersion(), aFileName( %S )", 
+			&aFileName );
+	
+	switch ( aLogOption )
+		{
+		case EATLogToFile:
+			{
+			LOGSTR1( "ATMH ReportIncorrectVersion > EATLogToFile" );			
+			
+			// A handle to a file server session.
+			RFs fs;
+			// Creates and opens a file, 
+			// and performs all operations on a single open file.
+			RFile file;	
+			// Create full path buffer
+			TBuf<KMaxFileName> logFileBuf;
+			// Connects a client to the file server.
+			TInt err( fs.Connect() );
+			
+			if ( !err )
+				{				
+                err = TATDriveInfo::CreatePath( logFileBuf, aFileName, fs );
+			    
+				// Replace file if exists
+				if ( err && err != KErrAlreadyExists )
+					{
+					LOGSTR2( "ATMH > TATDriveInfo::CreatePath() err( %i )", err );
+					return;
+					}
+				
+				// Replace file if exists (drive C)
+				err = file.Replace( fs, logFileBuf, EFileWrite );
+										
+				// Write to file
+				if ( !err )
+					{
+					err = file.Write( KDataFileVersion );
+					// Error msg buffer
+					TBuf8<KMaxFileName> msg;				     
+					// Write the error code to the buffer  
+					logFileBuf.Format( KIncorrectText, &KAtoolApiVersion, &aToolVersion );	
+					CnvUtfConverter::ConvertFromUnicodeToUtf8( msg, logFileBuf );
+					err = file.Write( msg );
+					}
+				// Closes the file.
+				file.Close();
+				}
+			
+			LOGSTR2( "ATMH > File err( %i )", err );			
+			// Closes the handle.
+			fs.Close();
+			}
+			break;
+			
+		case EATUseDefault:
+		case EATLogToTrace:
+			{
+			LOGSTR1( "ATMH > ReportIncorrectVersion > EATLogToTrace" );
+			// Error msg buffer
+			TBuf<KMaxFileName> msg;	
+			msg.Copy( KIncorrectTextTrace );
+			msg.Append( KIncorrectText );
+			TBuf<KMaxFileName> traceMsg;	
+			// Write the error code to the buffer  
+			traceMsg.Format( msg, &KAtoolApiVersion, &aToolVersion );
+			RDebug::Print( traceMsg );
+			}
+			break;
+		
+		default:
+			{
+			LOGSTR1( "ATMH > ReportIncorrectVersion > default" );
+			}
+			break;
+		}	
+	}
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/threadstack.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class TThreadStack.
+*
+*/
+
+
+#include "threadstack.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TThreadStack::TThreadStack()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TThreadStack::TThreadStack( TThreadId aId, TUint32 aStackStart ) :
+    iId( aId ),
+    iStackStart( aStackStart )
+    {
+    LOGSTR2( "ATMH TThreadStack::TThreadStack() aStackStart: %i", aStackStart );
+    }
+
+// -----------------------------------------------------------------------------
+// TThreadStack::ThreadStackStart()
+// Checks if this is the current thread and if this is the current
+// thread assings value to the given parameter
+// -----------------------------------------------------------------------------
+//
+TBool TThreadStack::ThreadStackStart( TUint32& aStackStart )
+    {
+    LOGSTR1( "ATMH TThreadStack::ThreadStackStart");
+    
+    if ( RThread().Id() == iId )
+        {
+        aStackStart = iStackStart;
+        return ETrue;
+        }
+    else
+        {
+        aStackStart = 0;
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TThreadStack::Match()
+// Checks if this is the the current thread.
+// -----------------------------------------------------------------------------
+//
+TBool TThreadStack::Match( const TUint aThreadId )
+    {
+    LOGSTR2( "ATMH TThreadStack::Match( %d )", aThreadId );
+    
+    if ( aThreadId != 0 )
+    	{
+    	LOGSTR2( "ATMH > iId.operator TUint() = %d", iId.operator TUint() );
+    	return ( aThreadId == iId.operator TUint() ) ? ETrue : EFalse;
+    	}
+    else
+    	{
+    	return ( RThread().Id() == iId ) ? ETrue : EFalse;
+    	}
+    }
+    
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/envpatcher/EnvPatcher.pl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,544 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+# 
+# Description:
+# Environment Patcher - Patches older S60 SDKs for supporting
+# tricks in newer platforms
+#
+
+
+require v5.6.1;	
+
+use File::Copy;
+use strict;
+
+# check amount of commandline options is valid
+if (@ARGV != 1)
+{
+    print "Usage: EnvPatcher <EPOCROOT>\n";
+    exit 1;
+}
+
+
+# get epocroot and convert, convert \ -> /
+(my $epocroot = $ARGV[0]) =~ s{\\}{/}g;
+
+# remove any trailing forward slashes
+$epocroot =~ s/\/$//;
+
+
+# create variables for paths
+my $e32toolsdir = $epocroot."/epoc32/tools";
+my $e32includedir = $epocroot."/epoc32/include";
+my $e32includeoemdir = $e32includedir."/oem";
+my $platformpathspath = $e32includedir."/platform_paths.hrh";
+my $domainplatformpathspath = $e32includedir."/domain/osextensions/platform_paths.hrh";
+my $mmppmpath = $e32toolsdir."/mmp.pm";
+my $pathutlpmpath = $e32toolsdir."/pathutl.pm";
+my $prepfilepmpath = $e32toolsdir."/prepfile.pm";
+
+# variables for hacked content
+my $dependshack = "\t\t\tif (/^DEPENDS\$/o) {\r\n\t\t\t\tnext LINE;  # Ignore DEPENDS keyword, not needed by ABLD\r\n\t\t\t}\r\n";
+my $smpsafehack = "\t\tif (/^SMPSAFE\$/o) {\r\n\t\t\tnext LINE;  # Ignore SMPSAFE keyword, not needed by older environments\r\n\t\t}\r\n";
+my $forwardslashhack = "\t\t# EnvPatcher forwardslash hack begins\r\n\t\t\$_=~s{/}{\\\\}g;   # convert all forward slashes to backslashes\r\n\t\t# EnvPatcher forwardslash hack ends\r\n\r\n";
+my $coreibyexportsupport = "\r\n// Following definition is used for exporting tools and stubs IBY files to\r\n// Core image.\r\n#define CORE_IBY_EXPORT_PATH(path,exported)  /epoc32/rom/include/##exported\r\n";
+
+
+# check epoc32\tools exists
+unless (-d $e32toolsdir)
+{
+    print "$e32toolsdir not found, please check valid epocroot has been given!\n";
+    exit 1;
+}
+
+# check epoc32\include exists
+unless (-d $e32includedir)
+{
+    print "$e32includedir not found, please check valid epocroot has been given!\n";
+    exit 1;
+}
+
+
+# create epoc32\include\oem if it does not exist
+unless (-d $e32includeoemdir)
+{
+    mkdir $e32includeoemdir or die;
+    print "Missing directory $e32includeoemdir created succesfully.\n";
+}
+
+
+# check if epoc32\include\domain\osextensions\platform_paths.hrh exists
+if (-e $domainplatformpathspath)
+{
+    # show an error if the file does not have any platform macros
+    unless (string_exists_in_file($domainplatformpathspath, "OS_LAYER_SYSTEMINCLUDE"))
+    {
+        print "ERROR: $domainplatformpathspath does not have SF macros.\n";
+        print "Please check your environment, if you have S60 3.2 OEM or newer, please get the latest version!\n";
+        exit 2;
+    }
+}
+
+
+# check if epoc32\include\platform_paths.hrh exists
+if (-e $platformpathspath)
+{
+    print "$platformpathspath already exists, not checking it.\n";    
+}
+else
+{
+    # create the file missing file
+    create_default_platform_paths_hrh();
+    print "Missing file $platformpathspath created succesfully.\n";    
+}
+
+
+# check if CORE_IBY_EXPORT_PATH macro exist in the platform_paths.hrh
+unless (string_exists_in_file($platformpathspath, "CORE_IBY_EXPORT_PATH"))
+{
+    # read content of the platform_paths.hrh
+    my @filecontent = read_file_to_array($platformpathspath);  
+
+    my $match_found = 0;
+    my $i = 0;
+    my $match_found_pos = 0;
+    
+    # find the position where the include guards start (this should be a safe position)
+    foreach (@filecontent)
+    {
+        if ($_ =~ /#define PLATFORM_PATHS_HRH/)
+        {
+            $match_found = 1;
+            $match_found_pos = $i;
+            last;
+        } 
+
+        $i++;
+    }
+    
+    if ($match_found)
+    {
+        # insert the patched content to the file
+        splice(@filecontent, $match_found_pos+1, 0, $coreibyexportsupport);
+        
+        # write the modified array to the file
+        write_file_from_array($platformpathspath, @filecontent);
+    
+        print "Platform_paths.hrh updated to support CORE_IBY_EXPORT_PATH macro.\n";
+    }
+    else
+    {
+        print "WARNING: $platformpathspath is corrupted or not supported!\n";    
+    }
+}
+ 
+    
+# check if epoc32\tools\mmp.pm exists
+if (-e $mmppmpath)
+{
+    # check if DEPENDS keyword already exists in the file
+    if (string_exists_in_file($mmppmpath, "DEPENDS"))
+    {
+        print "The SDK can already handle DEPENDS keyword in a MMP file.\n";        
+    }
+    else
+    {
+        # read content of the mmp.pm file
+        my @filecontent = read_file_to_array($mmppmpath);
+        
+        my $match_found = 0;
+        my $i = 0;
+        my $match_found_pos = 0;
+        
+        # loop through the array to find the correct place
+        foreach (@filecontent)
+        {
+            if ($_ =~ /Unrecognised Resource Keyword/)
+            {
+                $match_found = 1;
+                $match_found_pos = $i;
+                last;
+            } 
+
+            $i++;
+        }
+        
+        if ($match_found)
+        {
+            # insert the patched content to the file
+            splice(@filecontent, $match_found_pos-1, 0, $dependshack);
+            
+            # write the modified array to the file
+            write_file_from_array($mmppmpath, @filecontent);
+        
+            print "Mmp.pm patched with DEPENDS keyword hack.\n";
+        }
+        else
+        {
+            print "ERROR: Unable to find correct place from $mmppmpath for patching!\n";
+            print "Your SDK environment probably is not supported by this script!\n";
+            exit(2);    
+        }
+    }
+
+    # check if SMPSAFE keyword already exists in the file
+    if (string_exists_in_file($mmppmpath, "SMPSAFE"))
+    {
+        print "The SDK can already handle SMPSAFE keyword in a MMP file.\n";        
+    }
+    else
+    {
+        # read content of the mmp.pm file
+        my @filecontent = read_file_to_array($mmppmpath);
+        
+        my $match_found = 0;
+        my $i = 0;
+        my $match_found_pos = 0;
+        
+        # loop through the array to find the correct place
+        foreach (@filecontent)
+        {
+            if ($_ =~ /Unrecognised Keyword/)
+            {
+                $match_found = 1;
+                $match_found_pos = $i;
+                last;
+            } 
+
+            $i++;
+        }
+        
+        if ($match_found)
+        {
+            # insert the patched content to the file
+            splice(@filecontent, $match_found_pos, 0, $smpsafehack);
+            
+            # write the modified array to the file
+            write_file_from_array($mmppmpath, @filecontent);
+        
+            print "Mmp.pm patched with SMPSAFE keyword hack.\n";
+        }
+        else
+        {
+            print "ERROR: Unable to find correct place from $mmppmpath for patching!\n";
+            print "Your SDK environment probably is not supported by this script!\n";
+            exit(2);    
+        }
+    }
+}
+else
+{
+    print "WARNING: $mmppmpath not found, this environment is not supported!\n";
+}
+
+
+# check if epoc32\tools\pathutl.pm exists
+if (-e $pathutlpmpath)
+{
+    # check if "sub Path_Norm" already exists in the pathutil.pm file
+    # if it does not exists, then we need to patch prepfile.pm
+    if (string_exists_in_file($pathutlpmpath, "sub Path_Norm"))
+    {
+        print "The SDK is non Symbian OS 9.1, no need to add forward slash hack.\n";        
+    }
+    else
+    {
+        # check if prepfile.pm has already been patched
+        if (string_exists_in_file($prepfilepmpath, "EnvPatcher forwardslash hack"))
+        {        
+            print "The SDK has already been patched with forwardslash hack.\n";         
+        }
+        else
+        {    
+            # read content of the prepfile.pm file
+            my @filecontent = read_file_to_array($prepfilepmpath);  
+    
+            my $match_found = 0;
+            my $i = 0;
+            my $match_found_pos = 0;
+            
+            # loop through the array to find the correct place
+            foreach (@filecontent)
+            {
+                if ($_ =~ /# skip blank lines/)
+                {
+                    $match_found = 1;
+                    $match_found_pos = $i;
+                    last;
+                } 
+    
+                $i++;
+            }
+            
+            if ($match_found)
+            {
+                # insert the patched content to the file
+                splice(@filecontent, $match_found_pos+6, 0, $forwardslashhack);
+                
+                # write the modified array to the file
+                write_file_from_array($prepfilepmpath, @filecontent);
+            
+                print "Prepfile.pm patched with forward slash hack.\n";
+            }
+            else
+            {
+                print "ERROR: Unable to find correct place from $prepfilepmpath for patching!\n";
+                print "Your SDK environment probably is not supported by this script!\n";
+                exit(2);    
+            }
+        }
+    }    
+}
+else
+{
+    print "WARNING: $pathutlpmpath not found, this environment is not supported!\n";
+}
+ 
+ 
+ 
+# checks if string exists in the file    
+sub string_exists_in_file
+{
+    my $filepath = $_[0];
+    my $findstring = $_[1];
+    my $match_found = 0;     
+
+    open(FILE, "<", $filepath) or die "Failed to open $filepath for reading!";
+
+    # loop through the file for occurances
+    while (<FILE>)
+    {
+        if ($_ =~ /$findstring/)
+        {
+            $match_found = 1;
+            last;
+        } 
+    }
+
+    close FILE;
+    
+    return $match_found;
+}
+
+
+# reads lines from a file to an array    
+sub read_file_to_array
+{
+    my $filepath = $_[0];
+
+    open(FILE, "<", $filepath) or die "Failed to open $filepath for reading!";
+    my @data = <FILE>;
+    close FILE;
+    
+    return(@data);
+}
+
+
+# writes lines from an array to a file
+sub write_file_from_array
+{
+    my ($filepath, @data) = @_;
+    
+    # take a backup of the file
+    copy ($filepath, $filepath."EnvPatcher") or die "Cannot take backup of $filepath to $filepath.EnvPatcher";
+        
+    open(FILE, ">", $filepath) or die "Failed to open $filepath for writing!";
+
+    # write the array to file
+    foreach my $line (@data)
+    {
+        print FILE "$line";
+    }
+
+    close FILE;
+}
+
+sub create_default_platform_paths_hrh
+{
+    # the file does not exist, so create the missing file
+    open(FILE, ">", $platformpathspath) or die "Failed to open $platformpathspath for writing!\n";
+    
+    print FILE <<ENDOFTHEFILE;
+#ifndef PLATFORM_PATHS_HRH
+#define PLATFORM_PATHS_HRH
+
+/**
+* ---------------------------------------
+* Location, where the applications layer specific public headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define APP_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define APP_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the applications layer specific platform headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define APP_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define APP_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the middleware layer specific public headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define MW_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define MW_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the middleware layer specific platform headers should be exported
+* ---------------------------------------
+*/
+#define MW_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define MW_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the os layer specific public headers should be exported
+* ---------------------------------------
+*/
+#define  OSEXT_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define  OS_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the os specific platform headers should be exported
+* ---------------------------------------
+*/
+#define OSEXT_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define OS_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the  cenrep excel sheets should be exported
+* Deprecated: should no longer be used. Kept for compability.
+* ---------------------------------------
+*/
+#define CENREP_XLS_EXPORT_PATH(exported) /epoc32/tools/cenrep/data/src/##exported
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be 
+* used in the mmp-files that are part of the applications-layer. It includes all 
+* the needed directories from the /epoc32/include, that are valid ones for the 
+* application-layer components. 
+*
+* Applications layer is the last one in the list, since most likely the most of 
+* the headers come from middleware or os-layer  => thus they are first.
+*/
+#define APP_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+ 
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the middleware-layer. It includes all 
+* the needed directories from the /epoc32/include, that are valid ones for the 
+* middleware-layer components. 
+*/
+#define MW_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the  osextensions-layer. It includes all
+* the needed directories from the /epoc32/include, that are valid ones for the
+* os-layer components. 
+*/
+#define OS_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+
+
+// Below statement is Deprecated and the OS_LAYER_SYSTEMINCLUDE-macro has to be
+// used.
+#define OSEXT_LAYER_SYSTEMINCLUDE OS_LAYER_SYSTEMINCLUDE
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the os-layer. This is intended 
+* to be only used by those components which need to use in their mmp-file either
+* kern_ext.mmh or nkern_ext.mmh. Reason is that those
+* 2 files already contain the /epoc32/include  as system include path.
+* 
+*/
+#define OS_LAYER_KERNEL_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include/oem
+
+
+// Below statement is Deprecated and the OS_LAYER_KERNEL_SYSTEMINCLUDE-macro 
+// has to be used.
+#define OSEXT_LAYER_KERNEL_SYSTEMINCLUDE OS_LAYER_KERNEL_SYSTEMINCLUDE
+
+/**
+****************************************************************************
+* Definitions that also define the paths to the layer specific source directories.
+****************************************************************************
+*/
+/**
+* The below 3 macros define the paths to the layer-specific source dirs.
+* See usage on top of this hrh-file, these are used the same way as 
+* for instance the OS_LAYER_DOMAIN_EXPORT_PATH
+* Deprecated: is not allowed to be using in Symbian Foundation
+*/
+#define APP_LAYER_SOURCE_PATH(rest)    /s60/app/##rest
+#define MW_LAYER_SOURCE_PATH(rest)     /s60/mw/##rest
+#define OSEXT_LAYER_SOURCE_PATH(rest)  /s60/osext/##rest
+
+/**
+****************************************************************************
+* Definitions to export IBY files to different folders where they will be taken 
+* to ROM image
+****************************************************************************
+*/
+// Following definition is used for exporting tools and stubs IBY files to 
+// Core image.
+#define CORE_IBY_EXPORT_PATH(path,exported)  /epoc32/rom/include/##exported
+
+/**
+* ---------------------------------------
+* Macros for Configuration tool migration. 
+* The below macros define the location under epoc32, where the confml 
+* (Configuration Markup Language) and crml (Central Repository Markup Language) 
+* files should be exported.
+* ---------------------------------------
+*/
+#define CONFML_EXPORT_PATH(file,category)           /epoc32/rom/config/confml_data/##category##/##file
+#define CRML_EXPORT_PATH(file,category)             /epoc32/rom/config/confml_data/##category##/##file
+#define GCFML_EXPORT_PATH(file,category)            /epoc32/rom/config/confml_data/##category##/##file
+#define CONFML_CONFIG_EXPORT_PATH(file,category)    /epoc32/rom/config/confml_data/##category##/config/##file
+
+#define APP_LAYER_CONFML(exported) 	                CONFML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_CRML(exported)                    CRML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_GCFML(exported)                   GCFML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_CONFML_CONFIG(exported)           CONFML_CONFIG_EXPORT_PATH(exported,s60)
+                                                    
+#define MW_LAYER_CONFML(exported)                   CONFML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_CRML(exported)                     CRML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_GCFML(exported)                    GCFML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_CONFML_CONFIG(exported)            CONFML_CONFIG_EXPORT_PATH(exported,s60)
+       
+// Deprecate: Use the OS_LAYER_* macros instead of OSEXT_LAYER_*                                             
+#define OSEXT_LAYER_CONFML(exported)                CONFML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_CRML(exported)                  CRML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_GCFML(exported)                 GCFML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_CONFML_CONFIG(exported)         CONFML_CONFIG_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CONFML(exported)                   CONFML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CRML(exported)                     CRML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_GCFML(exported)                    GCFML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CONFML_CONFIG(exported)            CONFML_CONFIG_EXPORT_PATH(exported,s60)
+
+#endif  // end of PLATFORM_PATHS_HRH
+
+ENDOFTHEFILE
+
+    close FILE;    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/envpatcher/ReadMe.txt	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,46 @@
+Environment Patcher v1.0.1
+==========================
+
+Updated: 12th November 2009
+
+
+Introduction:
+-------------
+This tool can be used to patch your S60 SDK environment so that the tricks and
+macros introduced in the latest SDKs can be used in a public SDK and older
+OEM releases.
+
+This tool can perform the following tasks:
+- Adds support for forward slashes in paths in bld.inf/.mmp files in S60 3.0 
+- Removes an unncessary warning about DEPENDS and SMPSAFE resource keywords in
+  an .mmp file
+- Creates a missing epoc32\include\platform_paths.hrh file for supporting
+  platform macros introduced since S60 3.2 OEM and Symbian Foundation releases
+- Modifies epoc32\include\platform_paths.hrh for missing macros   
+- Creates a missing epoc32\include\oem directory to suppress a possible warning
+
+
+Usage:
+------
+EnvPatcher.pl <EPOCROOT>
+
+Where EPOCROOT is the path to the root of the SDK, for example:
+  EnvPatcher.pl c:\Symbian\9.1\S60_3rd_MR
+  EnvPatcher.pl z:\
+
+
+Requirements:
+-------------
+- S60 SDK (public or OEM), version 3.0 or newer
+- Perl 5.6.1 or newer
+
+
+
+
+Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/ReleaseNotes_AnalyzeTool.txt	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,136 @@
+===============================================================================
+
+RELEASE NOTES - ANALYZETOOL v1.9.1
+RELEASED 29th April 2010
+
+SUPPORTS SYMBIAN^1+
+
+===============================================================================
+
+Product Description:
+====================
+AnalyzeTool is a dynamic test tool that is used for testing Symbian software
+for memory and resource leaks and pinpointing the leaks from the source code.
+
+Main Features:
+==============
+- Pinpoints memoryleaks from target hardware and emulator to source code lines
+- Discovers resource leaks from processes
+- Command line interface and Carbide.c++ Extension
+
+===============================================================================
+
+What's New in v1.9.1
+====================
+- Change: Removed Avkon and Console UI's to simplify the maintenance of the
+  tool
+- Change: Middleware layer dependencies removed so AnalyzeTool can be now used
+  also in OS layer builds
+- Fix: Move all binaries to ROM instead of ROFS to avoid ROM build
+  dependencies issues in hooked components
+
+===============================================================================
+
+Installation Notes:
+===================
+AnalyzeTool is typically preinstalled on ROM. If not, it can be added to the
+ROM with the .iby file. Alternatively, the .sis file can be found under the sis-
+directory, but the user need to sign it with their own developer certificate.
+In Nokia R&D environment, you can use directly the R&D-signed .sis file under the
+internal\sis directory.
+
+When signing with own developer certificate, the following capabilities are
+needed:
+  ReadDeviceData
+  WriteDeviceData
+  DiskAdmin
+  AllFiles
+  SwEvent
+  NetworkServices
+  LocalServices
+  ReadUserData
+  WriteUserData
+  Location
+  UserEnvironment
+  CommDD
+  PowerMgmt
+  MultimediaDD
+  DRM
+  TrustedUI
+  ProtServ
+  NetworkControl
+  SurroundingsDD
+  TCB
+
+When builing AnalyzeTool against S60 3.0 or 3.1, you may need to patch your SDK
+environment first with some fixes. For more information, please refer to the
+instructions under the "envpatcher" directory.
+
+===============================================================================
+
+System Requirements:
+====================
+Basic Requirements:
+- Any S60 3.x device or emulator environment
+
+===============================================================================
+
+Compatibility Issues:
+=====================
+N/A
+
+===============================================================================
+
+Known Issues:
+=============
+- Kernel analysis are not supported.
+
+- When using monitored internal data gathering mode (-mi) and hooked
+  application contains huge amounts of allocations AnalyzeTool? storageserver
+  might run out of memory to store the data. This message "Symbian error code
+  -4" is seen when analyzing the data file with atool.exe. Solution is to use
+  external / monitored external data gathering mode. 
+
+- Switch allocator. AnalyzeTool change the application memory allocator to
+  AnalyzeTool own memory allocator and using the User::SwitchAllocator function
+  can lead to situation where the tested application does not work properly.
+  
+- AnalyzeTool hooked QT applications becomes too slow to run. Use small size
+  call stack(s) and new logging mode (external -e). 
+
+- Stif test case with AnalyzeTool can inform wrong memory leak alert.
+
+- AnalyzeTool overwrites functions TInt User::ProcessCritical(TCritical
+  aCritical) and TInt User::SetProcessCritical(TCritical aCritical), but this
+  works only when the function is called from hooked exe application. So if
+  setting critical is done from DLL (even if it's hooked with AnalyzeTool) the
+  overwriting does not work and the process stays set critical during the
+  testing.
+
+- If hooked application is closed by calling User::Exit() from DLL instead of
+  .exe application AnalyzeTool reports "abnormal process end" and can't report
+  proper memory leaks.
+ 
+===============================================================================
+
+Version History:
+================
+
+Version 1.9.0 - 8th April 2010
+==============================
+- Feature: Remove false positive memory leaks with better handling of global
+  variables
+- Feature: Automatic check of correct version of dbghelp.dll for better
+  emulator support
+- Change: HTI support removed
+- Fix: SBSVS variant compilation didn't work
+
+===============================================================================
+
+Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/atool_stub_sis.mk	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:  Stub sis makefile for Configuration UI.
+#
+
+TARGETDIR=$(EPOCROOT)EPOC32\Data\Z\System\Install
+
+SISNAME=analyzeTool_stub
+PKGNAME=analyzeTool_stub
+
+$(TARGETDIR) :
+	@perl -S emkdir.pl "$(TARGETDIR)"
+
+do_nothing :
+	rem do_nothing
+
+SISFILE=$(TARGETDIR)\$(SISNAME).sis
+
+$(SISFILE) : ..\sis\$(PKGNAME).pkg
+	makesis -s $? $@ 
+
+#
+# The targets invoked by bld...
+#
+
+MAKMAKE : do_nothing
+
+RESOURCE : do_nothing
+
+SAVESPACE : do_nothing
+
+BLD : do_nothing
+
+FREEZE : do_nothing
+
+LIB : do_nothing
+
+CLEANLIB : do_nothing
+
+FINAL : $(TARGETDIR) $(SISFILE)
+
+CLEAN : 
+	-erase $(SISFILE)
+
+RELEASABLES : 
+	@echo $(SISFILE)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <platform_paths.hrh>
+
+
+#include "../commandlineengine/group/bld.inf"
+#include "../staticlib/group/bld.inf"
+#include "../storageserver/group/bld.inf"
+#include "../kerneleventhandler/group/bld.inf"
+#include "../analyzetoolcleaner/group/bld.inf"
+#include "../dynamicmemoryhook/group/bld.inf"
+
+PRJ_EXPORTS
+//../rom/analyzetool.iby                          CORE_IBY_EXPORT_PATH(tools,analyzetool.iby)
+../rom/analyzetool_rom.iby                      CORE_IBY_EXPORT_PATH(tools/rom,analyzetool_rom.iby)
+
+/*
+PRJ_MMPFILES
+#ifndef SBSV2
+  #ifdef MARM
+    gnumakefile atool_stub_sis.mk
+  #endif
+#endif
+
+PRJ_EXTENSIONS
+#ifdef SBSV2
+  #ifdef MARM
+     START EXTENSION app-services/buildstubsis
+     OPTION SRCDIR ../sis
+     OPTION SISNAME analyzeTool_stub
+     END
+  #endif
+#endif
+*/  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/inc/atlog.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions of logging macros for Analyze Tool S60 modules.
+*
+*/
+
+#ifndef __ATLOG_H__
+#define __ATLOG_H__
+
+#ifdef _DEBUG
+//To enable/disable logging uncomment/comment the next line
+// #define LOGGING_ENABLED  //Enable logging
+//Uncomment next to enable logging only LOGSTR1 lines
+// #define LOGGING_ENABLED_FAST //Logging only function names
+
+//Disable next to use file logging
+ #define USE_RDEBUG
+#endif
+
+//Do not alter the code below this
+
+#ifdef __KERNEL_MODE__
+
+ #ifdef LOGGING_ENABLED
+  #include <kernel.h> 
+  #define LOGSTR1( AAA ) 			{ Kern::Printf( AAA ); }
+  #define LOGSTR2( AAA, BBB ) 			{ Kern::Printf( AAA, BBB ); }
+ #else
+  #define LOGSTR1( AAA )
+  #define LOGSTR2( AAA, BBB )
+ #endif
+
+#else // #ifdef __KERNEL_MODE__
+
+ #ifdef LOGGING_ENABLED
+
+//  INCLUDES
+  #include <flogger.h>
+  #ifdef USE_RDEBUG
+   #include <e32svr.h>
+  #endif
+
+// CONSTANTS
+  _LIT( KAtLoggingFolder, "atlog" );
+  _LIT( KAtLoggingFile  , "LOG.TXT" );
+  #define ONE_SPACE_MARGIN	_S(" ")
+
+// ---------------------------------------------------------------------------------
+// Internal MACROS. Do not call these directly, use the External MACROS instead
+// ---------------------------------------------------------------------------------
+
+  #ifdef LOGGING_ENABLED_FAST
+
+   #ifdef USE_RDEBUG
+    #define INTERNAL_LOGSTR1( AAA )				{ _LIT( logdes, AAA ); RDebug::Print( logdes() ); }
+   #else  // RFileLogger is used
+    #define INTERNAL_LOGSTR1( AAA )				{ _LIT( logdes, AAA ); RFileLogger::Write( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, logdes() ); }
+   #endif // USE_RDEBUG
+   #define INTERNAL_LOGSTR2( AAA, BBB )
+   #define INTERNAL_LOGSTR3( AAA, BBB, CCC )
+   #define INTERNAL_LOGMEM
+   #define INTERNAL_LOG( AAA )
+
+  #else
+  
+   #ifdef USE_RDEBUG
+    #define INTERNAL_LOGDESC8( AAA )				{ TBuf<100> tmp; if( sizeof( AAA ) < 100 ) tmp.Copy( AAA ); RDebug::Print( tmp );}
+    #define INTERNAL_LOGSTR1( AAA )				{ _LIT( logdes, AAA ); RDebug::Print( logdes() ); }
+    #define INTERNAL_LOGSTR2( AAA, BBB )			{ _LIT( logdes, AAA ); RDebug::Print( TRefByValue<const TDesC>( logdes()), BBB ); }
+    #define INTERNAL_LOGSTR3( AAA, BBB, CCC )	{ _LIT( logdes, AAA ); RDebug::Print( TRefByValue<const TDesC>(logdes()), BBB, CCC ); }
+    #define INTERNAL_LOGMEM						{ _LIT( logdes, "Heap size: %i" );  TBuf<50> buf; TInt a; User::AllocSize( a ); buf.Format( logdes, a ); RDebug::Print( buf ); }
+    #define INTERNAL_LOG( AAA )					AAA
+   #else  // RFileLogger is used
+    #define INTERNAL_LOGSTR1( AAA )				{ _LIT( logdes, AAA ); RFileLogger::Write( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, logdes() ); }
+    #define INTERNAL_LOGSTR2( AAA, BBB ) 		{ _LIT( logdes, AAA ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, TRefByValue<const TDesC>( logdes()), BBB ); }
+    #define INTERNAL_LOGSTR3( AAA, BBB, CCC) 	{ _LIT( logdes, AAA ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, TRefByValue<const TDesC>(logdes()), BBB, CCC ); }
+    #define INTERNAL_LOGMEM 					{ _LIT( logdes, "Heap size: %i" ); TMemoryInfoV1Buf info; UserHal::MemoryInfo(info); TInt freeMemory = info().iFreeRamInBytes; TBuf<50> buf; buf.Format( logdes, freeMemory ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, buf ); }
+    #define INTERNAL_LOG( AAA )					AAA
+   #endif // USE_RDEBUG
+
+  #endif
+
+ #else
+
+  #define INTERNAL_LOGSTR1( AAA )
+  #define INTERNAL_LOGSTR2( AAA, BBB )
+  #define INTERNAL_LOGSTR3( AAA, BBB, CCC )
+  #define INTERNAL_LOGMEM
+  #define INTERNAL_LOG( AAA )
+
+ #endif
+
+// ---------------------------------------------------------------------------------
+// External MACROS. Use these in code
+// ---------------------------------------------------------------------------------
+// Logging of string
+// i.e.: LOGSTR1( "Whoo-haa!" );
+ #define LOGSTR1( AAA ) { INTERNAL_LOGSTR1( AAA ); }
+
+// Logging of string + integer value
+// i.e.: LOGSTR2( "CHttpd status %i:", iStatus );
+ #define LOGSTR2( AAA, BBB ) { INTERNAL_LOGSTR2( AAA, BBB ); }
+
+// Logging of descriptor + 2 integers
+// i.e.: LOGSTR3( "Jippii %i %i", val1, val2 );
+ #define LOGSTR3( AAA, BBB, CCC ) { INTERNAL_LOGSTR3( AAA, BBB, CCC ); }
+
+// Log heap size
+ #define LOGMEM         { INTERNAL_LOGMEM }
+
+// Logging variable operations  
+ #define LOG( AAA )     INTERNAL_LOG( AAA )
+
+#endif // #ifdef __KERNEL_MODE__
+
+#endif // __ATLOG_H__
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/group/atoolkerneleventhandler.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for the AToolKernelEventHandler
+*
+*/
+
+#include <platform_paths.hrh>
+#include <kernel/kern_ext.mmh>
+#include "../../symbian_version.hrh"
+
+TARGET	     	atoolkerneleventhandler.ldd
+TARGETTYPE   	ldd
+CAPABILITY		ALL
+
+SMPSAFE
+
+USERINCLUDE   	../inc
+USERINCLUDE   	../../inc
+
+OS_LAYER_KERNEL_SYSTEMINCLUDE
+
+SOURCEPATH    ../src
+
+SOURCE        analyzetoolchannel.cpp
+SOURCE        analyzetooldevice.cpp
+SOURCE        analyzetooleventhandler.cpp
+
+LIBRARY       flogger.lib
+#ifdef WINSCW
+LIBRARY       emulator.lib
+	start wins
+	win32_headers
+	end
+#endif // WINSCW
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 ) || defined(BSW_FLEXIBLE_MEMORY_MODEL)
+MACRO	MCL_ROBJECTIX
+#endif
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../inc/analyzetool.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetool.h)
+../inc/atcommon.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/atcommon.h)
+../inc/analyzetool.inl OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetool.inl)
+../inc/analyzetooltraceconstants.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetooltraceconstants.h)
+
+PRJ_MMPFILES
+atoolkerneleventhandler.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/analyzetooldevicedrivertest.mmp
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetool.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,325 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class RAnalyzeTool.
+*
+*/
+
+
+#ifndef __ANALYZETOOL_H__
+#define __ANALYZETOOL_H__
+
+// INCLUDES
+#include <e32cmn.h>
+
+//Version information for command line engine.
+//Tells the version of AT core componenets.
+//ANALYZETOOL_CORE_VERSION_FOR_CLE 1.9.1
+
+// CONSTANTS
+inline TVersion KAnalyzeToolLddVersion() { return TVersion(1, 0, 1); }
+
+/* The name of the analyze tool device driver*/
+_LIT( KAnalyzeToolLddName, "AToolKernelEventHandler" );
+
+/* The priority of AnalyzeTool Dfc */
+const TInt KAnalyzeToolThreadPriority = 27;
+
+/* The name of the AnalyzeTool DFC */
+_LIT8( KAnalyzeToolThreadName, "AnalyzeToolThreadDfc" );
+
+/* The panic literal */
+_LIT( KClientPanic, "AnalyzeTool" );
+
+//const TInt KATMaxCallstackLength = 20;
+
+/* The device handler panic codes */
+enum TPanic
+	{
+	EPanicRequestPending,
+	EPanicNoRequestPending,
+	EPanicUnsupportedRequest
+	};
+
+// Size of following must be multiple of 4 bytes.
+
+class TMainThreadParams
+	{
+	public:
+		RAllocator* iAllocator;
+		TBool       iAlone;
+		TUint       iProcessId;
+	};
+typedef TPckgBuf<TMainThreadParams> TMainThreadParamsBuf;
+
+class TLibraryInfo
+	{
+	public:
+		TBuf8<KMaxLibraryName> iLibraryName;
+		TLinAddr  iRunAddress;
+		TUint32   iSize;
+		TInt      iIndex;
+		TUint     iProcessId;
+	};
+
+typedef TPckgBuf<TLibraryInfo> TLibraryInfoBuf;
+
+class TCodesegInfo
+	{
+	public:
+		TBuf8<KMaxLibraryName> iFullName;
+		TLinAddr iRunAddress;
+		TUint32  iSize;
+		TInt  iIndex;
+		TUint iProcessId;
+		TInt  iCodesegIndex; 
+		TLinAddr iFileEntryPoint;
+		TInt     iFuntionCount;
+		TLibraryFunction iFirstFunction;
+		TModuleMemoryInfo iMemoryInfo;
+	};
+
+typedef TPckgBuf<TCodesegInfo> TCodesegInfoBuf;
+
+class TThreadParams
+	{		
+	public:
+	    TLinAddr iStackAddress;
+	    TInt iStackSize;
+	    TUint iThreadId;
+	};
+
+typedef TPckgBuf<TThreadParams> TThreadParamsBuf;
+
+class TProcessIdentityParams
+	{		
+	public:
+		TBuf8<KMaxProcessName> iProcessName;
+		TInt iDynamicCount;
+		TInt iCodesegCount;
+		TUint iProcessId;
+		TUint iThreadId;
+	    TLinAddr iStackAddress;
+	    TInt iStackSize;
+	};
+
+typedef TPckgBuf<TProcessIdentityParams> TProcessIdentityParamsBuf;
+
+class TLibraryEventInfo
+	{
+	public:
+		enum TLibraryEvent
+			{ 
+			ELibraryAdded = 0, 
+			ELibraryRemoved,
+			EKillThread 
+			};
+					
+	public:
+		TUint iProcessId;
+		TBuf8<KMaxLibraryName> iLibraryName;
+		TLinAddr iRunAddress;
+		TUint32 iSize;
+		TLibraryEvent iEventType;
+		TUint iThreadId;
+	};
+
+typedef TPckgBuf<TLibraryEventInfo> TLibraryEventInfoBuf;
+
+class TProcessHandleInfo
+	{
+	public:
+		TInt     iProcessHandleCount;
+		TInt     iThreadHandleCount;
+		TInt     iIndex;
+		TInt     iThreadCount;
+		TLinAddr iUserStackRunAddress;
+		TInt     iUserStackSize;
+		TUint    iProcessId;
+	};
+
+typedef TPckgBuf<TProcessHandleInfo> TProcessHandleInfoBuf;
+
+/**
+*  A class for particular process's current handle count
+*/
+class TATProcessHandles
+    {
+    public:
+    
+        /** The ID of the process. */
+        TUint iProcessId;
+        
+        /** The number of current handles in the library. */
+        TInt iCurrentHandleCount;
+    };
+
+typedef TPckgBuf<TATProcessHandles> TATProcessHandlesBuf;
+
+class TClientCount
+    {
+    public:
+    
+        /** The count of clients */
+        TInt iClientCount;     
+    };
+
+typedef TPckgBuf<TClientCount> TClientCountBuf;
+
+class TATMemoryModel
+    {
+    public :
+        /* Memory model*/
+        TUint32 iMemoryModel;
+    };
+typedef TPckgBuf<TATMemoryModel> TATMemoryModelBuf;
+
+// CLASS DECLARATION
+
+/**
+*  The user-side handle to a logical channel which provides functions to 
+*  open a channel and to make requests to a analyze tool device driver. 
+*/
+
+class RAnalyzeTool : public RBusLogicalChannel
+	{
+	
+	public:
+		
+	/** Enumeration of supported functions */
+	enum TBasicAnalyzerControl
+		{
+		EGetProcessInfo = 0, /* The process information */
+		EGetCodesegInfo,	 /* The codesegment information */
+		EGetLibraryInfo,     /* The library information */
+		EGetDynamicInfo,	 /* The count of dynamic code in the process */
+		ELibraryEvent,       /* Subscribe events from library events */
+		ECancelLibraryEvent, /* Cancel subscribetion of library events */
+		ECurrentClientCount,  /* The count of clients in device driver */
+		EMainThreadAlloctor,
+		EThreadStack,
+		EGetProcessHandle,	/* Gets process global handles info*/
+		EGetCurrentHandles, /* Get a process's current handle count */
+		EGetMemoryModel
+		};
+			
+#ifndef __KERNEL_MODE__
+
+        /**
+        * Opens a handle to a logical channel.
+        * @return TInt Returns KErrNone, if successful or otherwise 
+        		  one of the other system-wide error codes
+        */
+		inline TInt Open();
+
+        /**
+        * Acquires process information.
+        * @param aProcessIdentityParams The process information which 
+        								is filled by the device driver
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline TInt GetProcessInfo( 
+				TProcessIdentityParamsBuf& aProcessIdentityParams );
+
+        /**
+        * Acquires codeseg information.
+        * @param aCodesegInfo The codeseg information which 
+        					  is filled by the device driver
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline TInt GetCodesegInfo( TCodesegInfoBuf& aCodesegInfo );
+		
+        /**
+        * Acquires library information.
+        * @param aLibraryInfo The library information which 
+        					  is filled by the device driver
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline TInt GetLibraryInfo( TLibraryInfoBuf& aLibraryInfo );
+				
+        /**
+        * Subscribes library event.
+        * @param aStatus The request status object for this request. 
+        * @param aLibraryInfo The library information which 
+        					  is filled by the device driver
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline void LibraryEvent( TRequestStatus& aStatus, 
+		                          TLibraryEventInfo& aLibraryInfo );
+		
+        /**
+        * Cancels subscribetion of the library event.
+        */
+		inline void CancelLibraryEvent();
+
+        /**
+        * Acquires device driver current client count.
+        * @param aClientCount A reference to TInt which is 
+        				      updated by the device driver.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline TInt ClientCount( TClientCountBuf& aClientCount );
+		
+        /**
+        * Acquires process main thread RAllocator
+        * @param aMainThreadParams The main thread information which 
+        					        is filled by the device driver
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */	
+		inline TInt MainThreadAlloctor( TMainThreadParamsBuf& aMainThreadParams );
+		
+		/**
+		* Acquires main thread stack address.
+		* @param aThreadStack Pointer to the TThreadParams object.
+		* @return TInt Returns KErrNone, if successful
+					   otherwise one of the other system-wide error codes
+		*/
+		inline TInt ThreadStack( TThreadParamsBuf& aThreadStack );
+
+        /**
+        * Acquires information about process global handles.
+        * @param aProcessHandleInfo Pointer to the TProcessHandleInfo object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		inline TInt GetProcessHandleInfo( TProcessHandleInfoBuf& aProcessHandleInfo );
+
+        /**
+        * Acquires a process's current handle count.
+        * @param aProcessHandles Pointer to the TATProcessHandles object.
+        * @return TInt Returns KErrNone, if successful
+                       otherwise one of the other system-wide error codes
+        */
+        inline TInt GetCurrentHandleCount( TATProcessHandlesBuf& aProcessHandles );
+
+        /**
+         * Acquires memory model system uses.
+         * @param aMemoryModel pointer to the TATMemoryModelBuf object.
+         */
+        inline TInt GetMemoryModel( TATMemoryModelBuf& aMemoryModel );
+        
+#endif // #ifndef __KERNEL_MODE__
+	};
+
+// INLINES
+#include <analyzetool/analyzetool.inl>
+
+#endif // #ifndef __ANALYZETOOL_H__
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetool.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for inline methods of the class RAnalyzeTool.
+*
+*/
+
+
+#ifndef __ANALYZETOOL_INL
+#define __ANALYZETOOL_INL
+
+#ifndef __KERNEL_MODE__
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::Open()
+// Opens a handle to a analyze tool device driver
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::Open()
+	{
+	return DoCreate( KAnalyzeToolLddName, 
+					 KAnalyzeToolLddVersion(), 
+					 KNullUnit, 
+					 NULL, 
+					 NULL, 
+					 EOwnerProcess );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetProcessInfo()
+// Acquires process information.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetProcessInfo( 
+		TProcessIdentityParamsBuf& aProcessIdentityParams )
+	{
+	return DoControl( EGetProcessInfo, &aProcessIdentityParams, NULL );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetCodesegInfo()
+// Acquires codeseg information.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetCodesegInfo( TCodesegInfoBuf& aCodesegInfo )
+	{
+	return DoControl( EGetCodesegInfo, &aCodesegInfo, NULL );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetLibraryInfo()
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetLibraryInfo( TLibraryInfoBuf& aLibraryinfo )
+	{
+	return DoControl( EGetLibraryInfo, &aLibraryinfo, NULL );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::LibraryEvent()
+// Subscribes library event.
+// ----------------------------------------------------------------------------
+//
+inline void RAnalyzeTool::LibraryEvent( TRequestStatus& aStatus,
+	TLibraryEventInfo& aLibInfo )
+	{
+	return DoRequest( ELibraryEvent, aStatus, (TAny*)&aLibInfo );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::CancelLibraryEvent()
+// Cancels subscribetion of the library event.
+// ----------------------------------------------------------------------------
+//
+inline void RAnalyzeTool::CancelLibraryEvent()
+	{
+	DoControl( ECancelLibraryEvent, NULL, NULL);
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::ClientCount()
+// Acquires the count of device driver current users
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::ClientCount( TClientCountBuf& aClientCount )
+	{
+	return DoControl( ECurrentClientCount, &aClientCount, NULL );
+	}
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::MainThreadAlloctor()
+// Acquires information about process main thread
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::MainThreadAlloctor( 
+	        TMainThreadParamsBuf& aMainThreadParams )
+    {
+    return DoControl( EMainThreadAlloctor, &aMainThreadParams, NULL );
+    }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::ThreadStack()
+// Acquires main thread stack address.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::ThreadStack( TThreadParamsBuf& aThreadStack )
+    {
+    return DoControl( EThreadStack, &aThreadStack, NULL );
+    }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetProcessHandleInfo()
+// Acquires information about process handles
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetProcessHandleInfo( 
+		    TProcessHandleInfoBuf& aProcessHandleInfo )
+    {
+    return DoControl( EGetProcessHandle, &aProcessHandleInfo, NULL );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCurrentHandleCount()
+// Acquires a process's current handle count
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetCurrentHandleCount( 
+		    TATProcessHandlesBuf& aProcessHandles )
+    {
+    return DoControl( EGetCurrentHandles, &aProcessHandles, NULL );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetMemoryModel()
+// Acquires memory model system uses.
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetMemoryModel( 
+            TATMemoryModelBuf& aMemoryModel )
+    {
+    return DoControl( EGetMemoryModel, &aMemoryModel, NULL );
+    }
+
+#endif // #ifndef __KERNEL_MODE__
+
+#endif // __ANALYZETOOL_INL
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetoolchannel.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class DAnalyzeToolChannel
+*
+*/
+
+
+#ifndef __ANALYZETOOLCHANNEL_H__
+#define __ANALYZETOOLCHANNEL_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include <kernel/kernel.h>
+#ifdef __WINSCW__
+#include <memmodel/emul/win32/memmodel.h>
+#endif // __WINSCW__
+
+// FORWARD DECLARATIONS
+class DAnalyzeToolEventHandler;
+
+// CLASS DECLARATION
+
+/**
+* The implementation of the abstract base class for a logical channel.
+*/
+class DAnalyzeToolChannel : public DLogicalChannel
+	{
+	public:
+		
+        /**
+        * C++ default constructor.
+        */
+		DAnalyzeToolChannel();
+		
+        /**
+        * Destructor.
+        */
+		~DAnalyzeToolChannel();
+		
+	protected: // from DLogicalChannel
+		
+        /**
+        * Creates the logical channel.
+        * @param aUnit A unit of the device.
+        * @param anInfo A pointer to an explicit 8-bit descriptor containing 
+        			    extra information for the physical device
+        * @param aVer The required version of the logical device
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		virtual TInt DoCreate( TInt aUnit, 
+							   const TDesC8* anInfo, 
+							   const TVersion &aVer );
+    
+        /**
+        * Handles a client request.
+        * @param aFunction The requested function.
+        * @param a1 A 32-bit value passed to the kernel-side. Its meaning 
+        			  depends on the device driver requirements
+        * @param a2 A 32-bit value passed to the kernel-side. Its meaning
+        			  depends on the device driver requirements
+        * @param aMessage Reference to received thread message.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		virtual TInt DoControl( TInt aFunction, TAny* a1, TAny* a2, TThreadMessage& aMessage );	
+		
+		/**
+		* Processes a message for this logical channel.
+		* This function is called in the context of a DFC thread.
+		* @param aMsg  The message to process.
+		*/
+		virtual void HandleMsg( TMessageBase* aMsg );
+		
+        /**
+        * Handles a client asynchronous request.
+        * @param aFunction The requested function.
+        * @param aStatus Pointer to client TRequestStatus.
+        * @param a1 A 32-bit value passed to the kernel-side. Its meaning 
+        			  depends on the device driver requirements
+        * @param a2 A 32-bit value passed to the kernel-side. Its meaning
+        			  depends on the device driver requirements
+        * @param aMessage Reference to received thread message.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		virtual TInt DoRequest( TInt aFunction, 
+								TRequestStatus* aStatus, 
+								TAny* a1, 
+								TAny* a2, 
+								TThreadMessage& aMessage );
+		
+        /**
+        * Cancels outstanding asynchronous request.
+        */
+		virtual void DoCancel();
+
+	private:
+		
+        /**
+        * Acquires current process information
+        * @param aProcessInfo Pointer to the TProcessIdentityParams object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt GetProcessInfo( TAny* aProcessInfo, TThreadMessage& aMessage );
+		
+        /**
+        * Acquires codeseg information.
+        * @param aCodesegInfo Pointer to the TCodesegInfo object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt GetCodesegInfo( TAny* aCodesegInfo, TThreadMessage& aMessage );
+		
+        /**
+        * Acquires library information.
+        * @param aLibraryInfo Pointer to the TLibraryInfo object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt GetLibraryInfo( TAny* aLibraryInfo, TThreadMessage& aMessage );
+	
+        /**
+        * Acquires information about process main thread RAllocator.
+        * @param aMainThreadParams Pointer to the TMainThreadParams object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt MainThreadAllocator( TAny* aMainThreadParams, 
+								  TThreadMessage& aMessage );
+		
+		/**
+		* Acquires main thread stack address.
+		* @param aThreadStack Pointer to the TThreadParams object.
+		* @return TInt Returns KErrNone, if successful
+					   otherwise one of the other system-wide error codes
+		*/
+		TInt ThreadStack( TAny* aThreadStack, 
+						  TThreadMessage& aMessage );
+
+        /**
+        * Acquires information about process global handles.
+        * @param aProcessHandleInfo Pointer to the TProcessHandleInfo object.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt GetProcessHandleInfo( TAny* aProcessHandleInfo, 
+								   TThreadMessage& aMessage );
+
+        /**
+        * Acquires a process's current handle count.
+        * @param aProcessHandles Pointer to the TATProcessHandles object.
+        * @return TInt Returns KErrNone, if successful
+                       otherwise one of the other system-wide error codes
+        */
+        TInt GetCurrentHandleCount( TAny* aProcessHandles, 
+									TThreadMessage& aMessage );
+        
+        /**
+		* Acquires the count of current device driver users.
+		* @param aClientCount A reference to TInt variable
+		* @return TInt Returns KErrNone, if successful
+        *               otherwise one of the other system-wide error codes
+		*/			
+        TInt ClientCount( TAny* aClientCount, 
+						  TThreadMessage& aMessage );
+		
+        /**
+         * Acquires memory model system uses.
+         * @return TInt Returns KErrNone, if successful
+         *              otherwise one of the other system-wide error codes
+         */
+        TInt GetMemoryModel( TAny* aMemoryModel,
+                            TThreadMessage& aMessage );
+        
+        #ifdef __WINSCW__
+        /**
+		* Gets module dependencies
+		* @param aModule Module handle
+		*/
+        void GetModuleDependencies( HMODULE aModule );
+        #endif // __WINSCW__
+        
+	private: //Member variables
+		
+		/* Handler which receives kernel events */
+		DAnalyzeToolEventHandler* iEventHandler;
+		
+		#ifdef __WINSCW__
+		/* Code segment array */
+		RArray<TCodesegInfo> iCodeSeg;
+		#endif // __WINSCW__
+		
+		/* A DFC queue for communication */
+		TDynamicDfcQue* iOwnDfcQ;
+
+	};
+
+#endif // #ifndef __ANALYZETOOLCHANNEL_H__
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooldevice.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class DAnalyzeToolDevice.
+*
+*/
+
+
+#ifndef __ANALYZETOOLEVICE_H__
+#define __ANALYZETOOLEVICE_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include <kernel/kernel.h>
+
+// CLASS DECLARATION
+
+/**
+* The implementation of the abstract base class for an LDD factory object.
+*/
+
+class DAnalyzeToolDevice : public DLogicalDevice
+	{
+	public:
+	
+        /**
+        * C++ default constructor.
+        */
+		DAnalyzeToolDevice();
+		
+	public: // from DLogicalDevice
+	
+        /**
+        * Second stage constructor.
+        @return KErrNone or standard error code.
+        */
+		virtual TInt Install();
+	
+        /**
+        * Gets the driver's capabilities.
+        @param aDes A user-side descriptor into which capabilities 
+        			information is to be written.
+        */
+		virtual void GetCaps( TDes8& aDes ) const;
+		
+        /**
+        * Called by the kernel's device driver framework to 
+        * create a Logical Channel.
+        @param aChannel Set to point to the created Logical Channel
+        @return KErrNone or standard error code.
+        */
+		virtual TInt Create( DLogicalChannelBase*& aChannel );
+	};
+
+
+#endif // __ANALYZETOOLEVICE_H__
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooleventhandler.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class DAnalyzeToolEventHandler.
+*
+*/
+
+
+#ifndef __ANALYZETOOLEVENTHANDLER_H__
+#define __ANALYZETOOLEVENTHANDLER_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include "atlog.h"
+#include <kernel/kernel.h>
+
+// CLASS DECLARATION
+
+/**
+* Callback class for kernel events
+*/
+
+class DAnalyzeToolEventHandler : public DKernelEventHandler
+	{
+	public:
+	
+        /**
+        * C++ default constructor.
+        */
+		inline DAnalyzeToolEventHandler( TDfcQue* aDfcQ );
+		
+        /**
+        * Destructor.
+        */ 
+		~DAnalyzeToolEventHandler();
+		
+        /**
+        * Second stage constructor.
+        * @param aDevice A pointer to device where the event handler belongs.
+        * @param aProcessId Owner process id.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		TInt Create( DLogicalDevice* aDevice, const TUint aProcessId );
+		
+        /**
+        * Subscribes library event.
+        * @param aStatus The request status object for this request. 
+        * @param aLibraryInfo The library information which 
+        					  is filled by the device driver
+        * @param aMessage Reference to received thread message.
+        * @return TInt Returns KErrNone, if successful
+        			   otherwise one of the other system-wide error codes
+        */
+		void InformLibraryEvent( TRequestStatus* aStatus, 
+								 TAny* aLibraryInfo,
+								 TThreadMessage& aMessage );
+        
+        /**
+        * Cancels subscribetion of the library event.
+        */
+		void CancelInformLibraryEvent();
+
+        /**
+        * Static function for DFC events.
+        * @param aPtr Pointer to DAnalyzeToolEventHandler object. 
+        */
+	    static void EventDfc( TAny* aPtr );
+		
+	private:
+	
+        /**
+        * Pointer to  callback function called when an event occurs.
+        * @param aEvent Designates what event is dispatched.
+        * @param a1 Event-specific paramenter.
+        * @param a2 Event-specific paramenter.
+        * @param aThis A pointer to the event handler
+        * @return TUint Bitmask returned by callback function.
+        */
+		static TUint EventHandler( TKernelEvent aEvent, 
+								   TAny* a1, 
+								   TAny* a2, 
+								   TAny* aThis );
+	
+	private:
+	
+        /**
+        * Handles the EEventAddLibrary and EEventRemoveLibrary events
+        * @param aLib* A pointer to added/removed library.
+        * @param aThread* A pointer to thread where the libary is.
+        * @param aInfo* A reference class to be written to the client
+        */	
+		void HandleLibraryEvent( DLibrary* aLib, 
+								 DThread* aThread, 
+								 TLibraryEventInfo& aInfo );
+		
+		/**
+		* Handles the EEventKillThread events
+		* @param aThread* A pointer to the thread being terminated. 
+		* @param aInfo* A reference class
+		*/	
+		void HandleKillThreadEvent( DThread* aThread, 
+									TLibraryEventInfo& aInfo );
+		
+		/**
+		* Informs client about the occured event
+		*/	
+	    void DoEventComplete();
+					
+	private:
+	
+		/* Mutex for serializing access to event handler */
+		DMutex* iHandlerMutex;
+		
+		/* Mutex fof serializing access to event handler variables */
+		DMutex* iDataMutex;		
+		
+		/* If the client is a RAM-loaded LDD (or PDD), it is possible for the DLL to
+		be unloaded while the handler is still in use.  This would result in an
+		exception.  To avoid this, the handler must open a reference to the
+		DLogicalDevice (or DPhysicalDevice) and close it in its d'tor. */
+		DLogicalDevice* iDevice;    
+				
+		/* Owner process ID */
+		TUint iProcessId;
+		
+		/* Event array */
+		RArray<TLibraryEventInfo> iEventArray;
+				
+		/* Pointer to client's TRequestStatus */ 
+		TRequestStatus* iClientRequestStatus;
+		
+		/* Pointer to client's thread */ 
+		DThread* iClientThread;
+
+		/* Pointer to client's TLibraryEventInfo */ 
+		TAny* iClientInfo;
+		
+		/* DFC for informing events to the client */ 
+		TDfc iEventDfc;
+	};
+	
+// ----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::DAnalyzeToolEventHandler()
+// C++ default constructor.
+// ----------------------------------------------------------------------------
+//
+inline DAnalyzeToolEventHandler::DAnalyzeToolEventHandler( TDfcQue* aDfcQ ) :	
+	DKernelEventHandler( EventHandler, this ),
+	iEventDfc( EventDfc, this, 1 )
+	{
+	LOGSTR1( "ATDD DAnalyzeToolEventHandler::DAnalyzeToolEventHandler()" );
+	iEventDfc.SetDfcQ( aDfcQ );
+	}
+
+#endif // __ANALYZETOOLEVENTHANDLER_H__
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooltraceconstants.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Common declarations/definitions for Analyze Tool.
+*
+*/
+
+
+
+#ifndef __ANALYZETOOLTRACECONSTANTS_H__
+#define __ANALYZETOOLTRACECONSTANTS_H__
+
+#include <analyzetool/atcommon.h>
+
+// Trace version information.
+const TUint KATTraceVersion = 0x2;
+
+// The default logging mode 
+const TATLogOption KDefaultLoggingMode = EATLogToTrace;
+
+// When needed, update the storage data file's version number directly inside
+// the _LIT8 macro. Note, if you change this string, also remember to update
+// the constant "KVersionStringLength" below.
+
+_LIT8( KDataFileVersion, "DATA_FILE_VERSION 11\r\n" );
+_LIT8( KProcessStart, "PROCESS_START %S %x " );
+_LIT16( KProcessStart16, "PROCESS_START %S %x " );
+_LIT8( KDllLoad, "DLL_LOAD %S %Lx %x %x\r\n" );
+_LIT16( KDllLoad16, "DLL_LOAD %S %Lx %x %x\r\n" );
+_LIT8( KDllUnload, "DLL_UNLOAD %S %Lx %x %x\r\n" );
+_LIT16( KDllUnload16, "DLL_UNLOAD %S %Lx %x %x\r\n" );
+_LIT8( KProcessEnd, "PROCESS_END %x " );
+_LIT16( KProcessEnd16, "PROCESS_END %x " );
+_LIT8( KProcessEndAbnormal, "PROCESS_END %x ABNORMAL " );
+_LIT8( KMemoryLeak, "MEM_LEAK " ); // Remember to update value of KMemoryLeak when changing this.
+_LIT8( KHandleLeak, "HANDLE_LEAK %S %x\r\n" );
+_LIT16( KHandleLeak16, "HANDLE_LEAK %S %x\r\n" );
+_LIT8( KErrorOccured, "ERROR_OCCURED %d " );
+_LIT8( KLoggingCancelled, "LOGGING_CANCELLED %x\r\n" );
+_LIT8( KNewLine, "\r\n" );
+_LIT8( KHexaNumber, " %x" );
+_LIT8( KSpace, " " );
+_LIT8( KUdeb, "UDEB" );
+_LIT8( KUrel, "UREL" );
+    
+// Constants for logging through debug channel
+_LIT( KTraceMessage, "PCSS %x %S" );
+_LIT( KMemoryAllocHeader, "ALLOCH " );
+_LIT( KMemoryAllocFragment, "ALLOCF " );
+_LIT( KMemoryFreedHeader, "FREEH " );
+_LIT( KMemoryFreedFragment, "FREEF " );
+_LIT( KSpaceTrace, " " );
+_LIT( KNewLineTrace, "\r\n" );
+_LIT( KHexaNumberTrace, " %x" );
+_LIT( KProcessEndTrace, "PROCESS_END %x " );
+_LIT( KProcessEndAbnormalTrace, "PROCESS_END %x ABNORMAL " );
+_LIT( KErrorOccuredTrace, "ERROR_OCCURED %d " );
+_LIT( KSubtestStart, "TEST_START " );
+_LIT( KSubtestEnd, "TEST_END " );
+_LIT8( KEmpty, "" );
+_LIT( KOpenSquareBracket, "[" );
+_LIT( KCloseSquareBracket, "]" );
+_LIT( KUnderLine, "_" );
+// File name format
+_LIT( KFormat, "%S%S%02d%S");// pad char="0", field width=2
+
+// A string for setting time January 1st, 1970 AD nominal Gregorian
+_LIT( KJanuaryFirst1970, "19700000:000000.000000" );
+
+// Module name when it cannot be defined
+_LIT8( KUnknownModule, "Unknown" );
+_LIT16( KUnknownModule16, "Unknown" );
+
+// Constant time variable used to calculate timestamps for pc side.
+const TInt64  KMicroSecondsAt1970 = 62168256000000000;
+
+// The length of the string KDataFileVersion
+const TInt KVersionStringLength = 22;
+
+// The length of the string KMemoryLeak
+const TInt KMemleakLength = 9;
+
+// The maximum length of one word (32 bits) represented in the hexadecimal text format
+// without "0x" prefix
+const TInt KHexa32Length = 8;
+
+// The maximum length of one word (32 bits) represented in the decimal text format
+const TInt KDec32Length = 10;
+
+// The maximum length of a TInt64 represented in the hexadecimal text format without
+// "0x" prefix
+const TInt KHexa64Length = 16;
+
+// The length of one space character in text
+const TInt KSpaceLength = 1;
+
+// The length of the combination of carriage return and new line characters.
+const TInt KNewlineLength = 2;
+
+// The maximum length of the "PROCESS_START..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KProcessStartBufLength = 16 + KMaxProcessName + KSpaceLength + KHexa32Length +
+                                        KSpaceLength + KHexa64Length + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "DLL_LOAD..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KDllLoadBufLength = 9 + KMaxLibraryName + KSpaceLength + KHexa64Length + KSpaceLength +
+                    KHexa32Length + KSpaceLength + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "DLL_UNLOAD..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KDllUnloadBufLength = 11 + KMaxLibraryName + KHexa64Length + KSpaceLength + KSpaceLength + 
+                    KHexa32Length + KSpaceLength + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "PROCESS_END..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KProcessEndBufLength = 12 + KHexa32Length + KSpaceLength +
+                                        KHexa64Length + KNewlineLength;
+                                        
+// The maximum length of the "ERROR_OCCURED..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KErrOccuredBufLength = 14 + KDec32Length + KSpaceLength +
+                                        KHexa64Length + KNewlineLength;
+                                        
+// The maximum length of the "ALLOCH / ALLOCF..." buffer. 
+const TInt KMemAllocBufLength = 255;
+
+// The maximum length of the "FREE..." buffer.
+const TInt KMemFreedBufLength = 255;
+
+// The maximum length of the "HANDLE_LEAK..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KHandleLeakBufLength = 12 + KMaxLibraryName + KSpaceLength +
+                                        KHexa32Length + KNewlineLength;
+                                        
+// The maximum length of the "TEST_START..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KTestStartBufLength = 11 + KHexa64Length + KSpaceLength +
+                                        KATMaxSubtestIdLength + KSpaceLength + KHexa64Length + KNewlineLength;
+
+// The maximum length of the "TEST_END..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KTestEndBufLength = 9 + KHexa64Length + KSpaceLength +
+                                        KATMaxSubtestIdLength + KSpaceLength + KHexa64Length + KNewlineLength;
+
+// The maximun length of the "LOGGING_CANCELLED..." buffer. The first number is the
+// length of the line tag and one space character (see the descriptor constants above).
+const TInt KCancelBufLength = 18 + KHexa64Length + KNewlineLength;
+
+// The maximun length of the "PROCESS_END %x ABNORMAL..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KEndAbnormalBufLength = 22 + KHexa32Length + KHexa64Length + 
+                                        KSpaceLength + KNewlineLength;
+
+// The maximun length of the file name extension buffer.
+const TInt KExtensionLength = 50;
+
+// The maximun length of the process UID3 buffer.
+const TInt KProcessUidLength = 20;
+
+#endif // __ANALYZETOOLTRACECONSTANTS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/atcommon.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Common declarations/definitions for Analyze Tool.
+*
+*/
+
+
+#ifndef ATCOMMON_H_
+#define ATCOMMON_H_
+
+// CONSTANTS
+const TInt KATMaxCallstackLength = 256;
+const TInt KATMaxFreeCallstackLength = 256;
+const TInt KATMaxSubtestIdLength = 256;
+
+// The following constants only limit the configuration UI.
+// The bigger the number is, the more space will be allocated run-time
+// by the client. So, change with care.
+const TInt KATMaxProcesses = 20;
+const TInt KATMaxDlls = 30;
+
+// Constants defining call stack address range in multiple memory model.
+const TInt32 KATMultipleMemoryModelLowLimit = 0x70000000;
+const TInt32 KATMultipleMemoryModelHighLimit = 0x90000000;
+
+
+// CLASS DECLARATIONS
+
+/**
+*  A class for storing process information
+*/
+class TATProcessInfo
+    {
+    public:
+    
+        /** The ID of the process. */
+        TUint iProcessId;
+        
+        /** The name of the process. */
+        TBuf8<KMaxProcessName> iProcessName;
+        
+        /** The starting time of the process. */
+        TInt64 iStartTime;
+    };
+
+
+// ENUMERATIONS
+
+/**
+*  Enumeration for different logging modes of Analyze Tool 
+*/
+enum TATLogOption
+    {
+    /** Using the default. */
+    EATUseDefault = 0,
+    
+    /** Logging to a file in S60. */
+    EATLogToFile,
+    
+    /** Logging to debug channel. */
+    EATLogToTrace,
+    
+    /** Logging to debug channel bypassing storage server. */
+    EATLogToTraceFast,
+    
+    /** Logging switched off. */
+    EATLoggingOff
+    };
+
+/**
+*  Class which supports interfacing with AnalyzeTool exported
+*  functions. Mainly meant for STIF integration.
+*/
+class AnalyzeToolInterface
+    {
+    public:
+
+        /**
+        * This function starts subtest with a given name.
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic.
+        */
+        IMPORT_C static void StartSubTest( const TDesC8& aSubtestId );
+
+        /**
+        * This function stops a subtest with a given name.
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic. 
+        */   
+        IMPORT_C static void StopSubTest( const TDesC8& aSubtestId );
+
+    };
+    
+
+#endif /*ATCOMMON_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/sis/analyzetooldevicedriver.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,33 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeToolDeviceDriver"},(0xEDF5A8A1),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 1 File to install
+"\epoc32\release\armv5\urel\atoolkerneleventhandler.ldd"-"!:\sys\bin\atoolkerneleventhandler.ldd"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetoolchannel.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1019 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class DAnalyzeToolChannel.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetoolchannel.h"
+#include "analyzetooldevice.h"
+#include "analyzetooleventhandler.h"
+
+#include <kernel/kern_priv.h>
+#ifdef __WINSCW__
+#include <emulator.h>
+#endif // __WINSCW__
+
+#include "atlog.h"
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoCreate()
+// Creates the logical channel.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoCreate( TInt /*aUnit*/, 
+    const TDesC8* /*aInfo*/, const TVersion &aVer )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::DoCreate()" );
+
+    // Check client version.
+    if ( !Kern::QueryVersionSupported( KAnalyzeToolLddVersion(), aVer ) )
+        {
+        return KErrNotSupported;
+        }
+     
+    TInt error = Kern::DynamicDfcQCreate( iOwnDfcQ, 
+                                          KAnalyzeToolThreadPriority, 
+                                          KAnalyzeToolThreadName );
+
+    if ( KErrNone != error )
+        {
+        return error;
+        }
+
+    SetDfcQ( iOwnDfcQ );
+    
+    iMsgQ.Receive();
+   
+    // Create the event handler
+    iEventHandler = new DAnalyzeToolEventHandler( iOwnDfcQ );
+
+    // Check that everything is OK
+    if ( !iEventHandler )
+        {
+        return KErrNoMemory;
+        }
+    
+    // 2nd stage constructor for event handler
+    return iEventHandler->Create( iDevice, Kern::CurrentProcess().iId );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DAnalyzeToolChannel()
+// Constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolChannel::DAnalyzeToolChannel()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::DAnalyzeToolChannel()" );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::~DAnalyzeToolChannel()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolChannel::~DAnalyzeToolChannel()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::~DAnalyzeToolChannel()" );
+    
+    if ( iEventHandler )
+        {
+        // Cancel all processing that we may be doing
+        DoCancel();
+        
+        // Client code should use Close() instead the operator delete 
+        // to destroy the event handler. 
+        TInt error( iEventHandler->Close() );
+        if ( KErrNone != error )
+            {
+            LOGSTR2( "ATDD iEventHandler->Close(%d)", error );
+            }
+        }
+    #ifdef __WINSCW__
+        iCodeSeg.Close();
+    #endif // __WINSCW__
+    
+    // Destroy the queqe
+    if ( iOwnDfcQ )
+        {
+        iOwnDfcQ->Destroy();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoControl()
+// Handles a client request.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoControl( TInt aFunction, 
+                                     TAny* a1, 
+                                     TAny* /*a2*/, 
+                                     TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::Request()" );
+    
+    TInt ret( KErrNone );
+
+    // Check the requested function
+    switch (aFunction)
+        {
+        case RAnalyzeTool::EGetProcessInfo:
+            ret = GetProcessInfo( a1, aMessage );
+            break;
+            
+        case RAnalyzeTool::EGetCodesegInfo:
+            ret = GetCodesegInfo( a1, aMessage );
+            break;
+
+        case RAnalyzeTool::EGetLibraryInfo:
+            ret = GetLibraryInfo( a1, aMessage );
+            break;
+            
+        case RAnalyzeTool::ECancelLibraryEvent:
+            iEventHandler->CancelInformLibraryEvent();
+            break;
+            
+        case RAnalyzeTool::ECurrentClientCount:
+            ret = ClientCount( a1, aMessage );
+            break;
+
+        case RAnalyzeTool::EMainThreadAlloctor:
+            ret = MainThreadAllocator( a1, aMessage );
+            break;
+        
+        case RAnalyzeTool::EThreadStack:
+             ret = ThreadStack( a1, aMessage );
+             break;
+             
+        case RAnalyzeTool::EGetProcessHandle:
+            ret = GetProcessHandleInfo( a1, aMessage );
+            break;
+        
+        case RAnalyzeTool::EGetCurrentHandles:
+            ret = GetCurrentHandleCount( a1, aMessage );
+            break;
+        case RAnalyzeTool::EGetMemoryModel:
+            ret = GetMemoryModel( a1, aMessage );
+            break;
+            
+        // Unsupported function. Panic
+        default:
+            Kern::PanicCurrentThread( KClientPanic, EPanicUnsupportedRequest );
+            break;
+        }
+        
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoRequest()
+// Handles a client asynchronous request.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoRequest( TInt aFunction, 
+                                     TRequestStatus* aStatus, 
+                                     TAny* a1, 
+                                     TAny* /*a2*/,
+                                     TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::DoRequest()" );
+    
+    // Check the requested function
+    switch (aFunction)
+        {
+        case RAnalyzeTool::ELibraryEvent:
+            iEventHandler->InformLibraryEvent( aStatus, a1, aMessage );
+            break;
+            
+        // Unsupported function. Panic
+        default:
+            aMessage.PanicClient( KClientPanic, EPanicUnsupportedRequest );
+            break;
+        }
+        
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoCancel()
+// Cancels outstanding asynchronous request.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::DoCancel()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::DoCancel()" );
+    
+    iEventHandler->CancelInformLibraryEvent();
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::HandleMsg()
+// Processes a message for this logical channel.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::HandleMsg(TMessageBase* aMsg)
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::HandleMsg()" );
+
+    TThreadMessage& message = *(TThreadMessage*)aMsg;
+
+    // Get message type
+    TInt id = message.iValue;
+
+    // Decode the message type and dispatch it to the relevent handler function...
+    if ( id == (TInt) ECloseMsg )
+        {
+        // Channel Close
+        DoCancel();
+        message.Complete( KErrNone, EFalse );
+        }
+    else if ( id == KMaxTInt )
+        {
+        // DoCancel
+        DoCancel();
+        message.Complete( KErrNone, ETrue );
+        }
+    else if ( id < 0 )
+        {
+        // DoRequest
+        TRequestStatus* status = (TRequestStatus*) message.Ptr0();
+        TInt error = DoRequest( ~id, status, message.Ptr1(), message.Ptr2(), message );
+        if ( KErrNone != error )
+            {
+            Kern::RequestComplete( message.Client(), status, error);
+            }
+        message.Complete(KErrNone, ETrue );
+        }
+    else
+        {
+        // DoControl
+        TInt ret = DoControl( id, message.Ptr0(), message.Ptr1(), message );
+        message.Complete( ret, ETrue );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetProcessInfo()
+// Acquires current process information
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetProcessInfo( TAny* aProcessInfo, 
+                                          TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetProcessInfo()" );
+
+    // Variable for reading parameters from user side
+    TProcessIdentityParamsBuf params;
+    
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), aProcessInfo, params, 0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess& process = *Kern::ProcessFromId( params().iProcessId );  
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == &process )
+        {        
+        return KErrNotFound;
+        }
+    
+    // Temporary variable for collecting information from the process
+    TProcessIdentityParamsBuf info;
+    
+    // Collect needed information from the process
+    process.AppendName( info().iProcessName );//lint !e64 !e1514
+    
+    // Gets the current thread
+    Kern::Containers()[ EThread ]->Wait(); 
+    DThread& thread = *Kern::ThreadFromId( params().iThreadId );
+    Kern::Containers()[ EThread ]->Signal();
+   
+    if ( NULL == &thread )
+        {
+        return KErrNotFound;
+        }     
+    
+    // Stack address of the main thread
+    info().iStackAddress = thread.iUserStackRunAddress;
+    info().iStackSize    = thread.iUserStackSize;  
+    
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+        
+    // Collect needed information from the process
+    info().iDynamicCount = process.iDynamicCode.Count();
+
+    // Temporary queue for acquiring the count of codesegments
+    SDblQue queue;
+
+    // Acquire the count of codesegments
+    TInt codesegCount = process.TraverseCodeSegs( &queue, 
+                                                  NULL, 
+                                                  DCodeSeg::EMarkDebug, 
+                                                  DProcess::ETraverseFlagAdd );
+    
+    #ifndef __WINSCW__
+        info().iCodesegCount = codesegCount;    
+    #else
+    // Reset codesegment array
+    iCodeSeg.Reset();
+    
+    if ( codesegCount > 0 )
+        {
+        SDblQueLink* link = queue.iA.iNext;
+        TCodesegInfo codeinfo;
+        // Iterate through codesegments
+        for ( TInt i = 0; i < codesegCount; ++i, link = link->iNext )
+            {
+            DWin32CodeSeg* codeseg = 
+                (DWin32CodeSeg*)_LOFF( link, DCodeSeg, iTempLink );
+
+            // Aqcuire codeseg information
+            codeinfo.iFileEntryPoint = codeseg->iFileEntryPoint;
+            codeinfo.iSize = codeseg->iSize;
+            codeinfo.iFullName.Copy( codeseg->iRootName );
+            codeinfo.iRunAddress = codeseg->iRunAddress;
+            iCodeSeg.Append( codeinfo );
+            }
+        }
+    
+    // Add dependency codesegments
+    DWin32CodeSeg* pcodeSeg = (DWin32CodeSeg*)process.iCodeSeg;
+    
+    // Get dependency codesegments
+    GetModuleDependencies( pcodeSeg->iModuleHandle );
+    
+    // Set codesegment count
+    info().iCodesegCount = iCodeSeg.Count();
+    #endif
+    
+    // Removes all code segments from a queue and clear specified mark(s)
+    DCodeSeg::EmptyQueue( queue, DCodeSeg::EMarkDebug );
+
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+
+    // Writes a descriptor to a thread's process.
+    error = Kern::ThreadDesWrite( aMessage.Client(), aProcessInfo, info, 0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        return error;
+        } 
+   
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCodesegInfo()
+// Acquires codeseg information.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetCodesegInfo( TAny* aCodesegInfo, 
+                                          TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetCodesegInfo()" );
+
+    // Temporary variable for collecting information from the codeseg
+    TCodesegInfoBuf params;
+
+    TInt error( KErrArgument );
+    
+    // Reads a descriptor from a thread's process.
+    error = Kern::ThreadDesRead( aMessage.Client(), aCodesegInfo, params, 0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+
+    if ( params().iIndex < 0 )
+        {
+        return KErrArgument;
+        }
+    
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == &process )
+        {
+        return KErrNotFound;
+        }
+    
+    // Temporary variable for collecting information 
+    TCodesegInfoBuf output;
+
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+
+    #ifndef __WINSCW__
+    // Temporary queue for acquiring the codesegments
+    SDblQue queue;
+    
+    // Acquire the codesegments
+    TInt actcount = process.TraverseCodeSegs( &queue, 
+                                              NULL, 
+                                              DCodeSeg::EMarkDebug, 
+                                              DProcess::ETraverseFlagAdd );
+    if ( actcount >= params().iIndex )
+        {
+        LOGSTR1( "ATDD DAnalyzeToolChannel::GetCodesegInfo() - actcount >= params.iIndex" );
+        SDblQueLink* link = queue.iA.iNext;
+        
+        // Iterate through codesegments
+        for (TInt i = 0; i < actcount; ++i, link = link->iNext)
+            {
+            DCodeSeg* codeseg = _LOFF( link, DCodeSeg, iTempLink );
+
+            // Is the codesegments which information client wants
+            if ( i == params().iIndex )
+                {
+                // Aqcuire codeseg information
+                output().iFileEntryPoint = codeseg->iFileEntryPoint;
+                output().iSize = codeseg->iSize;
+                output().iFullName.Copy( codeseg->iRootName );
+                output().iRunAddress = codeseg->iRunAddress;
+                error = codeseg->GetMemoryInfo( output().iMemoryInfo, &process );
+                
+                if ( KErrNone == error )
+                    {
+                    // Writes a descriptor to a thread's process.
+                    error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                                  aCodesegInfo, 
+                                                  output, 
+                                                  0 );   
+                    if ( KErrNone != error )
+                        {
+                        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+                        } 
+                    }
+                break;
+                }
+            }
+        }
+    // Removes all code segments from a queue and clear specified mark(s).
+    DCodeSeg::EmptyQueue( queue, DCodeSeg::EMarkDebug );
+    
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+    
+    return error;
+    #else // WINSCW
+    
+    if ( iCodeSeg.Count() > params().iIndex )
+        {
+        // Aqcuire codeseg information
+        output().iSize = iCodeSeg[params().iIndex].iSize;
+        output().iFullName.Copy( iCodeSeg[params().iIndex].iFullName );
+        output().iRunAddress = iCodeSeg[params().iIndex].iRunAddress;
+        
+        // Writes a descriptor to a thread's process.
+        error = Kern::ThreadDesWrite( aMessage.Client(), aCodesegInfo, output, 0 ); 
+        
+        if ( KErrNone != error )
+            {
+            LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+            }
+        }
+    
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+    
+    return error;
+    #endif
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetLibraryInfo()
+// Acquires library information.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetLibraryInfo( TAny* aLibraryInfo, 
+                                          TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetLibraryInfo()" );
+
+    // Temporary variable for reading informationfrom the user side
+    TLibraryInfoBuf params;
+
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), aLibraryInfo, params, 0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+
+    if ( params().iIndex < 0 )
+        {
+        return KErrArgument;
+        }
+   
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == &process )
+        {
+        return KErrNotFound;
+        }
+    
+    // Temporary variable for collecting information from the library
+    TLibraryInfoBuf output;
+        
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+
+    // Iterate to find the right library
+    if ( params().iIndex < process.iDynamicCode.Count() )
+        {
+        // Acquire entry to the codeseg
+        SCodeSegEntry entry = process.iDynamicCode[ params().iIndex ];
+        
+        // Acquire library information
+        entry.iLib->AppendName( output().iLibraryName );//lint !e64 !e1514
+        output().iRunAddress = entry.iSeg->iRunAddress;
+        output().iSize = entry.iSeg->iSize;
+        
+        // Writes a descriptor to a thread's process.
+        error = Kern::ThreadDesWrite( aMessage.Client(), aLibraryInfo, output, 0 ); 
+        
+        if ( KErrNone != error )
+            {
+            LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+            } 
+        
+        // Exits thread critical section and releases code segment mutex.
+        Kern::EndAccessCode();
+        
+        return error;
+        }
+    else
+        {
+        // Exits thread critical section and releases code segment mutex.
+        Kern::EndAccessCode();
+        
+        return KErrArgument;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::MainThreadAllocator()
+// Acquires information about process main thread RAllocator
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::MainThreadAllocator( TAny* aMainThreadParams, 
+                                               TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::MainThreadAllocator()" );
+
+    // Temporary variable for reading client side parameters
+    TMainThreadParamsBuf params;
+
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), 
+                                      aMainThreadParams, 
+                                      params, 
+                                      0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+    
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == &process )
+        {
+        return KErrNotFound;
+        }
+
+    // Gets the current process
+    Kern::AccessCode();
+
+    // Temporary variable for collecting information from the RAllocator
+    TMainThreadParamsBuf output;
+
+    // Aqcuire a reference to the main thread RAllocator
+    output().iAllocator = process.FirstThread()->iAllocator;
+
+    // Is this only thread in the process
+    output().iAlone = process.iThreadQ.First()->Alone();
+
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+
+    // Writes a descriptor to a thread's process.
+    error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                  aMainThreadParams, 
+                                  output, 
+                                  0 ); 
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        } 
+
+    return error;
+    }    
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::ThreadStack()
+// Acquires main thread stack address
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::ThreadStack( TAny* aThreadStack, 
+                                       TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::ThreadStack()" );
+
+    // Temporary variable for reading client side parameters
+    TThreadParamsBuf params;
+
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), 
+                                      aThreadStack, 
+                                      params, 
+                                      0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+    
+    // Gets the current process
+    Kern::Containers()[ EThread ]->Wait();
+    DThread& thread = *Kern::ThreadFromId( params().iThreadId );
+    Kern::Containers()[ EThread ]->Signal();
+    
+    if ( NULL == &thread )
+        {
+        return KErrNotFound;
+        }
+    
+    // Gets the current process
+    Kern::AccessCode();
+
+    // Temporary variable for collecting information from the RAllocator
+    TThreadParamsBuf output;
+
+    // Stack address of the main thread
+    output().iStackAddress = thread.iUserStackRunAddress;
+    output().iStackSize    = thread.iUserStackSize;
+
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+
+    // Writes a descriptor to a thread's process.
+    error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                  aThreadStack, 
+                                  output, 
+                                  0 ); 
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        } 
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetProcessHandleInfo()
+// Acquires information about process global handles
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetProcessHandleInfo( TAny* aProcessHandleInfo,
+                                                TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetProcessHandleInfo()" );
+
+    // Temporary variable for collecting information from the codeseg
+    TProcessHandleInfoBuf params;
+
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), 
+                                      aProcessHandleInfo, 
+                                      params, 
+                                      0 );  
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == &process )
+        {
+        return KErrNotFound;
+        }
+    
+    // Variable holding wanted information
+    TProcessHandleInfoBuf output;
+
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+
+    // Get the process thread queue.
+    SDblQue queue = process.iThreadQ;
+    error = KErrNotFound;
+        
+    // Tests whether this doubly linked list is empty.
+    if ( !queue.IsEmpty() )
+        {
+        // Gets a pointer to the first item in this doubly linked list.
+        SDblQueLink* link = queue.First();
+        DThread* thread = _LOFF( link, DThread, iProcessLink );
+
+        if ( thread )
+            {
+            
+#ifdef MCL_ROBJECTIX
+            TInt threadHandles( thread->iHandles.ActiveCount() );
+#else
+            TInt threadHandles( thread->iHandles->ActiveCount() );
+#endif
+            
+            // Aqcuire thread information
+            //thread->AppendName( output.iThreadName );
+            output().iUserStackRunAddress = thread->iUserStackRunAddress;
+            output().iUserStackSize = thread->iUserStackSize;
+            output().iThreadHandleCount = threadHandles;
+            
+#ifdef MCL_ROBJECTIX
+            RObjectIx objectIx = process.iHandles;
+            output().iProcessHandleCount = objectIx.ActiveCount();
+#else
+            DObjectIx* objectIx = process.iHandles;
+            output().iProcessHandleCount = objectIx->ActiveCount();
+#endif
+                        
+            // Writes a descriptor to a thread's process.
+            error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                          aProcessHandleInfo, 
+                                          output, 
+                                          0 ); 
+            
+            if ( KErrNone != error )
+                {
+                LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+                } 
+            }
+        }
+
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCurrentHandleCount()
+// Acquires a process's current handle count
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetCurrentHandleCount( TAny* aProcessHandles,
+                                                 TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetCurrentHandleCount()" );
+
+    // Temporary variable for collecting information from the codeseg
+    TATProcessHandlesBuf params;
+    
+    // Reads a descriptor from a thread's process.
+    TInt error = Kern::ThreadDesRead( aMessage.Client(), 
+                                      aProcessHandles, 
+                                      params, 
+                                      0 );
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesRead error %d", error );
+        return error;
+        } 
+    
+    // Gets the current process
+    Kern::Containers()[ EProcess ]->Wait();
+    DProcess* process = Kern::ProcessFromId( params().iProcessId );
+    Kern::Containers()[ EProcess ]->Signal();
+    
+    if ( NULL == process )
+        {
+        return KErrNotFound;
+        }
+
+    // Variable holding wanted information
+    TATProcessHandlesBuf output;
+    
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+    
+    SDblQue queue = process->iThreadQ;
+    SDblQueLink* link = queue.First();
+    TInt threadHandles( 0 );
+    
+    // Iterate through current processes's threads
+    while ( link != queue.Last() )
+        {
+        DThread* thread = _LOFF( link, DThread, iProcessLink );
+        
+#ifdef MCL_ROBJECTIX
+        threadHandles += thread->iHandles.ActiveCount();
+#else
+        threadHandles += thread->iHandles->ActiveCount();
+#endif
+        
+        link = link->iNext;
+        }
+
+    if ( link == queue.Last() )
+        {
+        DThread* thread = _LOFF( link, DThread, iProcessLink );
+
+#ifdef MCL_ROBJECTIX
+        threadHandles += thread->iHandles.ActiveCount();
+#else
+        threadHandles += thread->iHandles->ActiveCount();
+#endif
+        }
+    
+    output().iCurrentHandleCount = threadHandles;
+    
+    // Writes a descriptor to a thread's process.
+    error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                  aProcessHandles, 
+                                  output, 
+                                  0 ); 
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        } 
+    
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::ClientCount()
+// Acquires the count of current device driver users.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::ClientCount( TAny* aClientCount,
+                                       TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::ClientCount()" );
+    
+    // Enters thread critical section and acquires code segment mutex.
+    Kern::AccessCode();
+    
+    // Variable holding wanted information
+    TClientCountBuf output;
+    
+    // Get the number of DLogicalChannelBase objects currently in existence which
+    // have been created from this LDD.
+    output().iClientCount = DLogicalChannelBase::iDevice->iOpenChannels;
+    LOGSTR2( "ATDD > iOpenChannels count: %d", output().iClientCount ); 
+    
+    // Writes a descriptor to a thread's process.
+    TInt error = Kern::ThreadDesWrite( aMessage.Client(), 
+                                       aClientCount, 
+                                       output, 
+                                       0 ); 
+    
+    if ( KErrNone != error )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        } 
+    
+    // Exits thread critical section and releases code segment mutex.
+    Kern::EndAccessCode();
+    
+    return error;
+    }
+
+#ifdef __WINSCW__
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetModuleDependencies()
+// Get module dependencies
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::GetModuleDependencies( HMODULE aModule )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetModuleDependencies()" );
+
+    Emulator::TModule etm( aModule );
+    TUint32 dllSize( 0 );
+    // Temporary variable for collecting information from the codeseg
+    TCodesegInfo info;
+    TBool found( EFalse );
+    
+    const IMAGE_IMPORT_DESCRIPTOR* imports = etm.Imports();
+    while( imports->Characteristics != 0 )
+        {
+        // Reset flag
+        found = EFalse;
+        
+        // Get dll name
+        const TUint8* nameAddr = ( const TUint8* )( imports->Name + ( TInt )etm.iBase );
+        TPtrC8 namePtr( nameAddr );     
+        
+        // Get dll run address
+        Emulator::TModule imp_etm( ( PCSTR )etm.Translate( imports->Name ) );        
+        const TUint8* runAddr = ( const TUint8* )imp_etm.iBase;
+        
+        // Get dll size
+        const IMAGE_NT_HEADERS32* ntHeader = imp_etm.NtHeader();
+        dllSize = ntHeader->OptionalHeader.SizeOfImage;       
+        
+        // Check if DLL already exists in codesegment list
+        for( TInt i = 0; i < iCodeSeg.Count(); i++ )
+            {
+            if ( iCodeSeg[i].iFullName.Compare( namePtr ) == KErrNone )
+                {
+                found = ETrue;
+                break;
+                }
+            }
+        
+        if ( !found )
+            {
+            info.iSize = dllSize;
+            info.iFullName.Copy( namePtr );
+            info.iRunAddress = (TUint32) runAddr;  
+            // Append codesegment to array
+            iCodeSeg.Append( info );
+            }
+        imports++;
+        }
+    }
+  
+#endif // __WINSCW__
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetMemoryModel()
+// Acquires memory model system uses.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetMemoryModel(TAny* aMemoryModel,
+                                        TThreadMessage& aMessage)
+    {
+    LOGSTR1( "ATDD DAnalyzeToolChannel::GetMemoryModel()" );
+   
+    // Model buffer.
+    TATMemoryModelBuf model;
+    // Get current model.
+    model().iMemoryModel = (TUint32) Kern::HalFunction( EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL );
+    model().iMemoryModel &= EMemModelTypeMask; // Mask out other stuff.
+    // Write it to client side.
+    TInt error = Kern::ThreadDesWrite( aMessage.Client(),
+                                        aMemoryModel,
+                                        model,
+                                        0);
+    if ( error != KErrNone )
+        {
+        LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+        }
+    return error;
+    }
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetooldevice.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class DAnalyzeToolDevice.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetooldevice.h"
+#include "analyzetoolchannel.h"
+#include "atlog.h"
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::DAnalyzeToolDevice()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolDevice::DAnalyzeToolDevice()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolDevice::DAnalyzeToolDevice()" );
+    // Set version number
+    iVersion = KAnalyzeToolLddVersion();
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::Install()
+// Second stage constructor.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolDevice::Install()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolDevice::Install()" );
+    // Set device name
+    return SetName( &KAnalyzeToolLddName );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::GetCaps()
+// Gets the driver's capabilities.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolDevice::GetCaps( TDes8& /*aDes*/ ) const
+    {
+    LOGSTR1( "ATDD DAnalyzeToolDevice::GetCaps()" );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::Create()
+// Creates the logical channel.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolDevice::Create( DLogicalChannelBase*& aChannel )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolDevice::Create()" );
+
+    // create new channel
+    aChannel = new DAnalyzeToolChannel;
+
+    // check that everything is OK
+    return ( aChannel != NULL ) ? KErrNone : KErrNoMemory;
+    }
+
+// -----------------------------------------------------------------------------
+// DECLARE_STANDARD_LDD
+// Defines the entry point for a standard logical device driver (LDD),
+// and declares the ordinal 1 export function for creating 
+// the LDD factory object
+// -----------------------------------------------------------------------------
+//
+DECLARE_STANDARD_LDD()
+    {
+    LOGSTR1( "ATDD DECLARE_STANDARD_LDD()" );
+    return new DAnalyzeToolDevice;
+    }
+    
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+// None
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetooleventhandler.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class DAnalyzeToolEventHandler.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetooleventhandler.h"
+#include <kernel/kern_priv.h>
+
+// CONSTANTS
+
+// The handler mutex literal
+_LIT( KHandlerMutexName, "AnalyzeToolHandlerMutex" );
+
+// The handle data mutex literal
+_LIT( KDataMutexName, "AnalyzeToolDataMutex" );
+
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::Create()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolEventHandler::Create( DLogicalDevice* aDevice,
+    const TUint aProcessId )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::Create()" );
+    TInt ret( KErrNone );
+    
+    // Store owner process ID
+    iProcessId = aProcessId;
+    LOGSTR2( "ATDD DAnalyzeToolEventHandler::Create > iProcessId %d", 
+            iProcessId );
+    
+    // Open the device
+    ret = aDevice->Open();
+    if ( ret != KErrNone )
+        return ret;
+    iDevice = aDevice;
+
+    // Create mutex for the handler
+    ret = Kern::MutexCreate( iHandlerMutex, KHandlerMutexName, KMutexOrdDebug );
+    if ( ret != KErrNone )
+        return ret;
+    // Create mutex for the data
+    ret = Kern::MutexCreate( iDataMutex, KDataMutexName, KMutexOrdDebug-1 );
+    if ( ret != KErrNone )
+        return ret;
+
+    // Add handler to the handler queue
+    return Add();
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()" );
+    
+    CancelInformLibraryEvent();
+    
+    // Close the data mutex
+    if ( iDataMutex )
+        {
+        iDataMutex->Close( NULL );
+        }
+
+    // Close the handler mutex
+    if ( iHandlerMutex )
+        {
+        iHandlerMutex->Close( NULL );
+        }
+
+    // Close the device mutex
+    if ( iDevice )
+        {
+        iDevice->Close( NULL );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventHandler()
+// Function for receiving kernel events
+// -----------------------------------------------------------------------------
+//
+TUint DAnalyzeToolEventHandler::EventHandler( TKernelEvent aEvent, 
+    TAny* a1, TAny* a2, TAny* aThis )
+    {
+    
+    // Clarify the event type
+    switch ( aEvent)
+        {
+        case EEventRemoveLibrary:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveLibrary" );
+            // Cast the pointer to the handler
+            DAnalyzeToolEventHandler* handler = 
+            ( ( DAnalyzeToolEventHandler* ) aThis );
+            // Create variable for library information
+            TLibraryEventInfo info;
+            // Set as library remove event
+            info.iEventType = TLibraryEventInfo::ELibraryRemoved;
+            // Handle the event
+            handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+            break;
+            }
+        case EEventAddLibrary:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventAddLibrary" );
+            // Cast the pointer to the handler
+            DAnalyzeToolEventHandler* handler = 
+            ( ( DAnalyzeToolEventHandler* ) aThis );
+            // Create variable for library information
+            TLibraryEventInfo info;
+            // Set as library remove event
+            info.iEventType = TLibraryEventInfo::ELibraryAdded;
+            // Handle the event
+            handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+            break;
+            }
+        case EEventHwExc:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventHwExc" );
+            break;
+            }
+        case EEventSwExc:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventSwExc" );
+            break;
+            }
+        case EEventRemoveThread:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveThread" );
+            break;
+            }
+        case EEventKillThread:
+            {
+            LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventKillThread" );
+            
+            // Cast the pointer to the handler
+            DAnalyzeToolEventHandler* handler = 
+                ( ( DAnalyzeToolEventHandler* ) aThis );
+            
+            // Create variable for library information
+            TLibraryEventInfo info;
+            
+            // Set as kill thread event
+            info.iEventType = TLibraryEventInfo::EKillThread;
+            // Handle the event
+            handler->HandleKillThreadEvent( ( DThread* ) a1, info );
+            break;
+            }
+        default:
+            {
+            }
+            break;
+        }  
+    return ERunNext;
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleLibraryEvent()
+// Handles the EEventAddLibrary and EEventRemoveLibrary events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleLibraryEvent( DLibrary* aLib, 
+    DThread* aThread, TLibraryEventInfo& aInfo )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleLibraryEvent()" );
+    
+    // Aqcuire the handler mutex
+    Kern::MutexWait( *iHandlerMutex );
+
+    // Aqcuire the data mutex
+    Kern::MutexWait( *iDataMutex );
+    
+    TBool addInfo( EFalse );
+    
+    // Check the library event type
+    if ( aInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
+        {
+        if ( aThread != NULL )
+            {
+            if ( iProcessId == aThread->iOwningProcess->iId )
+                {
+                LOGSTR1( "ATDD > Process id match" );
+                aInfo.iProcessId = aThread->iOwningProcess->iId;
+                addInfo = ETrue;
+                }
+            }
+        }
+    else if ( aInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
+        {
+        if ( aThread != NULL )
+            {
+            aInfo.iProcessId = aThread->iOwningProcess->iId;
+            }
+        else
+            {
+            aInfo.iProcessId = 0;
+            }
+        addInfo = ETrue;
+        }
+    
+    if ( addInfo )
+        {
+        // Store lib info
+        aLib->AppendName( aInfo.iLibraryName );//lint !e64 !e1514
+        aInfo.iSize = aLib->iCodeSeg->iSize;
+        aInfo.iRunAddress = aLib->iCodeSeg->iRunAddress;
+        // Store library event info to the array
+        iEventArray.Append( aInfo );
+        LOGSTR2( "ATDD > iEventArray.Count() = %d", iEventArray.Count() );
+        
+        // if client has subscribed the event it is queued
+        if ( iClientThread != NULL )
+            {
+            iEventDfc.Enque();
+            }
+        }
+     
+    // Release the data mutex
+    Kern::MutexSignal( *iDataMutex );
+
+    // Release the handler mutex
+    Kern::MutexSignal( *iHandlerMutex );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::InformLibraryEvent()
+// Subscribes library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::InformLibraryEvent( TRequestStatus* aStatus, 
+                                                   TAny* aLibraryInfo,
+                                                   TThreadMessage& aMessage )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::InformLibraryEvent()" );
+
+    // Aqcuire the data mutex
+    Kern::MutexWait( *iDataMutex );  
+    
+    // Check if request from client which is already pending
+    DThread* current = aMessage.Client();
+    
+    LOGSTR2( "ATDD > Current Thread ID = %d", current->iId );
+ 
+    // Ensure that client doesn't subscribe service when there is a pending
+    // subscription
+    if ( NULL != iClientThread )
+        {
+        aMessage.PanicClient( KClientPanic, EPanicRequestPending );
+        }
+    else
+        {
+        // Store the client variable pointers
+        iClientThread         = current;
+        iClientRequestStatus  = aStatus;
+        iClientInfo           = aLibraryInfo;
+        }
+    
+    // Release the data mutex
+    Kern::MutexSignal( *iDataMutex );
+    
+    // Queue the event since now the client has subscribed it
+    iEventDfc.Enque();
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::CancelInformLibraryEvent
+// Cancels subscription of the library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::CancelInformLibraryEvent()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::CancelInformLibraryEvent()" );
+    
+    iEventDfc.Cancel();
+    
+    // Aqcuire the data mutex
+    Kern::MutexWait( *iDataMutex );
+
+    if ( NULL != iClientThread && iEventArray.Count() > 0 )
+        {
+        // Signal the request as complete
+        Kern::RequestComplete( iClientThread, 
+                               iClientRequestStatus, 
+                               KErrCancel );
+        
+        iClientThread         = NULL;
+        iClientRequestStatus  = NULL;
+        iClientInfo           = NULL;
+
+        // Reset the event array
+        iEventArray.Reset();
+        }
+   
+    // Release the data mutex
+    Kern::MutexSignal( *iDataMutex );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleKillThreadEvent()
+// Handles the EEventKillThread events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleKillThreadEvent( DThread* aThread, 
+                                                      TLibraryEventInfo& aInfo )
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleKillThreadEvent()" );
+    
+    // Aqcuire the handler mutex
+    Kern::MutexWait( *iHandlerMutex );
+
+    // Aqcuire the data mutex
+    Kern::MutexWait( *iDataMutex );
+    
+    aInfo.iProcessId = aThread->iOwningProcess->iId;
+    TBool alone( aThread->iOwningProcess->iThreadQ.First()->Alone() );
+    LOGSTR2( "ATDD > Is alone = %d", alone );
+    
+    // Check if this our process and is the only thread item.
+    if ( aInfo.iProcessId == iProcessId && !alone )
+        {
+        if ( aThread )
+            {
+            // Set current Thread id
+            LOGSTR2( "ATDD > Thread ID = %d", aThread->iId );
+            aInfo.iThreadId = aThread->iId;
+            // Append event to array (beginning of the array)
+            iEventArray.Insert( aInfo, 0 );
+            
+            // if client has subscribed the event it is queued
+            if ( iClientThread != NULL )
+                {
+                iEventDfc.Enque();
+                }
+            }
+        }
+    
+    // Release the data mutex
+    Kern::MutexSignal( *iDataMutex );
+
+    // Release the handler mutex
+    Kern::MutexSignal( *iHandlerMutex );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::DoEventComplete()
+// Informs client about the occured event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::DoEventComplete()
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::DoEventComplete()" );
+    
+    // Aqcuire the handler mutex
+    Kern::MutexWait( *iHandlerMutex );
+
+    // Aqcuire the data mutex
+    Kern::MutexWait( *iDataMutex );
+    
+    if ( NULL != iClientThread && iEventArray.Count() > 0 )
+        {
+        TInt ret = Kern::ThreadRawWrite( iClientThread, 
+                                         iClientInfo, 
+                                         &iEventArray[0],
+                                         sizeof( iEventArray[0] ) );
+        
+        LOGSTR2( "ATDD > ThreadRawWrite err = %d", ret );
+        
+        // Signal the request as complete
+        Kern::RequestComplete( iClientThread, 
+                               iClientRequestStatus, 
+                               ret );
+        
+        // Remove first item to array
+        iEventArray.Remove( 0 );
+        
+        // Compresses the array down to a minimum
+        iEventArray.Compress();
+        
+        // Ensure that pointers are set to NULL
+        iClientThread         = NULL;
+        iClientRequestStatus  = NULL;
+        iClientInfo           = NULL;
+        
+        LOGSTR2( "ATDD > iEventArray = %d", iEventArray.Count() );
+        }
+    
+    // Release the data mutex
+    Kern::MutexSignal( *iDataMutex );
+
+    // Release the handler mutex
+    Kern::MutexSignal( *iHandlerMutex );
+    }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventDfc()
+// Static function for DFC events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::EventDfc(TAny* aPtr)
+    {
+    LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventDfc()" ); 
+    ( (DAnalyzeToolEventHandler*) aPtr )->DoEventComplete();
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/rom/analyzetool.iby	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __ANALYZETOOL_IBY__
+#define __ANALYZETOOL_IBY__
+
+// Stub
+data=ZSYSTEM\Install\analyzetool_stub.sis                   \system\install\analyzetool_stub.sis
+
+#endif // __ANALYZETOOL_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/rom/analyzetool_rom.iby	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __ANALYZETOOL_ROM_IBY__
+#define __ANALYZETOOL_ROM_IBY__
+
+
+// Kernel event handler
+device[VARID]=ABI_DIR\BUILD_DIR\atoolkerneleventhandler.ldd     SHARED_LIB_DIR\atoolkerneleventhandler.ldd
+
+// Memory hook
+file=ABI_DIR\BUILD_DIR\atoolmemoryhook.dll                      SHARED_LIB_DIR\atoolmemoryhook.dll
+
+// Cleaner
+file=ABI_DIR\BUILD_DIR\atoolcleaner.dll           	            SHARED_LIB_DIR\atoolcleaner.dll
+
+// Storage server
+file=ABI_DIR\BUILD_DIR\atoolstorageserver.exe                   PROGRAMS_DIR\atoolstorageserver.exe
+file=ABI_DIR\BUILD_DIR\atoolstorageserverclnt.dll               SHARED_LIB_DIR\atoolstorageserverclnt.dll
+
+
+#endif // __ANALYZETOOL_ROM_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/AnalyzeTool.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,42 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeTool"},(0x20012432),1,9,1,TYPE=SA, RU
+
+;Localised Vendor name
+%{"Nokia Corporation"}
+
+;Unique Vendor name
+:"Nokia Corporation"
+
+;Supports Series 60 v 3.1
+[0x102032BE], 0, 0, 0, {"Series60ProductID"}
+
+;Supports S60 release 5.0
+[0x1028315F], 0, 0, 0, {"Series60ProductID"}
+
+"\epoc32\release\armv5\urel\atoolkerneleventhandler.ldd"            -"!:\sys\bin\atoolkerneleventhandler.ldd"
+"\epoc32\release\armv5\urel\atoolmemoryhook.dll"                    -"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\urel\atoolstorageserver.exe"                 -"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\urel\atoolstorageserverclnt.dll"             -"!:\sys\bin\atoolstorageserverclnt.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll"                 		-"!:\sys\bin\atoolcleaner.dll"
+
+; Install console application
+"\epoc32\release\armv5\urel\atool.exe"-"!:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/AnalyzeTool_udeb.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,42 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeTool"},(0x20012432),1,9,1,TYPE=SA, RU
+
+;Localised Vendor name
+%{"Nokia Corporation"}
+
+;Unique Vendor name
+:"Nokia Corporation"
+
+;Supports Series 60 v 3.1
+[0x102032BE], 0, 0, 0, {"Series60ProductID"}
+
+;Supports S60 release 5.0
+[0x1028315F], 0, 0, 0, {"Series60ProductID"}
+
+"\epoc32\release\armv5\udeb\atoolkerneleventhandler.ldd"            -"!:\sys\bin\atoolkerneleventhandler.ldd"
+"\epoc32\release\armv5\udeb\atoolmemoryhook.dll"                    -"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\udeb\atoolstorageserver.exe"                 -"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\udeb\atoolstorageserverclnt.dll"             -"!:\sys\bin\atoolstorageserverclnt.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll"                 		-"!:\sys\bin\atoolcleaner.dll"
+
+; Install console application
+"\epoc32\release\armv5\udeb\atool.exe"-"!:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/analyzeTool_stub.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Languages
+&EN
+
+;Header
+#{"AnalyzeTool"}, (0x20012432), 1,9,1
+
+; Non-localised vendor name
+:"Nokia Corporation"
+
+; Localised vendor names
+%{"Nokia Corporation"}
+
+; AnalyzeTool binaries
+""-"z:\sys\bin\atoolkerneleventhandler.ldd"
+""-"z:\sys\bin\atoolmemoryhook.dll"
+""-"z:\sys\bin\atoolstorageserver.exe"
+""-"z:\sys\bin\atoolstorageserverclnt.dll"
+""-"z:\sys\bin\atoolcleaner.dll"
+
+""-"z:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/group/atoolstaticlib.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for AToolStaticLib.
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET        atoolstaticlib.lib
+TARGETTYPE    lib
+UID           0x1000008d 0x20018421//0x02DF7F96
+CAPABILITY    ALL -TCB
+
+SMPSAFE
+
+USERINCLUDE   ../../inc
+SOURCEPATH    ../src
+SOURCE        atoolstaticlib.cpp
+
+OS_LAYER_SYSTEMINCLUDE
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../../dynamicmemoryhook/inc/customuser.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/customuser.h)
+
+PRJ_MMPFILES
+atoolstaticlib.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/src/atoolstaticlib.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The file contains declarations of extern methods and definitions
+*                of overloaded User methods.
+*
+*/
+
+
+#include <analyzetool/customuser.h>
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// GetInt()
+// Extern function for acquiring all integer values
+// -----------------------------------------------------------------------------
+// 
+GLREF_C TInt GetInt( const TUint8 aType );
+
+// -----------------------------------------------------------------------------
+// GetString()
+// Extern function for acquiring all string values
+// -----------------------------------------------------------------------------
+//
+GLREF_C TPtrC GetString( const TUint8 aType );
+
+// -----------------------------------------------------------------------------
+// User::Exit()
+// Overloaded User::Exit() function
+// -----------------------------------------------------------------------------
+// 
+void User::Exit( TInt aReason )
+    {   
+    LOGSTR2( "ATMH User::Exit %i", aReason ); 
+    CustomUser::Exit( aReason );
+    }
+
+// -----------------------------------------------------------------------------
+// User::Panic()
+// Overloaded User::Panic() function
+// -----------------------------------------------------------------------------
+//
+void User::Panic( const TDesC& aCategory, TInt aReason )
+    {
+    LOGSTR3( "ATMH User::Panic() %S %i", &aCategory, aReason );
+    CustomUser::Panic( aCategory, aReason );
+    }
+ 
+// -----------------------------------------------------------------------------
+// User::SetCritical()
+// Overloaded User::SetCritical() function which returns
+// KErrNone, if successful; KErrArgument, if EAllThreadsCritical is 
+// passed - this is a state associated with a process, and you use 
+// User::SetProcessCritical() to set it.
+// -----------------------------------------------------------------------------
+// 
+TInt User::SetCritical( TCritical aCritical )
+    {
+    LOGSTR2( "ATMH User::SetCritical() %i", aCritical );
+    return CustomUser::SetCritical( aCritical );
+    }
+
+// -----------------------------------------------------------------------------
+// User::SetProcessCritical()
+// Overloaded User::SetProcessCritical() function
+// KErrNone, if successful; KErrArgument, if either EProcessCritical or 
+// EProcessPermanent is passed - these are states associated with a 
+// thread, and you use User::SetCritical() to set them.
+// -----------------------------------------------------------------------------
+// 
+TInt User::SetProcessCritical( TCritical aCritical )
+    {
+    LOGSTR2( "ATMH User::SetProcessCritical() %i", aCritical );
+    return CustomUser::SetProcessCritical( aCritical );
+    }
+    
+// -----------------------------------------------------------------------------
+// UserHeap::SetupThreadHeap()
+// Overloaded UserHeap::SetupThreadHeap function
+// -----------------------------------------------------------------------------
+//  
+TInt UserHeap::SetupThreadHeap( TBool aNotFirst, 
+                                SStdEpocThreadCreateInfo& aInfo )
+    {
+    LOGSTR1( "ATMH UserHeap::SetupThreadHeap()" );
+        
+    // Check validity of parameters 
+    TInt logOption( GetInt( (TUint8) CustomUser::ELogOption ) );
+    if ( logOption < 0 )
+        logOption = KATDefaultLogOption;
+    
+    TInt debug( GetInt( (TUint8) CustomUser::EDebug ) );
+    if ( debug < 0 )
+        debug = KATDefaultDebug;
+    
+    TInt allocCallStack( GetInt( (TUint8) CustomUser::EAllocCallStackSize ) );
+    if ( allocCallStack < 0 )
+        allocCallStack = KATDefaultAllocCallStackSize;
+    
+    TInt freeCallStack( GetInt( (TUint8) CustomUser::EFreeCallStackSize ) );
+    if ( freeCallStack < 0 )
+        freeCallStack = KATDefaultFreeCallStackSize;
+        
+    return CustomUser::SetupThreadHeap( aNotFirst, aInfo, 
+            GetString( (TUint8) CustomUser::ELogFileName ),
+            (TUint32) logOption, (TUint32) debug,
+            GetString( (TUint8) CustomUser::EVersion ),
+            (TUint32) allocCallStack, (TUint32) freeCallStack,
+            KATArgumentList );
+    }
+  
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/bwins/atoolstorageserverclntu.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,26 @@
+EXPORTS
+	??0RATStorageServer@@QAE@XZ @ 1 NONAME ; RATStorageServer::RATStorageServer(void)
+	?CancelLogging@RATStorageServer@@QAEHI@Z @ 2 NONAME ; int RATStorageServer::CancelLogging(unsigned int)
+	?CheckMemoryAddress@RATStorageServer@@QBEHK@Z @ 3 NONAME ; int RATStorageServer::CheckMemoryAddress(unsigned long) const
+	?Close@RATStorageServer@@QAEXXZ @ 4 NONAME ; void RATStorageServer::Close(void)
+	?Connect@RATStorageServer@@QAEHXZ @ 5 NONAME ; int RATStorageServer::Connect(void)
+	?GetCurrentAllocsL@RATStorageServer@@QAEHIAAK0@Z @ 6 NONAME ; int RATStorageServer::GetCurrentAllocsL(unsigned int, unsigned long &, unsigned long &)
+	?GetLoadedDllsL@RATStorageServer@@QAEHIAAV?$RArray@V?$TBuf8@$0DM@@@@@@Z @ 7 NONAME ; int RATStorageServer::GetLoadedDllsL(unsigned int, class RArray<class TBuf8<60> > &)
+	?GetLoggingFileL@RATStorageServer@@QAEHIAAVTDes8@@@Z @ 8 NONAME ; int RATStorageServer::GetLoggingFileL(unsigned int, class TDes8 &)
+	?GetLoggingModeL@RATStorageServer@@QAEHIAAW4TATLogOption@@@Z @ 9 NONAME ; int RATStorageServer::GetLoggingModeL(unsigned int, enum TATLogOption &)
+	?GetMaxAllocsL@RATStorageServer@@QAEHIAAK0@Z @ 10 NONAME ; int RATStorageServer::GetMaxAllocsL(unsigned int, unsigned long &, unsigned long &)
+	?GetProcessesL@RATStorageServer@@QAEHAAV?$RArray@VTATProcessInfo@@@@@Z @ 11 NONAME ; int RATStorageServer::GetProcessesL(class RArray<class TATProcessInfo> &)
+	?GetUdebL@RATStorageServer@@QAEHIAAK@Z @ 12 NONAME ; int RATStorageServer::GetUdebL(unsigned int, unsigned long &)
+	?IsMemoryAdded@RATStorageServer@@QAEHK@Z @ 13 NONAME ; int RATStorageServer::IsMemoryAdded(unsigned long)
+	?LogDllLoaded@RATStorageServer@@QAEHABVTDesC8@@KK@Z @ 14 NONAME ; int RATStorageServer::LogDllLoaded(class TDesC8 const &, unsigned long, unsigned long)
+	?LogDllUnloaded@RATStorageServer@@QAEHABVTDesC8@@KK@Z @ 15 NONAME ; int RATStorageServer::LogDllUnloaded(class TDesC8 const &, unsigned long, unsigned long)
+	?LogMemoryAllocated@RATStorageServer@@QAEHKAAV?$TFixedArray@K$0BAA@@@H@Z @ 16 NONAME ; int RATStorageServer::LogMemoryAllocated(unsigned long, class TFixedArray<unsigned long, 256> &, int)
+	?LogMemoryFreed@RATStorageServer@@QAEHKAAV?$TFixedArray@K$0BAA@@@@Z @ 17 NONAME ; int RATStorageServer::LogMemoryFreed(unsigned long, class TFixedArray<unsigned long, 256> &)
+	?LogProcessEnded@RATStorageServer@@QAEHII@Z @ 18 NONAME ; int RATStorageServer::LogProcessEnded(unsigned int, unsigned int)
+	?LogProcessStarted@RATStorageServer@@QAEHABVTDesC16@@ABVTDesC8@@IKK@Z @ 19 NONAME ; int RATStorageServer::LogProcessStarted(class TDesC16 const &, class TDesC8 const &, unsigned int, unsigned long, unsigned long)
+	?StartSubTest@RATStorageServer@@QAEHABVTDesC8@@@Z @ 20 NONAME ; int RATStorageServer::StartSubTest(class TDesC8 const &)
+	?StartSubTest@RATStorageServer@@QAEHIABVTDesC8@@H@Z @ 21 NONAME ; int RATStorageServer::StartSubTest(unsigned int, class TDesC8 const &, int)
+	?StopSubTest@RATStorageServer@@QAEHABVTDesC8@@@Z @ 22 NONAME ; int RATStorageServer::StopSubTest(class TDesC8 const &)
+	?StopSubTest@RATStorageServer@@QAEHIABVTDesC8@@H@Z @ 23 NONAME ; int RATStorageServer::StopSubTest(unsigned int, class TDesC8 const &, int)
+	?Version@RATStorageServer@@QBE?AVTVersion@@XZ @ 24 NONAME ; class TVersion RATStorageServer::Version(void) const
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/eabi/atoolstorageserverclntu.def	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,27 @@
+EXPORTS
+	_ZN16RATStorageServer11StopSubTestERK6TDesC8 @ 1 NONAME
+	_ZN16RATStorageServer11StopSubTestEjRK6TDesC8i @ 2 NONAME
+	_ZN16RATStorageServer12LogDllLoadedERK6TDesC8mm @ 3 NONAME
+	_ZN16RATStorageServer12StartSubTestERK6TDesC8 @ 4 NONAME
+	_ZN16RATStorageServer12StartSubTestEjRK6TDesC8i @ 5 NONAME
+	_ZN16RATStorageServer13CancelLoggingEj @ 6 NONAME
+	_ZN16RATStorageServer13GetMaxAllocsLEjRmS0_ @ 7 NONAME
+	_ZN16RATStorageServer13GetProcessesLER6RArrayI14TATProcessInfoE @ 8 NONAME
+	_ZN16RATStorageServer13IsMemoryAddedEm @ 9 NONAME
+	_ZN16RATStorageServer14GetLoadedDllsLEjR6RArrayI5TBuf8ILi60EEE @ 10 NONAME
+	_ZN16RATStorageServer14LogDllUnloadedERK6TDesC8mm @ 11 NONAME
+	_ZN16RATStorageServer14LogMemoryFreedEmR11TFixedArrayImLi256EE @ 12 NONAME
+	_ZN16RATStorageServer15GetLoggingFileLEjR5TDes8 @ 13 NONAME
+	_ZN16RATStorageServer15GetLoggingModeLEjR12TATLogOption @ 14 NONAME
+	_ZN16RATStorageServer15LogProcessEndedEjj @ 15 NONAME
+	_ZN16RATStorageServer17GetCurrentAllocsLEjRmS0_ @ 16 NONAME
+	_ZN16RATStorageServer17LogProcessStartedERK7TDesC16RK6TDesC8jmm @ 17 NONAME
+	_ZN16RATStorageServer18LogMemoryAllocatedEmR11TFixedArrayImLi256EEi @ 18 NONAME
+	_ZN16RATStorageServer5CloseEv @ 19 NONAME
+	_ZN16RATStorageServer7ConnectEv @ 20 NONAME
+	_ZN16RATStorageServer8GetUdebLEjRm @ 21 NONAME
+	_ZN16RATStorageServerC1Ev @ 22 NONAME
+	_ZN16RATStorageServerC2Ev @ 23 NONAME
+	_ZNK16RATStorageServer18CheckMemoryAddressEm @ 24 NONAME
+	_ZNK16RATStorageServer7VersionEv @ 25 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/group/atoolstorageserverclnt.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for the client side of AToolStorageServer
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET            atoolstorageserverclnt.dll
+TARGETTYPE        dll
+UID               0x1000008d 0x20012431
+CAPABILITY        ALL -TCB
+
+SMPSAFE
+
+SOURCEPATH        ../src
+
+SOURCE            atstorageserverclnt.cpp
+
+USERINCLUDE       ../inc
+USERINCLUDE       ../../inc
+USERINCLUDE       ../../server/inc
+USERINCLUDE       ../../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY           euser.lib
+LIBRARY           flogger.lib
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/inc/atstorageserverclnt.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,371 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the client side handle class RATStorageServer
+*
+*/
+
+
+
+#ifndef ATSTORAGESERVERCLNT_H
+#define ATSTORAGESERVERCLNT_H
+
+
+// INCLUDES
+#include    <e32base.h>
+#include    <analyzetool/atcommon.h>
+
+
+// CONSTANTS
+// Constants for the lowest version of the server with which the
+// client is compatible
+const TUint KLowestVersionNumberMaj = 0;
+const TUint KLowestVersionNumberMin = 1;
+const TUint KLowestVersionNumberBld = 1;
+
+
+// FORWARD DECLARATIONS
+class TATProcessInfo;
+
+
+// CLASS DECLARATION
+
+/**
+*  The main class of the Storage Server client. Objects of this class work as handles
+*  to the Storage Server's server side. Use Connect() to connect a client to the server,
+*  and Close() to end an opened session.
+*/
+class RATStorageServer: public RSessionBase
+    {
+    public:  // Constructor and destructor
+       
+        /**
+        * C++ default constructor.
+        */
+        IMPORT_C RATStorageServer();
+   
+    public: // New functions
+        
+        /**
+        * Creates a new process for the server, if that doesn't already exist, and
+        * connects a client to the server by creating a new session with it, and
+        * initializes the client for use. To end the server session, use Close().
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt Connect();
+    
+        /**
+        * Closes a handle to a server session. This has also the effect of destroying
+        * the associated server side session object. Also, the server itself and the
+        * process where it is running are destroyed, if there are no other open sessions
+        * left.
+        */
+        IMPORT_C void Close();
+    
+        /**
+        * This method is called to initialize the server for logging and it is to be
+        * called as the first method after connecting to the server. The method informs
+        * the server that a new process has been started. The method cannot be called
+        * again without a call to the LogProcessEnded() first. Otherwise a STSEClient: 3
+        * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+        * to the server.
+        * @param aFileName The name of the logging file used when the system is logging
+        *   to a file (the logging mode is EATLogToFile). The length of aFileName must not be
+        *   greater than KMaxFileName, otherwise the method raises a STSEClient: 2 panic.
+        * @param aProcessName The name of the new process started. The length of this
+        *   descriptor must not be greater than KMaxProcessName, otherwise the method
+        *   raises a STSEClient: 2 panic.
+        * @param aProcessId The ID of the process started.
+        * @param aLogOption An option telling the logging mode.
+        * @param aIsDebug Determines whether a binary is UDEB or UREL
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogProcessStarted( const TDesC& aFileName,
+                                         const TDesC8& aProcessName,
+                                         TUint aProcessId,
+                                         TUint32 aLogOption, TUint32 aIsDebug );
+        
+        /**
+        * Asks the server to log that a new DLL has been loaded. Note, the method
+        * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3
+        * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+        * to the server.
+        * @param aDllName The name of the new DLL loaded. The length of this descriptor
+        *   must not be greater than KMaxLibraryName, otherwise the method raises a
+        *   STSEClient: 2 panic.
+        * @param aStartAddress The start address of the DLL loaded.
+        * @param aEndAddress The end address of the DLL loaded.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogDllLoaded( const TDesC8& aDllName, TUint32 aStartAddress,
+                                              TUint32 aEndAddress );
+        
+        /**
+        * Asks the server to log that a new DLL has been unloaded. Note, the method
+        * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3
+        * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+        * to the server. If the method is called with illegal parameter values, a
+        * STSEClient: 2 panic is raised.
+        * @param aDllName The name of the DLL to be unloaded. The length of this
+        *   descriptor must not be greater than KMaxLibraryName, otherwise the method
+        *   raises a STSEClient: 2 panic.
+        * @param aStartAddress The start address of the DLL to be unloaded.
+        * @param aEndAddress The end address of the DLL to be unloaded.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogDllUnloaded( const TDesC8& aDllName, TUint32 aStartAddress,
+                                               TUint32 aEndAddress );
+        
+        /**
+        * Informs the server that a memory allocation has occured at the specified
+        * address. Sends also the current call stack to the server. Note, the method
+        * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3 
+        * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+        * to the server.
+        * @param aMemAddress The memory location where memory has been allocated.
+        * @param aCallstack An array including the current call stack.
+        * @param aSize The size of the newly allocated memory chunk.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogMemoryAllocated( TUint32 aMemAddress,
+                                          TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+                                          TInt aSize );
+                
+        /**
+        * Informs the server that memory was released at the specified address. Note,
+        * the method LogProcessStarted() has to be previously called. Otherwise a 
+        * STSEClient: 3 panic is raised. A KERN-EXEC: 0 panic is raised if the client is
+        * not connected to the server.
+        * @param aMemAddress The memory location where memory has been deallocated.
+        * @param aFreeCallstack An array including the current call stack.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogMemoryFreed( TUint32 aMemAddress, 
+                                      TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack );
+        
+        /**
+        * Tells the server that the process under test has been ended. Prints information
+        * related to process ending, such as possibly occured memory leaks (when file
+        * logging mode used), and possibly occured handle leaks. Note, the method 
+        * LogProcessStarted() has to be previously called. Otherwise a STSEClient:
+        * 3 panic is raised. A call to this method also closes the file opened for
+        * the current process. So, no further logging is possible without a new call
+        * to the method LogProcessStarted(). A KERN-EXEC: 0 panic is raised if the client
+        * is not connected to the server.
+        * @param aProcessId The ID number of the process ended.
+        * @param aHandleLeaks Amount of handle leaks.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system-wide error codes.
+        */
+        IMPORT_C TInt LogProcessEnded( TUint aProcessId, 
+                                       TUint aHandleLeaks );
+           
+        /**
+        * Gives the lowest version number of the server needed for this client.
+        * @return The lowest version of the server needed for this client.
+        */
+        IMPORT_C TVersion Version() const;  
+
+        /**
+        * Checks if the current process has allocated, but not freed, the given memory
+        * address. Note, the method LogProcessStarted() has to be previously called.
+        * Otherwise a STSEClient: 3 panic is raised. A KERN-EXEC: 0 panic is raised if
+        * the client is not connected to the server.
+        * @param aMemAddress The memory location to check.
+        * @return When the system is logging into a file: the index of a found 
+        *   memory address or KErrNotFound, if a matching memory address cannot
+        *   be found. When the system is not logging into a file: always KErrNone.
+        */
+        IMPORT_C TInt CheckMemoryAddress( TUint32 aMemAddress ) const;
+        
+        /**
+        * Gets all the processes with currently open logging sessions.
+        * @param aProcesses A reference to a process array to be filled by the server.
+        * @return KErrNone, if successful; otherwise one of the other
+        *   system wide error codes.
+        */
+        IMPORT_C TInt GetProcessesL( RArray<TATProcessInfo>& aProcesses );
+        
+        /**
+        * Gets all the DLLs loaded by the given process.
+        * @param aProcessId The ID of the process whose DLLs will be fetched.
+        * @param aDlls An array that after this function call includes names of
+        *   the given process's dlls
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetLoadedDllsL( TUint aProcessId,
+                                      RArray< TBuf8<KMaxLibraryName> >& aDlls );
+                
+        /**
+        * Gets the logging mode of the given process.
+        * @param aProcessId The ID of the process whose logging mode is being asked.
+        * @param aLoggingMode An enumeration telling the logging mode after a call
+        *   to this function.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetLoggingModeL( TUint aProcessId, TATLogOption& aLoggingMode );
+        
+        /**
+        * Starts a sub test for the given process.
+        * @param aProcessId The ID of the process for which to start a sub test.
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic.
+        * @param aHandleCount The current handle count of a particular process.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; KErrNotSupported, if the requested process does not have a logging
+        *   session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+        *   other system wide error codes.
+        */
+        IMPORT_C TInt StartSubTest( TUint aProcessId, const TDesC8& aSubtestId, TInt aHandleCount = 0 );
+
+        /**
+        * Stops a sub test for the given process.
+        * @param aProcessId The ID of the process for which to stop a sub test.
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic.
+        * @param aHandleCount The current handle count of a particular process.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; KErrNotSupported, if the requested process does not have a logging
+        *   session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+        *   other system wide error codes.
+        */
+        IMPORT_C TInt StopSubTest( TUint aProcessId, const TDesC8& aSubtestId, TInt aHandleCount = 0 );
+        
+        /**
+        * Gets the number and total size of the memory chunks currently allocated by the
+        * requested process. 
+        * @param aProcessId The ID of the process whose information is requested.
+        * @param aNumber On return contains the number of memory chunks currenlty
+        *   allocated by the requested process.
+        * @param aSize On return contains the amount of memory currently allocated
+        *   by the requested process.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetCurrentAllocsL( TUint aProcessId, TUint32& aNumber, TUint32& aSize );
+        
+        /**
+        * Gets the maximum number and total size of the memory chunks allocated by the
+        * requested process. 
+        * @param aProcessId The ID of the process whose information is requested.
+        * @param aNumber On return contains the maximum number of memory chunks
+        *   allocated by the requested process during the test run.
+        * @param aSize On return contains the maximum amount of memory allocated
+        *   by the requested process during the test run.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetMaxAllocsL( TUint aProcessId, TUint32& aNumber, TUint32& aSize );
+        
+        /**
+        * Starts a sub test for the calling process.
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic.
+        * @return KErrNone, if successful; KErrNotSupported, if the calling process
+        *   does not have a logging session ongoing or its logging mode is not
+        *   EATLogToTrace; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt StartSubTest( const TDesC8& aSubtestId );
+
+        /**
+        * Stops a sub test for the calling process
+        * @param aSubtestId The name identifying this particular sub test. The length
+        *   of this descriptor must not be greater than KATMaxSubtestIdLength, or
+        *   otherwise the method raises a STSEClient: 2 panic.
+        * @return KErrNone, if successful; KErrNotSupported, if the calling process
+        *   does not have a logging session ongoing or its logging mode is not
+        *   EATLogToTrace; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt StopSubTest( const TDesC8& aSubtestId );
+        
+        /**
+        * Cancels logging for the requested process. After logging of a given process
+        * has been cancelled, the session associated with that process will not be
+        * usable anymore. If a process wants to start logging again, it needs to close
+        * the handle and open it again in order to create a new session. Until then, most
+        * of the client's methods will return KErrCancel.
+        * @param aProcessId The process ID of the process whose logging is requested to
+        *   be cancelled.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt CancelLogging( TUint aProcessId );
+
+        /**
+        * Gets the number and total size of the memory chunks currently allocated by the
+        * requested process. 
+        * @param aProcessId The ID of the process whose information is requested.
+        * @param aIsUdeb On return contains an value greater than KErrNone if
+        *   mode is UDEB. Else the mode is UREL
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetUdebL( TUint aProcessId, TUint32& aIsUdeb );
+
+        /**
+        * Gets the number and total size of the memory chunks currently allocated by the
+        * requested process. 
+        * @param aProcessId The ID of the process whose information is requested.
+        * @param aFileName On return contains logging filename for the process.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        IMPORT_C TInt GetLoggingFileL( TUint aProcessId, TDes8& aFileName );
+     
+        /**
+		* Check a memory allocation (memory address) from an internal array.
+		* @param aMemAddress The memory address to be check
+		* @return KErrNone, if memory address found in array; 
+		* 	KErrNotFound, if the requested memory address was not found.
+		*/
+        IMPORT_C TInt IsMemoryAdded( TUint32 aMemAddress );
+               
+    protected: // New functions
+    
+        /**
+        * Creates a new process for the server, if it does not already exist.
+        * @return KErrNone, if successful; otherwise one of the other
+        * system-wide error codes. 
+        */
+        TInt CreateProcess();
+        
+    private: // Internal functions
+    
+        /**
+        * Creates two buffers: one for storing call stack memory addresses and one for
+        * handle leaks. Internally used by this class. May leave, if there is 
+        * insufficient memory.
+        */
+        void ConstructBuffersL();
+        
+    private: // Data
+    
+        /** A pointer to a buffer of call stack's memory addresses */
+        CBufFlat* iStackBuf;
+    };
+
+#endif      // ATSTORAGESERVERCLNT_H   
+
+            
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/src/atstorageserverclnt.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,930 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the client side handle class RATStorageServer
+*
+*/
+
+
+
+// INCLUDE FILES
+#include    "atstorageserverclnt.h"
+#include    "atstorageserver.h"
+#include    "atlog.h"
+#include    "atstorageservercommon.h"
+
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::RATStorageServer
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RATStorageServer::RATStorageServer() :
+    RSessionBase(), iStackBuf( NULL )
+    {
+    LOGSTR1( "STSE RATStorageServer::RATStorageServer()" );
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::Connect
+// A function for connecting to the server
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::Connect()
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::Connect()" );
+ 
+    TInt errorCode( KErrNone );
+    errorCode = CreateProcess();
+    
+    // If process's creation failed, return the error code
+    if ( errorCode != KErrNone )
+        {
+        return errorCode;
+        }
+        
+    // Otherwise create a new session    
+    errorCode = CreateSession( KStorageServerName, Version() );
+    
+    // If creation of a new session failed, return the error code
+    if ( errorCode != KErrNone )
+        {
+        return errorCode;
+        }
+    
+    // Construct a buffer for call stack's memory addresses. If the function leaves,
+    // the leave code is put in "errorCode". 
+    TRAP( errorCode, ConstructBuffersL() ); 
+    
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::Close
+// Destroys all memory reserved by this class, and calls RSessionBase::Close()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void RATStorageServer::Close()
+    {
+    LOGSTR1( "STSE void RATStorageServer::Close()" );
+    
+    // Delete iStackBuf
+    delete iStackBuf;
+    iStackBuf = NULL;
+    
+    // Call the base class' Close()
+    RSessionBase::Close(); 
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogProcessStarted
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogProcessStarted( const TDesC& aFileName,
+                                                   const TDesC8& aProcessName,
+                                                   TUint aProcessId,
+                                                   TUint32 aLogOption, TUint32 aIsDebug )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogProcessStarted()" );
+    
+    // Panic always if aFileName or aProcessName are longer than allowed.
+    __ASSERT_ALWAYS( aFileName.Length() <= KMaxFileName &&
+                     aProcessName.Length() <= KMaxProcessName,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    // Panic (in debug builds) if aProcessId is KNullProcessId
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+    // This information is optional -> ignoring error
+    // Must be before EProcessStarted in order to append udeb/urel
+    // information to LogProcessStarted
+    TIpcArgs ipcArgs2( aIsDebug );
+    SendReceive( CATStorageServer::EProcessUdeb, ipcArgs2 );
+    
+    TIpcArgs ipcArgs( &aFileName, &aProcessName, aProcessId, aLogOption );
+    TInt error( 0 );
+    
+    error = SendReceive( CATStorageServer::EProcessStarted, ipcArgs );
+
+    // Return, if error is not KErrNone.
+    if ( error != KErrNone )
+        {
+        return error;
+        }
+    
+    return KErrNone;
+    }
+       
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogDllLoaded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogDllLoaded( const TDesC8& aDllName,
+                                              TUint32 aStartAddress,
+                                              TUint32 aEndAddress )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogDllLoaded()" );
+    
+    // Panic always if aDllName is longer than allowed.
+    __ASSERT_ALWAYS( aDllName.Length() <= KMaxLibraryName,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    // Panic (in debug builds) if aStartAddress is greater than aEndAddress
+    __ASSERT_DEBUG( aStartAddress <= aEndAddress,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TIpcArgs ipcArgs( &aDllName, aStartAddress, aEndAddress );
+    
+    return SendReceive( CATStorageServer::EDllLoaded, ipcArgs );
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogDllUnloaded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogDllUnloaded( const TDesC8& aDllName,
+                                                TUint32 aStartAddress,
+                                                TUint32 aEndAddress )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogDllUnloaded()" );
+    
+    // Panic always if aDllName is longer than allowed.
+    __ASSERT_ALWAYS( aDllName.Length() <= KMaxLibraryName,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    // Panic (in debug builds) if aStartAddress is greater than aEndAddress
+    __ASSERT_DEBUG( aStartAddress <= aEndAddress,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+      
+    TIpcArgs ipcArgs( &aDllName, aStartAddress, aEndAddress );
+    
+    return SendReceive( CATStorageServer::EDllUnloaded, ipcArgs );
+    }    
+        
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogMemoryAllocated
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogMemoryAllocated( TUint32 aMemAddress,
+                                                    TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+                                                    TInt aSize )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogMemoryAllocated()" );
+    
+    TInt count=0;
+    // The number of memory addresses in aCallstack
+    for ( TInt i = 0; i < KATMaxCallstackLength; i++ )
+        {
+        if( aCallstack[i] == 0 )
+            {
+            break;
+            }
+        count++;
+        }
+    
+    LOGSTR2( "STSE The number of memory addresses in the current call stack: %d", count );
+    
+    // The maximum number of call stack's memory addresses this server can handle
+    // is KMaxCallstackLength
+    if ( count > KATMaxCallstackLength )
+        {
+        count = KATMaxCallstackLength;
+        }
+        
+    // Panic (in debug builds) if the parameters are faulty
+    __ASSERT_DEBUG( aMemAddress != 0 && count >= 0 && aSize >= 0,
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+          
+    // Buffer position
+    TInt pos = 0;  
+    TUint32 callStackAddr;
+                 
+    // Write the number of memory addresses of aCallstack (one word) into
+    // the beginning of the call stack buffer
+    iStackBuf->Write( pos, &count, KWordSize );
+    
+    // Increase the position by one word
+    pos += KWordSize; 
+      
+    // Write all the memory addresses of aCallStack into the buffer 
+    for ( TInt i = 0; i < count; i++ )
+        {
+        callStackAddr = aCallstack[i];
+        
+        // Write the current memory address (the length of an address is one word)
+        iStackBuf->Write( pos, &callStackAddr, KWordSize ); 
+        
+        // Move the pos variable one word (4 bytes) onwards.
+        pos += KWordSize;        
+        }  
+    
+    TPtr8 bufPtr( iStackBuf->Ptr(0) );       
+     
+    TIpcArgs ipcArgs( aMemAddress, &bufPtr, aSize );
+     
+    return SendReceive( CATStorageServer::EMemoryAllocated, ipcArgs );  
+    }
+        
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogMemoryFreed
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogMemoryFreed( TUint32 aMemAddress,
+        TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogMemoryFreed()" );
+    
+    TInt count=0;
+    // The number of memory addresses in aFreeCallstack
+    for ( TInt i = 0; i < KATMaxCallstackLength; i++ )
+        {
+        if( aFreeCallstack[i] == 0 )
+            {
+            break;
+            }
+        count++;
+        }
+    LOGSTR3( "STSE > aFreeCallstack.Count() ( %i ), address( %x )", 
+    		count, aMemAddress );
+    
+    // The maximum number of call stack's memory addresses this server can handle
+	// is KMaxCallstackLength
+	if ( count > KATMaxFreeCallstackLength )
+		{
+		count = KATMaxFreeCallstackLength;
+		}
+		  
+	// Buffer position
+	TInt pos = 0;	
+	TUint32 callStackAddr;
+				 
+	// Write the number of memory addresses of aFreeCallstack (one word) into
+	// the beginning of the call stack buffer
+	iStackBuf->Write( pos, &count, KWordSize );
+	
+	// Increase the position by one word
+	pos += KWordSize; 
+	  
+	// Write all the memory addresses of aFreeCallstack into the buffer 
+	for ( TInt i = 0; i < count; i++ )
+		{
+		callStackAddr = aFreeCallstack[i];
+		
+		// Write the current memory address (the length of an address is one word)
+		iStackBuf->Write( pos, &callStackAddr, KWordSize ); 
+		
+		// Move the pos variable one word (4 bytes) onwards.
+		pos += KWordSize;        
+		}  
+	
+	TPtr8 bufPtr( iStackBuf->Ptr( 0 ) );	 
+	TIpcArgs ipcArgs( aMemAddress, &bufPtr );
+    	
+    return SendReceive( CATStorageServer::EMemoryFreed, ipcArgs );
+    }        
+        
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogProcessEnded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogProcessEnded( TUint aProcessId,
+                                                 TUint aHandleLeaks )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::LogProcessEnded()" );
+    
+    // Panic (in debug builds) if the parameters are faulty
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TIpcArgs ipcArgs( aProcessId, aHandleLeaks );
+    
+    return SendReceive( CATStorageServer::EProcessEnded, ipcArgs );
+    }
+
+//-----------------------------------------------------------------------------
+// RATStorageServer::Version()
+// Returns the version number.
+//-----------------------------------------------------------------------------
+//
+EXPORT_C TVersion RATStorageServer::Version() const
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::Version()" );
+    
+    return TVersion(KLowestVersionNumberMaj, KLowestVersionNumberMin,
+                                                KLowestVersionNumberBld);
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CheckMemoryAddress
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::CheckMemoryAddress( TUint32 aMemAddress ) const
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::CheckMemoryAddress()" );
+    
+    // Panic (in debug builds) if the parameters are faulty
+    __ASSERT_DEBUG( aMemAddress != 0, 
+            StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TIpcArgs ipcArgs( aMemAddress );
+    
+    return SendReceive( CATStorageServer::EMemoryCheck, ipcArgs ); 
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetProcessesL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetProcessesL( RArray<TATProcessInfo>& aProcesses )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetProcessesL()" );
+    
+    TInt error( KErrNone );
+    TInt sizeOfProcessInfo = sizeof( TATProcessInfo );
+    
+    // Reset the sent array
+    aProcesses.Reset();
+    
+    // Calculate the length of the buffer to be constructed for processes.
+    // One word will be reserved for the length of the array.
+    TInt bufferLength = KWordSize + KATMaxProcesses * sizeOfProcessInfo; 
+    
+    CBufFlat* processBuf;
+    // Construct processBuf and expand it before the beginning (index 0)
+    processBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( processBuf );
+    processBuf->ExpandL( 0, bufferLength );
+    
+    TPtr8 bufPtr( processBuf->Ptr(0) );
+    
+    // Send the buffer to the server, which will fill it.
+    TIpcArgs ipcArgs( &bufPtr );  
+    error = SendReceive( CATStorageServer::EGetProcesses, ipcArgs ); 
+    // Return with the error code if the operation failed
+    if ( error != KErrNone )
+        {
+        CleanupStack::PopAndDestroy( processBuf );
+        return error;
+        }
+    
+    // A variable for the number of TATProcessInfo objects
+    TInt count( 0 );
+     // A variable for the position
+    TInt pos( 0 );
+    
+    // Read the value for count 
+    processBuf->Read( pos, &count, KWordSize );
+    
+    // Return if we got an illegal value for count     
+    if ( count < 0 || count > KATMaxProcesses )
+        {
+        CleanupStack::PopAndDestroy( processBuf );
+        return KErrGeneral;
+        }    
+
+    // Move the position one word onwards.    
+    pos += KWordSize;
+
+    TATProcessInfo processInfo;
+
+    // Go through all TATProcessInfo objects sent to the server 
+    for ( TInt j = 0; j < count; j++ )
+        {
+        // Read one of the TATProcessInfo objects stored in the buffer.
+        processBuf->Read( pos, &processInfo, sizeOfProcessInfo );
+       
+        // Append this processInfo to the array
+        error = aProcesses.Append( processInfo );
+
+        if ( error != KErrNone )
+            {
+            CleanupStack::PopAndDestroy( processBuf );
+            return error;
+            }
+
+        // Move the pos variable one word onwards.
+        pos += sizeOfProcessInfo;
+        }  
+    
+    CleanupStack::PopAndDestroy( processBuf );
+    return error;
+    }
+        
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoadedDllsL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetLoadedDllsL( TUint aProcessId, 
+                                                RArray< TBuf8<KMaxLibraryName> >& aDlls )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetLoadedDllsL()" );
+    
+    // Panic (in debug builds) if aProcessId is faulty
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TInt error( KErrNone );
+    
+    // Size of a DLL descriptor
+    TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> );
+    
+    // Reset the sent array
+    aDlls.Reset();
+    
+    // Calculate the length of the buffer to be constructed for DLL names.
+    // One word will be reserved for the length of the array.
+    TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc; 
+    
+    CBufFlat* dllBuf;
+    // Construct dllBuf and expand it before the beginning (index 0)
+    dllBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( dllBuf );
+    dllBuf->ExpandL( 0, bufferLength );
+    
+    TPtr8 bufPtr( dllBuf->Ptr(0) );
+    
+    // Call the server with the given arguments
+    TIpcArgs ipcArgs( aProcessId, &bufPtr );  
+    error = SendReceive( CATStorageServer::EGetDlls, ipcArgs );
+    
+    // Return, if error is not KErrNone.
+    if ( error != KErrNone )
+        {
+        CleanupStack::PopAndDestroy( dllBuf );      
+        return error;
+        }
+    
+    // A variable for the number of objects in the buffer
+    TInt count( 0 );
+    
+     // A variable for the position
+    TInt pos( 0 );
+    
+    // Read the value for count 
+    dllBuf->Read( pos, &count, KWordSize );
+    
+    // Return if we got an illegal value for count
+    if ( count < 0 || count > KATMaxDlls )
+        {
+        CleanupStack::PopAndDestroy( dllBuf );
+        return KErrGeneral;
+        }
+
+    // Move the position one word onwards.    
+    pos += KWordSize;
+
+    TBuf8<KMaxLibraryName> dllName;
+
+    // Go through all DLL names objects sent to the server 
+    for ( TInt j = 0; j < count; j++ )
+        {
+        // Read one of the DLL names stored in the buffer.
+        dllBuf->Read( pos, &dllName, sizeOfDllDesc );
+       
+        // Append this DLL name to the array
+        error = aDlls.Append( dllName );
+
+        if ( error != KErrNone )
+            {
+            return error;
+            }
+
+        // Move the pos variable one word onwards.
+        pos += sizeOfDllDesc;
+        }  
+    
+    CleanupStack::PopAndDestroy( dllBuf );
+    return error;
+    }    
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoggingModeL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetLoggingModeL( TUint aProcessId,
+                                                TATLogOption& aLoggingMode )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetLoggingModeL()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TInt error(0);
+    
+    // The length of the buffer to be constructed for logging mode
+    TInt bufferLength = KWordSize; 
+    
+    CBufFlat* loggingModeBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    loggingModeBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( loggingModeBuf );
+    loggingModeBuf->ExpandL( 0, bufferLength );
+    
+    TPtr8 bufPtr( loggingModeBuf->Ptr(0) );
+    
+    // Call the server
+    TIpcArgs ipcArgs( aProcessId, &bufPtr );  
+    error = SendReceive( CATStorageServer::EGetLoggingMode, ipcArgs );
+    
+    // Return if an error occured.
+    if ( error )
+        {
+        CleanupStack::PopAndDestroy( loggingModeBuf );
+        return error;
+        }
+      
+    // A variable for the position
+    TInt pos( 0 );
+    
+    // Read the value for aNumber
+    loggingModeBuf->Read( pos, &aLoggingMode, KWordSize );
+    
+    CleanupStack::PopAndDestroy( loggingModeBuf );
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::StartSubTest
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::StartSubTest( TUint aProcessId, 
+                                              const TDesC8& aSubtestId, TInt aHandleCount )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::StartSubTest()" );
+    
+    // Panic if the parameters are faulty
+    __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    // Panic (in debug builds) if the parameters are faulty
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    TIpcArgs ipcArgs( aProcessId, &aSubtestId, aHandleCount );
+    
+    return SendReceive( CATStorageServer::ESubtestStart, ipcArgs );
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::StopSubTest
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::StopSubTest( TUint aProcessId, 
+                                             const TDesC8& aSubtestId, TInt aHandleCount )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::StopSubTest()" );
+    
+    // Panic if the parameters are faulty
+    __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    // Panic (in debug builds) if the parameters are faulty
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    TIpcArgs ipcArgs( aProcessId, &aSubtestId, aHandleCount );
+    
+    return SendReceive( CATStorageServer::ESubtestStop, ipcArgs );
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetCurrentAllocsL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetCurrentAllocsL( TUint aProcessId, 
+                                                  TUint32& aNumber,
+                                                  TUint32& aSize   )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetCurrentAllocsL()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TInt error(0);
+    
+    // The length of the buffer to be constructed for allocation number and size
+    TInt bufferLength = KWordSize + KWordSize; 
+    
+    CBufFlat* allocInfoBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    allocInfoBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( allocInfoBuf );
+    allocInfoBuf->ExpandL( 0, bufferLength );
+    
+    TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+    
+    // Call the server
+    TIpcArgs ipcArgs( aProcessId, &bufPtr );  
+    error = SendReceive( CATStorageServer::EGetCurrentAllocs, ipcArgs );
+    
+    // Return if error is not KErrNone.
+    if ( error != KErrNone )
+        {
+        CleanupStack::PopAndDestroy( allocInfoBuf );
+        return error;
+        }
+      
+    // A variable for the position
+    TInt pos( 0 );
+    
+    // Read the value for aNumber
+    allocInfoBuf->Read( pos, &aNumber, KWordSize );
+    
+    pos += KWordSize;
+    
+    // Read the value for aSize
+    allocInfoBuf->Read( pos, &aSize, KWordSize );
+    
+    CleanupStack::PopAndDestroy( allocInfoBuf );
+    
+    return KErrNone;
+    }
+                                                  
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetMaxAllocsL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetMaxAllocsL( TUint aProcessId, 
+                                              TUint32& aNumber,
+                                              TUint32& aSize   )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetMaxAllocsL()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    TInt error(0);
+     
+    // The length of the buffer to be constructed for allocation number and size
+    TInt bufferLength = KWordSize + KWordSize; 
+
+    CBufFlat* allocInfoBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    allocInfoBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( allocInfoBuf );
+    allocInfoBuf->ExpandL( 0, bufferLength );
+
+    TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+
+    // Call the server
+    TIpcArgs ipcArgs( aProcessId, &bufPtr );
+    error = SendReceive( CATStorageServer::EGetMaxAllocs, ipcArgs );
+
+    // Return, if error is not KErrNone.
+    if ( error != KErrNone )
+        {
+        CleanupStack::PopAndDestroy( allocInfoBuf );
+        return error;
+        }
+
+    // A variable for the position
+    TInt pos( 0 );
+
+    // Read the value for aNumber
+    allocInfoBuf->Read( pos, &aNumber, KWordSize );
+
+    pos += KWordSize;
+
+    // Read the value for aSize
+    allocInfoBuf->Read( pos, &aSize, KWordSize );
+
+    CleanupStack::PopAndDestroy( allocInfoBuf );
+
+    return KErrNone;
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::StartSubTest
+// An overloaded version without a PID parameter
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::StartSubTest( const TDesC8& aSubtestId )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::StartSubTest()" );
+    
+    // Panic if the parameters are faulty
+    __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    TIpcArgs ipcArgs( &aSubtestId );
+    
+    return SendReceive( CATStorageServer::ESubtestStart2, ipcArgs );
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::StopSubTest
+// An overloaded version without a PID parameter
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::StopSubTest( const TDesC8& aSubtestId )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::StopSubTest()" );
+    
+    // Panic if the parameters are faulty
+    __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+        
+    TIpcArgs ipcArgs( &aSubtestId );
+    
+    return SendReceive( CATStorageServer::ESubtestStop2, ipcArgs );
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CancelLogging
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::CancelLogging( TUint aProcessId )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::CancelLogging()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TIpcArgs ipcArgs( aProcessId );
+    
+    return SendReceive( CATStorageServer::ECancelLogging, ipcArgs );
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CreateProcess
+// Checks if the server already exists. If it doesn't, creates a new process
+// for it.
+// -----------------------------------------------------------------------------
+//
+TInt RATStorageServer::CreateProcess()
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::CreateProcess()" );
+    
+    TInt errorCode( KErrNone );
+ 
+    // Check if the server already exists
+    TFindServer findServer( KStorageServerName );
+    TFullName fullName;
+
+    errorCode = findServer.Next( fullName );
+    
+    // Return KErrNone if the server is already running
+    if ( errorCode == KErrNone )
+        {
+        return KErrNone;
+        }
+    
+    // Otherwise initiate starting the server by creating first a new process for it.
+    // The second argument of the Create() method call is an empty descriptor, because
+    // we don't need to pass any data to the thread function of the new process's main
+    // thread.
+    RProcess process;
+    errorCode = process.Create( KStorageServerFile, KNullDesC );
+    
+    // Return the error code if the creation of the process failed
+    if ( errorCode != KErrNone )
+        {
+        return errorCode;
+        }
+    
+    TRequestStatus status;
+    process.Rendezvous( status );
+    
+    // If the status is not KRequestPending, abort the project creation
+    // and return KErrGeneral
+    if ( status != KRequestPending )
+        {
+        process.RendezvousCancel( status );
+        process.Kill( KErrGeneral );
+        process.Close();
+        return KErrGeneral;
+        }
+    
+    // Otherwise make the first thread of the new process eligible for execution
+    process.Resume();
+    
+    // Wait for a signal from the server       
+    User::WaitForRequest( status );
+    
+    // Close the process handle    
+    process.Close();
+    
+    // Return the error code
+    return status.Int();
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::ConstructBuffersL
+// Allocates buffers from heap. Called when connecting to the server
+// -----------------------------------------------------------------------------
+//
+void RATStorageServer::ConstructBuffersL()
+    {
+    LOGSTR1( "STSE void RATStorageServer::ConstructBuffersL()" );
+    
+    // Calculate the length of the buffer to be constructed for call stack.
+    // One word will be reserved for the length of the array
+    TInt bufferLength = ( (1 + KATMaxCallstackLength) * KWordSize  );
+    
+    // Construct iStackBuf and expand it before the beginning (index 0)
+    iStackBuf = CBufFlat::NewL( bufferLength );
+    iStackBuf->ExpandL( 0, bufferLength );
+    }
+    
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoggingFileL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetLoggingFileL( TUint aProcessId,
+                                                    TDes8& aFileName )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetLoggingFileL()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TInt error(0);
+
+    TBuf8<KMaxFileName> fileBuf;
+    // Call the server
+    TIpcArgs ipcArgs( aProcessId, &fileBuf );  
+    error = SendReceive( CATStorageServer::EGetLoggingFile, ipcArgs );
+    
+    // Return, if an error occured.
+    if ( error )
+        {
+        return error;
+        }
+      
+    aFileName.Copy( fileBuf );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetUdebL
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TInt RATStorageServer::GetUdebL( TUint aProcessId, TUint32& aIsUdeb )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::GetUdebL()" );
+    
+    // Panic (in debug builds) if aProcessId is illegal
+    __ASSERT_DEBUG( aProcessId != KNullProcessId,        
+        StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+    
+    TInt error(0);
+    TBuf8<KMaxVersionName> isUdeb;
+    _LIT8( KUdeb, "UDEB" );
+    // Call the server
+    TIpcArgs ipcArgs( aProcessId, &isUdeb );  
+    error = SendReceive( CATStorageServer::EGetUdeb, ipcArgs );
+    
+    // Return, if an error occured.
+    if ( error != KErrNone )
+        {
+        return error;
+        }
+    
+    if ( isUdeb.Compare( KUdeb() ) == 0 )
+        {
+        LOGSTR1( "STSE TInt RATStorageServer::GetUdebL() - Is UDEB" );    
+        aIsUdeb = 1;    
+        }
+    else
+        {
+        LOGSTR1( "STSE TInt RATStorageServer::GetUdebL() - Is UREL" );
+        aIsUdeb = 0;    
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::IsMemoryAdded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::IsMemoryAdded( TUint32 aMemAddress )
+    {
+    LOGSTR1( "STSE TInt RATStorageServer::IsMemoryAdded()" );
+        
+    TIpcArgs ipcArgs( aMemAddress );    
+    return SendReceive( CATStorageServer::EIsMemoryAdded, ipcArgs );
+    }
+
+//  End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../client/inc/atstorageserverclnt.h         OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/atstorageserverclnt.h)
+
+PRJ_MMPFILES
+../server/group/atoolstorageserver.mmp
+../client/group/atoolstorageserverclnt.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/storageservertest.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/inc/atstorageservercommon.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Includes common constants and enums for the AnalyzeTool 
+*                StorageServer client and server.
+*
+*/
+
+
+
+#ifndef ATSTORAGESERVERCOMMON_H
+#define ATSTORAGESERVERCOMMON_H
+
+
+//  INCLUDES
+
+#include <e32base.h>
+
+
+// CONSTANTS
+
+// Server's file name
+_LIT(KStorageServerFile, "AToolStorageServer.exe");
+
+// server name
+_LIT(KStorageServerName,"AToolStorageServer");
+
+
+// The path of the storage file
+#ifdef __WINS__
+_LIT( KATDataFilePath, ":\\logs\\analyzetool\\" );
+#else
+_LIT( KATDataFilePath, ":\\analyzetool\\" );
+_LIT( KATDataFilePath2, ":\\data\\analyzetool\\" );
+#endif
+
+// The word size in the current system is 32 bits, which is 4 bytes.
+const TInt KWordSize = 4;
+
+// Leak array granularity value
+const TInt KLeakArrayGranularity = 100;
+
+// DATA TYPES
+
+/** Storage Server panic codes */
+enum TStorageServerPanics
+    {
+    EAToolBadRequest = 1, // An undefined operation request from the client
+    EAToolBadArgument,    // Illegal arguments / function parameters   
+    EAToolNotAllowed,     // An operation is not allowed in the current program state
+    EAToolInternalError,   // An internal error has occured
+    EAToolIllegalLogOption // An undefined log option has been requested 
+    };
+
+
+/** Panic categories */
+_LIT(KCategoryServer,"STSEServer");
+_LIT(KCategoryClient,"STSEClient");
+
+inline void StorageServerPanic( const TDesC &aCategory, TStorageServerPanics aReason )
+    {
+    User::Panic(aCategory, aReason);
+    }
+  
+#endif      // ATSTORAGESERVERCOMMON_H   
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/group/atoolstorageserver.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The .mmp file for the server side of AToolStorageServer
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET        atoolstorageserver.exe
+TARGETTYPE    exe
+UID           0x0 0x20012430   
+CAPABILITY    NONE
+
+SMPSAFE
+
+EPOCHEAPSIZE 0x10000 0x800000
+
+SOURCEPATH    ../src
+
+SOURCE        atstorageserver.cpp
+SOURCE        atstorageserversession.cpp
+SOURCE        atmemoryentry.cpp
+SOURCE        atdynprocessinfo.cpp
+SOURCE        atdriveinfo.cpp
+SOURCE        atdllinfo.cpp
+
+USERINCLUDE   ../inc
+USERINCLUDE   ../../inc
+USERINCLUDE   ../../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY     euser.lib
+LIBRARY     efsrv.lib
+LIBRARY     flogger.lib
+LIBRARY     charconv.lib
+LIBRARY     platformenv.lib 
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdllinfo.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class TATDllInfo.
+*
+*/
+
+
+#ifndef ATDLLINFO_H
+#define ATDLLINFO_H
+
+// INCLUDES
+#include <u32std.h>
+
+/**
+*  Stores information of process loaded library
+*/
+class TATDllInfo
+    {
+    
+    public: // Constructors
+        
+        /**
+        * C++ default constructor.
+        * @param aStartAddress Start address of the library 
+        * @param aEndAddress The end address of the library 
+        * @param aLoadTime The current time in a 64-bit form.
+        * @param aDllName The name of the library
+        */
+        TATDllInfo( const TUint32 aStartAddress, const TUint32 aEndAddress, 
+        		const TInt64& aLoadTime, const TDesC8& aDllName );
+
+    public: // New functions
+
+        /**
+        * Returs library start address
+        * @return TUint32 start address of the library
+        */
+        TUint32 StartAddress();
+        
+        /**
+		* Returns library end address
+		* @return TUint32 end address of the library
+		*/
+		TUint32 EndAddress();
+                
+        /**
+        * Gets specific library name
+        * return TDes8 Name of the library
+        */
+        TDes8& Name();
+        
+        /**
+		* Returns library load time
+		* @return TInt64 library load time
+		*/
+        TInt64 LibraryLoadTime();
+        		
+        /**
+		* Checks if two objects of this class match based on the objects's
+        * saved library name.
+		* @param aFirst Library object
+		* @param aSecond Library object
+		* return TBool ETrue, if the two objects match. EFalse otherwise.
+		*/
+        static TBool Match( const TATDllInfo& aFirst, const TATDllInfo& aSecond );
+                
+    public: // Member variables
+
+        /* Start address of the loaded dll */
+    	const TUint32 iStartAddress;
+
+        /* End address of the loaded dll */
+        const TUint32 iEndAddress;
+
+        /* Loaded dll name */
+        TBuf8<KMaxLibraryName> iName;
+        
+        /** For storing the time when DLL has loaded. */
+        const TInt64 iLoadTime;
+    };
+
+#endif // ATDLLINFO_H
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdriveinfo.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class TATDriveInfo.
+*
+*/
+
+
+
+#ifndef ATDRIVEINFO_H
+#define ATDRIVEINFO_H
+
+#include <f32file.h>
+
+/**
+*  Check what drives exists and creates file full path.
+*/
+class TATDriveInfo
+    {    
+    public: // Constructors
+        
+        /**
+        * C++ default constructor.
+        */
+        TATDriveInfo();
+
+    public: // New functions
+
+        /**
+        * Create the file full path.
+        * @param aPath Full path.
+        * @param aFileName Filename.
+        * @param aFs A handle to a file server.
+        * @return KErrNone or KErrAlreadyExists, if successful; 
+        *   Otherwise one of the other system wide error codes.
+        */
+        static TInt CreatePath( TDes& aPath, const TDesC& aFileName, RFs& aFs );   
+    
+    private: // New functions
+    
+        /**
+        * Get the available drive character.
+        * @param aDrive The drive letter.
+        * @param aDriveNumber The drive number.
+        * @param aFs A handle to a file server.
+        * @param aDriveType Drive type.
+        * @return KErrNone, if successful; otherwise KErrNotFound
+        */
+        static TInt GetDrive( TChar& aDrive, TInt& aDriveNumber, 
+                RFs& aFs, const TUint aDriveType );  
+        
+    };
+
+#endif // ATDRIVEINFO_H
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdynprocessinfo.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class CATDynProcessInfo
+*
+*/
+
+
+#ifndef ATDYNPROCESSINFO_H
+#define ATDYNPROCESSINFO_H
+
+
+//  INCLUDES
+#include    <e32base.h>
+#include    <analyzetool/atcommon.h>
+#include	"atdllinfo.h"
+
+// FORWARD DECLARATIONS
+class CATStorageServerSession;
+
+// CLASS DECLARATION
+
+/**
+*  A class that can store different process related information. The information
+*  is associated to a particular process wiht a member telling a process ID.
+*  All the other information but the process ID and the pointer to this process's
+*  associated session object can be subject to change dynamically, run-time.
+*/
+class CATDynProcessInfo : public CBase
+    {
+    public: // Constructor
+
+        /**
+        * Constructor. 
+        */ 
+        CATDynProcessInfo();
+    
+        /**
+        * Constructor. 
+        * @param aProcessId A process ID.
+        * @param aSessionObject A pointer to this process's associated session object.
+        * @param aDlls The loaded DLLs of the associated process.
+        */
+        CATDynProcessInfo( TUint aProcessId,
+                           CATStorageServerSession* aSessionObject,
+                           const RArray<TATDllInfo>& aDlls );
+        
+        /**
+        * Constructor.
+        * @param aProcessId A process ID.
+        * @param aSessionObject A pointer to this process's associated session object.
+        */
+        CATDynProcessInfo( TUint aProcessId,
+                           CATStorageServerSession* aSessionObject );
+                           
+        /**
+        * Constructor.
+        * @param aProcessId A process ID.
+        */
+        CATDynProcessInfo( TUint aProcessId );
+
+        /**
+        * Destructor
+        */
+        virtual ~CATDynProcessInfo();
+        
+    public:
+        
+        /**
+        * Compares two objects of this class based on the process ID.
+        * @param aFirst The first object of this class to be compared.
+        * @param aSecond The second object of this class to be compared.
+        * @return  Zero, if the two objects are equal. A negative value,
+        *   if the first object is less than the second. A positive value,
+        *   if the first object is greater than the second.
+        */
+        static TInt Compare( const CATDynProcessInfo& aFirst,
+                             const CATDynProcessInfo& aSecond );
+        
+    public:
+
+        /** The ID of the process. */
+        const TUint iProcessId;
+        
+        /** A pointer to the session object associated with this process. */
+        CATStorageServerSession* const iSessionObject;
+        
+        /** The DLLs loaded by the associated process */
+        RArray<TATDllInfo> iDlls;
+    };
+  
+#endif      // ATDYNPROCESSINFO_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atmemoryentry.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the class CATMemoryEntry
+*
+*/
+
+
+#ifndef ATMEMORYENTRY_H
+#define ATMEMORYENTRY_H
+
+
+//  INCLUDES
+#include <e32base.h>
+
+
+// CLASS DECLARATION
+
+/**
+*  A class for storing memory entries when the server is informed that memory has been
+*  allocated. The class stores the memory address of a new allocation and a pointer to
+*  a buffer including the current call stack. It also stores a time stamp, and the size
+*  of the allocation. 
+*     The class has member methods for evaluating two different objects of this class
+*  with each other. In the construction the class takes a pointer to the call stack
+*  buffer, but it does not create the buffer itself. However, it is responsible for
+*  deleting the buffer in the destruction.
+*/
+class CATMemoryEntry : public CBase
+    {
+    public: // Constructor
+
+        /**
+        * Constructor.
+        * @param aMemAddress An address to allocated memory.
+        * @param aCallstackBuf A pointer to a buffer containing call stack's memory
+        *   addresses.
+        * @param aAllocTime The current time in a 64-bit form.
+        * @param aAllocSize The size of an allocated memory chunk.
+        */ 
+        CATMemoryEntry( TUint32 aMemAddress, const CBufFlat* aCallstackBuf,
+                        const TInt64& aAllocTime, TInt aAllocSize );
+
+        /**
+        * Destructor
+        */
+        virtual ~CATMemoryEntry();
+
+    public:
+        /**
+        * Compares two objects of this class based on the allocation time.
+        * @param aFirst The first object of this class to be compared.
+        * @param aSecond The second object of this class to be compared.
+        * @return  Zero, if the two objects are equal. A negative value,
+        *   if the first object is less than the second. A positive value,
+        *   if the first object is greater than the second.
+        */
+        static TInt Compare( const CATMemoryEntry& aFirst,
+                             const CATMemoryEntry& aSecond );
+
+        /**
+        * Checks if two objects of this class match based on the objects's
+        * saved memory allocation addresses.
+        * @param aFirst The first object of this class to be evaluated.
+        * @param aSecond The second object of this class to be evaluated.
+        * @return ETrue, if the two objects match. EFalse otherwise.
+        */
+        static TBool Match( const CATMemoryEntry& aFirst,
+                            const CATMemoryEntry& aSecond );
+
+    public:
+
+        /** For storing an address of a memory allocation. */
+        const TUint32 iMemAddress;
+
+        /** A pointer to an array for storing the current call stack. */
+        const CBufFlat* const iCallstackBuf;
+        
+        /** For storing the time when an allocation has occured. */
+        const TInt64 iAllocTime;
+        
+        /** For storing the size of an allocation. */
+        const TInt iAllocSize;
+        
+    };
+  
+  
+#endif      // ATMEMORYENTRY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atstorageserver.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,218 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the server side main class CATStorageServer
+*
+*/
+
+
+#ifndef ATSTORAGESERVER_H
+#define ATSTORAGESERVER_H
+
+
+//  INCLUDES
+#include    <e32base.h>
+#include    <analyzetool/atcommon.h>
+#include 	"atdllinfo.h"
+
+// CONSTANTS
+// Constants for the server's version
+const TUint KVersionNumberMaj = 0;
+const TUint KVersionNumberMin = 1;
+const TUint KVersionNumberBld = 1;
+
+// DATA TYPES
+
+// FORWARD DECLARATIONS
+class TATProcessInfo;
+class CATDynProcessInfo;
+class CATStorageServerSession;
+
+// CLASS DECLARATION
+
+/**
+*  The main class of the Storage Server.
+*  When a client connects to the server, a new session object
+*  is created by an object of this class. If the server does not exist when
+*  connecting, a new process and an object of this class are created first.
+*/
+class CATStorageServer : public CPolicyServer
+    {
+    
+    public: // Enumerations
+    
+        // opcodes used in message passing between client and server
+        enum TStorageServerReq
+            {
+            EProcessStarted,
+            EDllLoaded,
+            EDllUnloaded,
+            EMemoryAllocated,
+            EMemoryFreed,
+            EProcessEnded,
+            EMemoryCheck,
+            EGetProcesses,
+            EGetDlls,
+            ESetLoggingMode,
+            EGetLoggingMode,
+            ESubtestStart,
+            ESubtestStop,
+            ESubtestStart2,
+            ESubtestStop2,
+            EGetCurrentAllocs,
+            EGetMaxAllocs,
+            ECancelLogging,
+            EGetUdeb,
+            EGetLoggingFile,
+            EProcessUdeb,
+            EIsMemoryAdded,
+            EOutOfBounds
+            };
+    
+    
+    public: // Constructors and destructor
+        
+        /**
+        * Two-phased constructor that can leave.
+        * @return A new instance of this class
+        */
+        static CATStorageServer* NewL();
+        
+        /**
+        * Two-phased constructor that can leave and leaves a pointer
+        * on the cleanup stack.
+        * @return A new instance of this class
+        */
+        static CATStorageServer* NewLC();
+        
+        /**
+        * Destructor
+        */
+        virtual ~CATStorageServer();
+
+    public: // New functions
+        
+  
+        /**
+        * Creates a new server object and starts the server.
+        */
+        static void RunServerL();
+        
+        /**
+        * Increments the count of active sessions for this server.
+        */
+        void IncSessionCount();
+
+        /**
+        * Decrements the count of active sessions for this server.
+        */
+        void DecSessionCount();
+        
+        /**
+        * Adds a new process into the server's arrays.
+        * @param aProcessName The name of the process to be added.
+        * @param aProcessId The ID of the process to be added.
+        * @param aSessionObject A pointer to the current process's associated session
+        *   object.
+        * @param aStartTime The starting time of the process to be added. It represents
+        *   time as a number of microseconds since midnight, January 1st, 0 AD nominal 
+        *   Gregorian. This is the representation used by, e.g., the TTime class.
+        * @return KErrNone, if the operation is successful; KErrAlreadyExists, if
+        *   an attempt is being made to insert a duplicate process; otherwise one of
+        *   the other system wide error codes.
+        */
+        TInt AddProcessL( const TDesC8& aProcessName, 
+                         TUint aProcessId,
+                         CATStorageServerSession* aSessionObject,
+                         const TInt64& aStartTime );
+        
+        /**
+        * Removes a process from the server's arrays.
+        * @param aProcessId The ID of the process to be removed.
+        * @return KErrNone, if successful; KErrNotFound, if a process with
+        *   the specified process ID could not be found in the array.
+        */
+        TInt RemoveProcessL( TUint aProcessId );
+        
+        /**
+        * Adds a DLL for a given process to the dynamic process info array of this class.
+        * @param aProcessId The ID of the process that has loaded the DLL to be added.
+        * @param aDllInfo Information of the DLL.
+        * @return KErrNone, if successful; KErrNotFound, if a process with the given
+        *   process ID could not be found; KErrAlreadyExists, if a DLL with the given
+        *   name was already stored; otherwise one of the other system wide error codes.
+        */
+        TInt AddDllL( TUint aProcessId, const TATDllInfo aDllInfo );
+        
+        /**
+        * Removes a DLL associated with the given process from the dynamic process
+        * info array of this class.
+        * @param aProcessId The ID of the process that has loaded the DLL to be removed.
+        * @param aDllName The name of the DLL to be removed.
+        * @return KErrNone, if successful; KErrNotFound, if a process with
+        *   the specified process ID could not be found, or if a DLL with the specified
+        *   name could not be found.
+        */
+        TInt RemoveDllL( TUint aProcessId, const TDesC8& aDllName );
+            
+        /**
+        * Gives a reference to the process info array of this class.
+        * @return A reference to iProcesses array
+        */
+        const RArray<TATProcessInfo>& ProcessInfoArray();
+        
+        /**
+        * Gives a reference to the dynamic process info array of this class.
+        * @return A reference to iProcessesDyn array
+        */
+        const RPointerArray<CATDynProcessInfo>& DynProcessInfoArray();
+                
+    public: // Functions from base classes
+        
+        /**
+        * From CPolicyServer.
+        * Creates a new server-side session object.
+        * @param aVersion The version of this server
+        * @param aMessage A message from the client
+        * @return A pointer to a new session object.
+        */
+        CSession2* NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) const;
+        
+    private:
+
+        /**
+        * C++ default constructor.
+        * @param aPriority A priority for this active object
+        */
+        CATStorageServer( TInt aPriority );
+
+        /**
+        *  Symbian 2nd phase constructor.
+        */
+        void ConstructL();
+   
+    private: // Data
+        
+        /** The number of active sessions */
+        TInt iSessionCount;
+        
+        /** An array for storing TATProcessInfo objects */
+        RArray<TATProcessInfo> iProcesses;
+        
+        /** An array for storing CATDynProcessInfo pointers */
+        RPointerArray<CATDynProcessInfo> iProcessesDyn;
+    };
+
+#endif      // ATSTORAGESERVER_H
+            
+// End of File
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atstorageserversession.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,588 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Declaration of the server side session class CATStorageServerSession
+*
+*/
+
+
+#ifndef ATSTORAGESERVERSESSION_H
+#define ATSTORAGESERVERSESSION_H
+
+
+//  INCLUDES
+#include    <e32base.h>
+#include    <f32file.h>
+#include    <analyzetool/atcommon.h>
+
+// FORWARD DECLARATIONS
+class CATStorageServer;
+class CATMemoryEntry;
+
+// CLASS DECLARATIONS
+
+/**
+*  A class for storing memory addresses and sizes of allocations.
+*  Needed for giving allocation information for the configuration UI.
+*/
+class TAllocInfo
+    {
+    public:
+    
+    // Constructor
+    TAllocInfo( TUint32 aMemAddress, TInt aAllocSize );
+    
+    /** Address of a memory allocation. */
+    const TUint32 iMemAddress;
+    
+    /** Size of the associated allocation. */
+    const TInt iAllocSize;
+    };
+
+
+/**
+*  The session class for Storage Server.
+*  When the Storage Server client connects to the server, a new object of this
+*  class is constructed. So, for every client there is an associated object
+*  of this class. CATStorageServer forwards all client messages to their associated
+*  session objects.
+*/
+class CATStorageServerSession : public CSession2
+    {
+    public: // Enumerations
+        
+    public:  // Constructors and destructor
+        
+        /**
+        * Two-phased constructor that can leave.
+        * @return A new instance of this class
+        */
+        static CATStorageServerSession* NewL( CATStorageServer& aStorageServer );
+        
+        /**
+        * Two-phased constructor that can leave and leaves a pointer
+        * on the cleanup stack.
+        * @return A new instance of this class
+        */
+        static CATStorageServerSession* NewLC( CATStorageServer& aStorageServer );
+        
+        /**
+        * Destructor
+        */
+        virtual ~CATStorageServerSession();
+        
+    public: // Functions from base classes 
+        
+        /**
+        * Receives messages sent by a client.
+        * @param aMessage A message from a client
+        */
+        virtual void ServiceL( const RMessage2& aMessage );
+        
+    protected: // new functions
+        
+        /**
+        * Initializes this session for logging. This includes opening a logging file
+        * with a requested name. The method is to be called as the first method after
+        * connecting to the server. The method logs information on process starting into
+        * the just opened logging file.
+        * If a logging session is already ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is already
+        * ongoing. Otherwise one of the other system wide error codes.
+        */
+        TInt LogProcessStartedL( const RMessage2& aMessage );
+        
+        /**
+        * Initializes this session for logging. The method is to be called as the first
+        * method after connecting to the server. The method logs information on process
+        * starting into debug channel.
+        * If a logging session is already ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is already
+        * ongoing. Otherwise one of the other system wide error codes.
+        */
+        TInt LogProcessStartTraceL( const RMessage2& aMessage );
+         
+        /**
+        * Logs information on a DLL load into the opened file.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; Otherwise one of the other system wide error codes.
+        */
+        TInt LogDllLoadedL( const RMessage2& aMessage );
+        
+        /**
+        * Logs information on a DLL load into debug channel.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; Otherwise one of the other system wide error codes.
+        */
+        TInt LogDllLoadTraceL( const RMessage2& aMessage );
+        
+        /**
+        * Logs information on a DLL unload into the opened file.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; Otherwise one of the other system wide error codes.
+        */
+        TInt LogDllUnloadedL( const RMessage2& aMessage );
+        
+        /**
+        * Logs information on a DLL unload into debug channel.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; Otherwise one of the other system wide error codes.
+        */
+        TInt LogDllUnloadTraceL( const RMessage2& aMessage );
+        
+        /**
+        * Stores a memory allocation (memory address, current call stack, allocation
+        * time and allocation size) in an internal array.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrAlreadyExists, if an attempt is being made to allocate
+        *   again an already allocated memory area; Otherwise one of the other system
+        *   wide error codes.
+        */
+        TInt LogMemoryAllocatedL( const RMessage2& aMessage );
+        
+        /**
+        * Logs information on a memory allocation into debug channel.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrAlreadyExists, if an attempt is being made to allocate
+        *   again an already allocated memory area; Otherwise one of the other system
+        *   wide error codes.
+        */
+        TInt LogMemoryAllocTraceL( const RMessage2& aMessage );
+                
+        /**
+        * Check a memory allocation (memory address) from an internal array.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @param aRemoveAlloc Boolean to enable removing the found address from allocations.
+        * @return KErrNone, if memory address found in array; 
+        *   KErrNotFound, if the requested memory address was not found.
+        */
+        TInt IsMemoryAdded( const RMessage2& aMessage, const TBool aRemoveAlloc = EFalse );
+        
+        /**
+        * Removes a memory allocation (memory address, current call stack, allocation
+        * time and allocation size) from an internal array.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrNotFound, if the requested memory address was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        TInt LogMemoryFreedL( const RMessage2& aMessage );
+        
+        /**
+        * Logs information on freeing of a memory allocatin into debug channel.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrNotFound, if the requested memory address was not
+        *   found; Otherwise one of the other system wide error codes.
+        */
+        TInt LogMemoryFreedTraceL( const RMessage2& aMessage );
+        
+        /**
+        * Logs all non-released memory allocations into the opened file as memory leaks.
+        * Then the method logs a number of possibly occured handle leaks into the file.
+        * Next, the method logs information on process ending into the logging file.
+        * Finally, this method closes the logging file opened for the connected process,
+        * and ends the current logging session. However, this method does not end the 
+        * actual client-server session.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrNotSupported if this method is called with a wrong
+        *   process id from the client. Otherwise one of the other system wide error
+        *   codes.
+        */
+        TInt LogProcessEndedL( const RMessage2& aMessage );
+        
+        /**
+        * Logs a number of possibly occured handle leaks into debug channel. Then, the method
+        * logs information on process ending into debug channel. The method also
+        * ends the current logging session. However, this method does not end the actual
+        * client-server session.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrCancel, if a logging session is not
+        *   currently ongoing; KErrNotSupported if this method is called with a wrong
+        *   process id from the client. Otherwise one of the other system wide error
+        *   codes.
+        */
+        TInt LogProcessEndTraceL( const RMessage2& aMessage );
+        
+        /**
+        * Checks if a given memory address can be found.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return When the system is logging into a file: the index of a found 
+        *   memory address, or KErrNotFound, if a matching memory address cannot
+        *   be found. KErrNone, when the system is not logging into a file.
+        *   KErrCancel, if a logging session is not currently ongoing.
+        */
+        TInt CheckMemoryAddressL( const RMessage2& aMessage );
+        
+        /**
+        * Checks if a given memory address can be found.
+        * If a logging session is not ongoing, the method makes the client raise an
+        * STSEClient: 3 panic, and returns KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return When the system is logging into a file: the index of a found 
+        *   memory address, or KErrNotFound, if a matching memory address cannot
+        *   be found. KErrNone, when the system is not logging into a file.
+        *   KErrCancel, if a logging session is not currently ongoing.
+        */
+        TInt CheckMemoryAddressTrace( const RMessage2& aMessage );
+        
+        /**
+        * Gets all the processes currently logging with AnalyzeTool
+        * @param aMessage A message that includes parameters sent by the client.
+        *   On return a buffer including all the currently logging processes is written
+        *   into this message.
+        * @return KErrNone, if successful; otherwise one of the other system wide error
+        *   codes.
+        */
+        TInt GetProcessesL( const RMessage2& aMessage );
+        
+        /**
+        * Gets all the DLLs loaded by the process determined by the parameters.
+        * @param aMessage A message that includes parameters sent by the client.
+        *   A buffer including all the DLLs loaded by the requested process is
+        *   written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetDllsL( const RMessage2& aMessage );
+        
+        /**
+        * Gets the logging mode of the process determined by the parameters.
+        * @param aMessage A message that includes parameters sent by the client.
+        *   On return, the logging mode is written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetLoggingModeL( const RMessage2& aMessage );
+        
+        /**
+        * Starts a sub test for the given process.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process is not
+        *   found; KErrNotSupported, if the requested process does not have a logging
+        *   session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+        *   other system wide error codes.
+        */
+        TInt StartSubtestL( const RMessage2& aMessage );
+        
+        /**
+        * Stops a sub test for the given process.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process is not
+        *   found; KErrNotSupported, if the requested process does not have a logging
+        *   session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+        *   other system wide error codes.
+        */
+        TInt StopSubtestL( const RMessage2& aMessage );
+        
+        /**
+        * Starts a sub test for the calling process. Does not need a PID from the client.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrNotSupported, if the calling process
+        *   does not have a logging session ongoing or its logging mode is not
+        *   EATLogToTrace; Otherwise one of the other system wide error codes.
+        */
+        TInt StartSubtest2L( const RMessage2& aMessage );
+        
+        /**
+        * Stops a sub test for the calling process. Does not need a PID from the client.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrNotSupported, if the calling process
+        *   does not have a logging session ongoing or its logging mode is not
+        *   EATLogToTrace; Otherwise one of the other system wide error codes.
+        */
+        TInt StopSubtest2( const RMessage2& aMessage );
+        
+        /**
+        * Gets the number and total size of the current memory chunks allocated by the
+        * requested process.
+        * @param aMessage A message that includes parameters sent by the client. The
+        *   requested information is written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetCurrentAllocsL( const RMessage2& aMessage );
+        
+        /**
+        * Gets the maximum number of memory chunks and the maximum amount of memory 
+        * allocated by the requested process during the test run.
+        * @param aMessage A message that includes parameters sent by the client. The
+        *   requested information is written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetMaxAllocsL( const RMessage2& aMessage );
+        
+        /**
+        * Cancels logging for the requested process. After logging of a given process
+        * has been cancelled, the session associated with that process will not be
+        * usable anymore. If a process wants to start logging again, it needs to close
+        * the handle and open it again in order to create a new session. Until then, any
+        * of the server's methods that can be called by the client will return
+        * KErrCancel.
+        * @param aMessage A message that includes parameters sent by the client.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt CancelLoggingL( const RMessage2& aMessage );
+        
+        /**
+        * Gets the logging file of the process determined by the parameters.
+        * @param aMessage A message that includes parameters sent by the client.
+        *   On return, the logging file is written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetLoggingFileL( const RMessage2& aMessage );
+        
+        /**
+        * Gets the mode of the process determined by the parameters.
+        * @param aMessage A message that includes parameters sent by the client.
+        *   On return, the logging file is written into this message.
+        * @return KErrNone, if successful; KErrNotFound, if the requested process was
+        *   not found; otherwise one of the other system wide error codes.
+        */
+        TInt GetUdebL( const RMessage2& aMessage );
+        
+        /**
+        * Sets the mode of the process determined by the parameters.
+        * @param aMessage A message that includes parameters sent by the client.
+        */
+        void SetUdeb( const RMessage2& aMessage );
+        
+    private:  // New functions for internal use  
+    
+        /**
+        * Releases the resources reserved by this object, and before closing the logging
+        * file and file server session, the method logs information on the occured error
+        * into the logging file.
+        * @param aError The error code to be logged.
+        */
+        void HandleError( TInt aError );
+        
+        /**
+        * Releases the resources reserved by this object, and logs information on the
+        * occured error into debug channel.
+        * @param aError The error code to be logged.
+        */
+        void HandleErrorTrace( TInt aError );
+        
+        /**
+        * Opens a file server session and a file with the name specified.
+        * @param aFileName The name of the file into which to log.
+        * @param aProcessName Current process name.
+        * @return KErrNone, if successful; otherwise one of the other system wide
+        *   error codes.
+        */
+        TInt OpenFsAndFile( const TDesC& aFileName, const TDesC8& aProcessName );
+        
+        /**
+        * Method is used to parse file name extension.
+        * @param aFileName The name of the file into which to log.
+        * @param aExtension Parsed file extension. 
+        */
+        void ParseExtension( TDes& aFileName, TDes& aExtension );
+        
+        /**
+        * Called internally when need generate new file name.
+        * @param aFileName The name of the file into which to log.
+        * @param aProcessName Current process name.
+        */
+        void GenerateNewFileName( TDes& aFileName, const TDesC8& aProcessName );
+        
+        /**
+        * Method is used to check that file exists and is valid.
+        * @param aFileName The name of the file into which to log.
+        */
+        void CheckIfFileAlreadyExist( const TDes& aFileName );
+        
+        /**
+        * Method is used to check file version.
+        * @param aFileName The name of the file into which to log.
+        */
+        void CheckFileVersion( const TDes& aFileName );
+        
+        /**
+        * Closes the handles to the file server session and to the file (if currently open).
+        */
+        void CloseFsAndFile();
+        
+        /**
+        * Writes the memory leaks stored in the iLeakArray member array into the
+        * logging file opened for the current logging session. If the method is
+        * called in a wrong program state (logging session is not ongoing, or the
+        * logging mode is not EATLogToFile), STSEClient: 4, and STSEServer: 4
+        * panics are raised.
+        * @param aMessage The current message from the client.
+        * @return KErrNone, if successful; otherwise one of the other system wide
+        *   error codes.
+        */
+        TInt PrintLeaksL( const RMessage2& aMessage );
+        
+        /**
+        * Sets the server's mode of operation. The operation mode is determined with
+        * an enumeration value, which is received from the client. If the method is
+        * called in a wrong program state (logging session is ongoing), STSEClient: 4,
+        * and STSEServer: 4 panics are raised.
+        * @param aMessage The current message from the client.
+        */
+        void SetLogOption( const RMessage2& aMessage );
+        
+        /**
+        * Logs the given descriptor through debug channel.
+        * @param aLogString The descriptor to be logged.
+        * @return KErrNone, if successful; KErrNotSupported, if a logging session is not
+        *   ongoing, or the logging mode is not EATLogToTrace;
+        */
+        TInt LogThroughTrace( const TDesC& aLogString ) const;
+        
+        /**
+        * Gives a reference to the allocation info array of this class.
+        * @return A reference to iAllocInfoArray array
+        */
+        RArray<TAllocInfo>& AllocInfoArray();
+               
+        /**
+        * Creates a panic in the associated client's code.
+        * @param aPanic The panic code
+        * @param aMessage The message associated with this panic.
+        */
+        void PanicClient( TInt aPanic, const RMessage2& aMessage );
+        
+        /**
+        * Logs the abnormal end to the debug channel (If logging mode is EATLogToTrace) 
+        * and to the file(If logging mode is EATLogToFile).
+        */
+        void LogAbnormalEnd();
+        
+        /**
+        * Get the current universal time.
+        * @return Time
+        */
+        TInt64 GetTime();
+        
+    private: // Constructors 
+        
+        /**
+        * C++ default constructor.
+        */
+        CATStorageServerSession( CATStorageServer& aStorageServer );
+        
+        /**
+        *  Symbian 2nd phase constructor.
+        */
+        void ConstructL();   
+        
+    private: // Data
+        
+        /** A reference to the CATStorageServer object that has created this session */    
+        CATStorageServer& iStorageServer;
+               
+        /** A handle to a file server */
+        RFs iFileServer;
+        
+        /** A handle to a file */
+        RFile iFile;
+        
+        /** A member variable for storing results of server function calls. */ 
+        TInt iError;
+        
+        /** An object for getting time stamps */ 
+        TTime iTime;
+        
+        /** 
+        * An array for storing CATMemoryEntry pointers. Used when logging
+        * to an S60 file.
+        */
+        RPointerArray<CATMemoryEntry> iLeakArray;
+        
+        /** 
+        * An array for storing TAllocInfo objects. Used for keeping records on memory
+        * allocations and their sizes.
+        */
+        RArray<TAllocInfo> iAllocInfoArray;
+        
+        /** The ID of the process associated with this session. */
+        TUint iProcessId;
+        
+        /**
+        * A boolean telling whether this session has been initialized for logging
+        * ( whether the client's LogProcessStarted() method has been called ) or not.
+        */
+        TBool iLoggingOngoing;
+        
+        /**
+        * A variable telling the number of microseconds from January 1st, 0 AD
+        * nominal Gregorian to January 1st, 1970 AD nominal Gregorian. 
+        */
+        TInt64 iMicroSecondsAt1970;
+        
+        /**
+        * An enumeration that tells the current operation mode of the Storage Server.
+        */
+        TATLogOption iLogOption;
+        
+        /** The total size of all the current allocations of this process */
+        TUint32 iCurAllocSize;
+        
+        /** The maximum number of allocations of this process */
+        TUint32 iMaxAllocs;
+        
+        /** The maximum total size of allocations of this process */
+        TUint32 iMaxAllocSize;
+        
+        /** The logging file of this process */
+        TBuf8<KMaxFileName> iLogFile;
+
+        /** The mode of the session. Default is 1 = UDEB */
+        TUint32 iIsUdeb;
+    };
+
+#endif      // ATSTORAGESERVERSESSION_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdllinfo.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class TATDllInfo.
+*
+*/
+
+// INCLUDE FILES
+#include "atdllinfo.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::TATDllInfo
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TATDllInfo::TATDllInfo( const TUint32 aStartAddress, const TUint32 aEndAddress,
+	const TInt64& aLoadTime, const TDesC8& aDllName  )
+ :  iStartAddress( aStartAddress ), iEndAddress( aEndAddress ), 
+	iLoadTime( aLoadTime )
+    {
+    LOGSTR3( "STSE TATDllInfo::TATDllInfo() %x - %x", iStartAddress, iEndAddress );
+    
+    iName.Copy( aDllName );
+    }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::StartAddress
+// Returns library start address
+// -----------------------------------------------------------------------------
+//
+TUint32 TATDllInfo::StartAddress()
+    {
+    LOGSTR2( "STSE TATDllInfo::StartAddress( %x )", iStartAddress );
+    
+    return iStartAddress;
+    }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::EndAddress
+// Returns library end address
+// -----------------------------------------------------------------------------
+//
+TUint32 TATDllInfo::EndAddress()
+    {
+    LOGSTR2( "STSE TATDllInfo::EndAddress( %x )", iEndAddress );
+    
+    return iEndAddress;
+    }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::Name
+// Gets specific library name
+// -----------------------------------------------------------------------------
+//
+TDes8& TATDllInfo::Name()
+    {
+    LOGSTR1( "STSE TATDllInfo::Name()" );
+    
+    return iName;
+    }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::LibraryLoadTime
+// Returns library load time
+// -----------------------------------------------------------------------------
+//
+TInt64 TATDllInfo::LibraryLoadTime()
+    {
+    LOGSTR1( "STSE TATDllInfo::LibraryLoadTime()" );
+    
+    return iLoadTime;
+    }
+        
+// -----------------------------------------------------------------------------
+// TATDllInfo::Match
+// Checks if two objects of this class match based on the objects's
+// saved library name.
+// -----------------------------------------------------------------------------
+//
+TBool TATDllInfo::Match( const TATDllInfo& aFirst, const TATDllInfo& aSecond )
+    {
+    LOGSTR1( "STSE TATDllInfo::Match()" );
+    
+    if ( aFirst.iName.Compare( aSecond.iName ) == 0 )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdriveinfo.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class TATDriveInfo.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <f32file.h>
+#include <driveinfo.h>
+#include "atdriveinfo.h"
+#include "atstorageservercommon.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::TATDriveInfo
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TATDriveInfo::TATDriveInfo()
+    {
+    LOGSTR1( "TATD TATDriveInfo::TATDriveInfo()" );
+    }
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::CreatePath()
+// -----------------------------------------------------------------------------
+//    
+TInt TATDriveInfo::CreatePath( TDes& aPath, 
+    const TDesC& aFileName, RFs& aFs )
+    {
+    LOGSTR1( "TATD TInt TATDriveInfo::CreatePath()" );
+    
+    // Drive letter    
+    TChar driveLetter;
+    // Drive number
+    TInt dNumber( EDriveZ );     
+    TBool found( EFalse );
+    // Drive type
+    TUint driveType( KDriveAttRemovable );    
+    TInt err( KErrNotFound );
+    
+    while ( !found )
+        {
+        // Get drive letter
+        if ( GetDrive( driveLetter, dNumber, aFs, driveType ) == KErrNotFound )
+        	{
+        	if ( driveType == KDriveAttInternal )
+        		{
+                return KErrNotFound;
+        		}       	
+            driveType = KDriveAttInternal;
+        	dNumber = EDriveZ;
+        	}       
+        else
+        	{
+			// Create path
+			aPath.Delete( 0, aPath.MaxLength() );
+			aPath.Append( driveLetter );
+		  
+		            
+		#ifdef __WINS__
+            // For emulator the data file is stored to different location
+            aPath.Append( KATDataFilePath );       
+		#else
+		    TDriveInfo driveInfo;
+		    aFs.Drive( driveInfo, dNumber );      
+            // The drive is removable( memory card ) so we can log inside of root folder
+            if ( driveInfo.iDriveAtt & KDriveAttRemovable )
+                {
+                aPath.Append( KATDataFilePath );       
+                }
+            // The drive is internal user can only access data folder so log into that
+            else
+                {
+                aPath.Append( KATDataFilePath2 );       
+                }
+		#endif
+						
+			// Make a directory for AToolStorageServer's logging data file
+			err = aFs.MkDir( aPath );
+			LOGSTR2( "STSE > aFs.MkDir err = %i", err );
+			
+			if ( !err || err == KErrAlreadyExists )
+				{                
+                if ( aFileName.Length() != 0 && 
+                     ( ( aPath.MaxLength() - aPath.Length() ) > aFileName.Length() ) )
+                    {
+                    aPath.Append( aFileName );
+                    }
+				found = ETrue;
+				}
+        	}
+        }        
+    return err;        
+    }
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::GetDrive()
+// -----------------------------------------------------------------------------
+//    
+TInt TATDriveInfo::GetDrive( TChar& aDrive, TInt& aDriveNumber, RFs& aFs, 
+	const TUint aDriveType )
+    {
+    LOGSTR1( "TATD TInt TATDriveInfo::GetDrive()" );
+       
+    // Contains drive information.
+    TDriveInfo driveInfo; 
+    
+    for ( TInt i = aDriveNumber; i >= (TInt)EDriveA; i-- )
+        {
+        // Gets information about a drive and the medium mounted on it.
+        // If error occured then skip to next drive.
+        if ( aFs.Drive( driveInfo, i ) != KErrNone )
+            continue;
+                
+        // Test whether drive is available. If not, skip to next drive.
+        if ( driveInfo.iDriveAtt & KDriveAbsent || i == (TInt)EDriveD ||
+             driveInfo.iDriveAtt & KDriveAttRom || 
+             driveInfo.iMediaAtt & KMediaAttWriteProtected ||
+             driveInfo.iDriveAtt & KDriveFileSysROFS )
+            continue;
+        
+        // Maps a drive number to the corresponding character.
+        if ( aFs.DriveToChar( i, aDrive ) != KErrNone )
+            continue;                
+        
+        if ( driveInfo.iDriveAtt & aDriveType &&
+             driveInfo.iType != EMediaNotPresent &&
+             driveInfo.iType != EMediaCdRom )
+            {
+            TUint status( 0 );
+            
+            switch ( aDriveType )
+                {
+                case KDriveAttRemovable:
+                    {
+                    // Get the drive status of the default removable mass storage.                    
+                    if ( DriveInfo::GetDriveStatus( aFs, i, status ) == KErrNone )
+                        {
+                        // To indicate that the drive is physically removable.
+                        if ( status & DriveInfo::EDriveRemovable &&
+                             !( status & DriveInfo::EDriveCorrupt ) )
+                            {
+                            aDriveNumber = --i;
+                            return KErrNone;
+                            }
+                        }
+                    }
+                    break;
+                case KDriveAttInternal:
+                    {
+                    // Get the drive status of the default removable mass storage.
+                    if ( DriveInfo::GetDriveStatus( aFs, i, status ) == KErrNone )
+                        {
+                        // To indicate that the drive is internal and 
+                        // cannot be physically removed.
+                        if ( status & DriveInfo::EDriveInternal &&
+                             !( status & DriveInfo::EDriveExternallyMountable ) )
+                            {
+                            aDriveNumber = --i;
+                            return KErrNone;
+                            }
+                        }
+                    }
+                    break;
+                    
+                default:
+                    break;
+                }
+            }
+        }
+    return KErrNotFound;
+    }
+ 
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdynprocessinfo.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATDynProcessInfo
+*
+*/
+
+
+// INCLUDE FILES
+#include    "atdynprocessinfo.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//  
+CATDynProcessInfo::CATDynProcessInfo() :
+    iProcessId( KNullProcessId ),
+    iSessionObject( NULL )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//  
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId,
+                                      CATStorageServerSession* aSessionObject,
+                                      const RArray<TATDllInfo>& aDlls ) :
+    iProcessId( aProcessId ),
+    iSessionObject( aSessionObject ),
+    iDlls( aDlls )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//  
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId,
+                                      CATStorageServerSession* aSessionObject ) :
+    iProcessId( aProcessId ), iSessionObject( aSessionObject )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//  
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId ) :
+    iProcessId( aProcessId ), iSessionObject( NULL )
+    {
+    }
+
+// Destructor
+CATDynProcessInfo::~CATDynProcessInfo()
+    {
+    iDlls.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::Compare
+// -----------------------------------------------------------------------------
+//  
+TInt CATDynProcessInfo::Compare( const CATDynProcessInfo& aFirst, 
+	const CATDynProcessInfo& aSecond )
+    {
+    if ( aFirst.iProcessId < aSecond.iProcessId )
+        {
+        return -1;
+        }
+    
+    if ( aFirst.iProcessId > aSecond.iProcessId )
+        {
+        return 1;
+        }
+   
+    // else
+    return 0;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atmemoryentry.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATMemoryEntry
+*
+*/
+
+
+
+// INCLUDE FILES
+#include    "atmemoryentry.h"
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::CATMemoryEntry
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//  
+CATMemoryEntry::CATMemoryEntry( TUint32 aMemAddress,
+                                const CBufFlat* aCallstackBuf,
+                                const TInt64& aAllocTime,
+                                TInt aAllocSize ) :
+    iMemAddress( aMemAddress ),
+    iCallstackBuf( aCallstackBuf ),
+    iAllocTime( aAllocTime ),
+    iAllocSize( aAllocSize )
+    {
+    }
+
+// Destructor
+CATMemoryEntry::~CATMemoryEntry()
+    {
+    delete const_cast<CBufFlat*>( iCallstackBuf );
+    }
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::Compare
+// -----------------------------------------------------------------------------
+//  
+TInt CATMemoryEntry::Compare( const CATMemoryEntry& aFirst, const CATMemoryEntry& aSecond )
+    {
+    if ( aFirst.iAllocTime < aSecond.iAllocTime )
+        {
+        return -1;
+        }
+    
+    if ( aFirst.iAllocTime > aSecond.iAllocTime )
+        {
+        return 1;
+        }
+   
+    // else
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::Match
+// -----------------------------------------------------------------------------
+//
+TBool CATMemoryEntry::Match( const CATMemoryEntry& aFirst, const CATMemoryEntry& aSecond )
+    {
+    if ( aFirst.iMemAddress == aSecond.iMemAddress )
+        {
+        return ETrue;
+        }
+    
+    // else
+    return EFalse;
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atstorageserver.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,452 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions for the class CATStorageServer. Includes also the
+*                entry point of the atoolstorageserver.exe executable.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include    "atstorageserver.h"
+#include    "atstorageserversession.h"
+#include    "atstorageservercommon.h"
+#include    "atlog.h"
+#include    "atdynprocessinfo.h"
+
+
+// CONSTANTS
+
+
+// The amount of different ranges of requests specified for this policy server.
+// In a policy server, different actions can be determined for different ranges
+// of requests.
+const TUint8 KAmountOfRanges = 2;
+
+
+const TInt ranges[KAmountOfRanges] =
+    {
+    CATStorageServer::EProcessStarted,
+    CATStorageServer::EOutOfBounds
+    };
+
+
+const TUint8 actionForRange[ KAmountOfRanges ] = 
+    { 0, CPolicyServer::ENotSupported };
+
+
+const CPolicyServer::TPolicyElement elements[] =
+    {
+    
+    { _INIT_SECURITY_POLICY_C1( ECapability_None ),
+          CPolicyServer::EFailClient }
+    
+    };
+
+
+const CPolicyServer::TPolicy policy =
+    {
+    CPolicyServer::EAlwaysPass, // On connect
+    KAmountOfRanges, // Range count
+    ranges,
+    actionForRange,
+    elements,
+    };
+
+
+
+// ENTRY POINT
+
+TInt E32Main()
+    { 
+    LOGSTR1( "STSE TInt E32Main() in ATStorageServer.cpp" );
+    
+    __UHEAP_MARK;
+    
+    // Create a cleanup stack 
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    
+    TInt errorCode( KErrNoMemory );
+    
+    // If there was enough memory to create a cleanup stack, 
+    // create and start the server.
+    if( cleanup )
+        {
+        // If RunServerL() doesn't leave, errorCode will be set to KErrNone
+        TRAP( errorCode, CATStorageServer::RunServerL() );
+        delete cleanup;
+        }
+
+    // Signal the client that server creation failed, if a leave occured during
+    // the call to 'RunServerL()' function
+    if( errorCode != KErrNone )
+        {
+        RProcess::Rendezvous( errorCode );
+        }
+    
+    __UHEAP_MARKEND;
+       
+    return errorCode;
+    
+    }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::CATStorageServer
+// C++ default constructor can NOT contain any code that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer::CATStorageServer( TInt aPriority ) :
+    CPolicyServer( aPriority, policy, ESharableSessions ),
+    iSessionCount( 0 )
+    {
+    LOGSTR1( "STSE CATStorageServer::CATStorageServer()" );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServer::ConstructL()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer* CATStorageServer::NewL()
+    {
+    CATStorageServer* self = NewLC();
+    CleanupStack::Pop( self );
+    
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer* CATStorageServer::NewLC()
+    {  
+    CATStorageServer* self = new ( ELeave ) CATStorageServer( EPriorityStandard );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    self->StartL( KStorageServerName );
+    return self;
+    }
+
+// Destructor
+CATStorageServer::~CATStorageServer()
+    {
+    LOGSTR1( "STSE CATStorageServer::~CATStorageServer()" );
+    
+    iProcesses.Close();
+    iProcessesDyn.ResetAndDestroy();
+    iProcessesDyn.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewSessionL
+// Create a new server session.
+// -----------------------------------------------------------------------------
+// 
+CSession2* CATStorageServer::NewSessionL(
+    const TVersion &aVersion,
+    const RMessage2& /*aMessage*/ ) const
+    {
+    LOGSTR1( "STSE CSession2* CATStorageServer::NewSessionL()" );
+    
+    // The server's version
+    TVersion version( KVersionNumberMaj, KVersionNumberMin,
+        KVersionNumberBld );
+
+    // Check this is a high enough version of the server
+    if ( !User::QueryVersionSupported(version, aVersion) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    
+    // Construct and return a new session object
+    return CATStorageServerSession::NewL( const_cast<CATStorageServer&>(*this) );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::RunServerL
+// Create active scheduler and a server object
+// -----------------------------------------------------------------------------
+//    
+void CATStorageServer::RunServerL()
+    {
+    LOGSTR1( "STSE void CATStorageServer::RunServerL()" );
+    
+    // Create and install an active scheduler
+    CActiveScheduler* activeSched = new (ELeave) CActiveScheduler;
+    CleanupStack::PushL( activeSched );
+    CActiveScheduler::Install( activeSched );
+
+    // Create server
+    CATStorageServer::NewLC();
+     
+    // The initialization performed alright, signal the client
+    RProcess::Rendezvous( KErrNone );
+
+    // Start the active scheduler
+    CActiveScheduler::Start();
+
+    // Remove the server and active scheduler from the cleanup stack
+    CleanupStack::PopAndDestroy( 2, activeSched );
+    }
+  
+// -----------------------------------------------------------------------------
+// CATStorageServer::IncSessionCount
+// Increments the count of active sessions for this server.
+// -----------------------------------------------------------------------------
+// 
+void CATStorageServer::IncSessionCount()
+    {
+    LOGSTR1( "STSE void CATStorageServer::IncSessionCount()" );
+    
+    iSessionCount++;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServer::DecSessionCount
+// Decrements the count of active sessions for this server.
+// -----------------------------------------------------------------------------
+// 
+void CATStorageServer::DecSessionCount()
+    {
+    LOGSTR1( "STSE void CATStorageServer::DecSessionCount()" );
+       
+    iSessionCount--;
+    
+    // Cancels all outstanding messages and stops the active scheduler,
+    // if there are no other sessions open at the moment
+    if ( iSessionCount <= 0 )
+        {
+        this->Cancel();
+        CActiveScheduler::Stop();
+        }
+    }
+  
+// -----------------------------------------------------------------------------
+// CATStorageServer::AddProcessL
+// -----------------------------------------------------------------------------
+// 
+TInt CATStorageServer::AddProcessL( const TDesC8& aProcessName,
+                                   TUint aProcessId,
+                                   CATStorageServerSession* aSessionObject,
+                                   const TInt64& aStartTime )
+    {
+    LOGSTR1( "STSE TInt CATStorageServer::AddProcessL()" );
+
+    TInt error( KErrNone );
+    TATProcessInfo processInfo;
+    
+    processInfo.iProcessId = aProcessId;
+    processInfo.iProcessName.Copy( aProcessName );
+    processInfo.iStartTime = aStartTime;
+    
+    // Insert the static process info into the iProcesses array
+    error = iProcesses.InsertInUnsignedKeyOrder( processInfo );
+    
+    // Return if an error occured
+    if ( error != KErrNone)
+        {
+        return error;
+        }
+    
+    // Construct a CATDynProcessInfo object with the given process ID and logging mode
+    CATDynProcessInfo* dynProcessInfo = 
+                            new (ELeave) CATDynProcessInfo( aProcessId,
+                                                            aSessionObject );
+    
+    // Insert the dynamic process info into the iProcessesDyn array
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    error = iProcessesDyn.InsertInOrder( dynProcessInfo, order );
+    
+    return error;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServer::RemoveProcessL
+// -----------------------------------------------------------------------------
+// 
+TInt CATStorageServer::RemoveProcessL( TUint aProcessId )
+    {
+    LOGSTR1( "STSE TInt CATStorageServer::RemoveProcessL()" );
+    
+    TATProcessInfo processInfo;
+    processInfo.iProcessId = aProcessId;
+    
+    TInt index = iProcesses.FindInUnsignedKeyOrder( processInfo );
+
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index; 
+        }
+     
+    // Remove the TATProcessInfo object at "index" from the array
+    iProcesses.Remove( index );
+     
+    // Now, start removing the associated dynamic process info object
+
+    // Construct a CATDynProcessInfo object with the given process ID
+    CATDynProcessInfo* dynProcessInfo = 
+                            new (ELeave) CATDynProcessInfo( aProcessId );
+    
+    // Find the index of a CATDynProcessInfo object with the given ID in the array
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+     
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+     
+    // Otherwise, delete the object and remove the pointer at "index"
+    delete iProcessesDyn[index];
+    iProcessesDyn.Remove( index ); 
+     
+    return KErrNone;   
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::AddDllL
+// -----------------------------------------------------------------------------
+// 
+TInt CATStorageServer::AddDllL( TUint aProcessId, 
+    const TATDllInfo aDllInfo )
+    {
+    LOGSTR1( "STSE TInt CATStorageServer::AddDllL()" );
+ 
+    // Construct a CATDynProcessInfo object with the given process ID
+    CATDynProcessInfo* dynProcessInfo = 
+		new (ELeave) CATDynProcessInfo( aProcessId );
+  
+    // Find out if a process with this ID can be found in the dynamic process array
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+     
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+        
+    // If we are here, the wanted process was found at index => append a DLL for it
+    dynProcessInfo = iProcessesDyn[index];
+    
+    // Get the DLL array from this dynamic process info object
+    RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;    
+    
+    // Let's see if the DLL to be added already exists
+    TIdentityRelation<TATDllInfo> matcher( TATDllInfo::Match );
+    index = dllArray.Find( aDllInfo, matcher );
+    
+    // If so, return KErrAlreadyExists
+    if ( index != KErrNotFound )
+        {
+        return KErrAlreadyExists;
+        }
+
+    // Otherwise append this DLL to the array and return 
+    return dynProcessInfo->iDlls.Append( aDllInfo );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::RemoveDllL
+// -----------------------------------------------------------------------------
+// 
+TInt CATStorageServer::RemoveDllL( TUint aProcessId,
+                                  const TDesC8& aDllName )
+    {
+    LOGSTR1( "STSE TInt CATStorageServer::RemoveDllL()" );
+
+    // Construct a CATDynProcessInfo object with the given process ID
+    CATDynProcessInfo* dynProcessInfo = 
+		new (ELeave) CATDynProcessInfo( aProcessId );
+  
+    // Find out if a process with this ID can be found in the dynamic process array
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+     
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+        
+    // If we are here, the wanted process was found at index
+    dynProcessInfo = iProcessesDyn[index];
+
+    // Get the DLL array from this dynamic process info object
+    RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+    
+    // Try to find wanted DLL
+    TIdentityRelation<TATDllInfo> matcher( TATDllInfo::Match );    
+    index = dllArray.Find( TATDllInfo( 0, 0, 0, aDllName  ), matcher );
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+        
+    // Otherwise remove the found DLL at "index"
+    dllArray.Remove( index );    
+        
+    return KErrNone;  
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::ProcessInfoArray
+// -----------------------------------------------------------------------------
+// 
+const RArray<TATProcessInfo>& CATStorageServer::ProcessInfoArray()
+    {
+    LOGSTR1( "STSE RArray<TATProcessInfo>& CATStorageServer::ProcessInfoArray()" );
+     
+    return iProcesses;   
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServer::DynProcessInfoArray
+// -----------------------------------------------------------------------------
+// 
+const RPointerArray<CATDynProcessInfo>& CATStorageServer::DynProcessInfoArray()
+    {
+    LOGSTR1( "STSE RPointerArray<CATDynProcessInfo>& CATStorageServer::DynProcessInfoArray()" );
+     
+    return iProcessesDyn;   
+    }    
+    
+//  End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atstorageserversession.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,3397 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definitions and constants for the class CATStorageServerSession
+*
+*/
+
+
+
+// INCLUDE FILES
+#include    <utf.h>
+#include    <analyzetool/analyzetooltraceconstants.h>
+#include    "atstorageserversession.h"
+#include    "atstorageserver.h"
+#include    "atstorageservercommon.h"
+#include    "atmemoryentry.h"
+#include    "atlog.h"
+#include    "atdynprocessinfo.h"
+#include    "atdriveinfo.h"
+
+// CONSTANTS
+
+// New file name start and end index.
+const TInt KNameIndexStart = 1;
+const TInt KNameIndexEnd = 100;
+
+// ==================== MEMBER FUNCTIONS for TAllocInfo ========================
+
+// -----------------------------------------------------------------------------
+// TAllocInfo::TAllocInfo
+// Implementation for the constructor of the class TAllocInfo
+// -----------------------------------------------------------------------------
+//
+TAllocInfo::TAllocInfo( TUint32 aMemAddress, TInt aAllocSize ) :
+    iMemAddress( aMemAddress ),
+    iAllocSize( aAllocSize )
+    {
+    }
+
+
+// ============== MEMBER FUNCTIONS for CATStorageServerSession =================
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CATStorageServerSession
+// C++ default constructor. It Does not contain any code that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession::CATStorageServerSession( CATStorageServer& aStorageServer ) :
+    iStorageServer( aStorageServer ),
+    iError( 0 ),
+    iLeakArray( KLeakArrayGranularity ),
+    iProcessId( KNullProcessId ),
+    iLoggingOngoing( EFalse ),
+    iLogOption( KDefaultLoggingMode ),
+    iCurAllocSize( 0 ),
+    iMaxAllocs( 0 ),
+    iMaxAllocSize( 0 ),
+    iLogFile( KEmpty() ),
+    iIsUdeb( 1 )
+    {
+    LOGSTR1( "STSE CATStorageServerSession::CATStorageServerSession()" );
+    
+    // Initialize iMicroSecondsAt1970
+    TTime time( KJanuaryFirst1970 );
+    iMicroSecondsAt1970 = time.Int64();
+    
+    // Increment the server's session count by one (1)
+    iStorageServer.IncSessionCount();
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::ConstructL()
+    {
+    // Intentionally left empty
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession* CATStorageServerSession::NewL( CATStorageServer& aStorageServer )
+    { 
+    CATStorageServerSession* self = NewLC( aStorageServer );
+    CleanupStack::Pop( self );
+    
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession* CATStorageServerSession::NewLC( CATStorageServer& aStorageServer )
+    { 
+    CATStorageServerSession* self = new ( ELeave ) CATStorageServerSession( aStorageServer );
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::~CATStorageServerSession
+// Destructor
+// -----------------------------------------------------------------------------
+CATStorageServerSession::~CATStorageServerSession()
+    {
+    LOGSTR1( "STSE CATStorageServerSession::~CATStorageServerSession()" );
+      
+    // Empty the array and delete the referenced objects
+    iLeakArray.ResetAndDestroy();
+  
+    // Close the leak array
+    iLeakArray.Close();
+    
+    // Close the allocation info array
+    iAllocInfoArray.Close();
+    
+    // Check if process closed abnormal
+    if ( iProcessId != KNullProcessId && 
+         iLoggingOngoing && iLogOption != EATLoggingOff && 
+         iError != KErrNoMemory )
+        {
+        LogAbnormalEnd();
+        }
+    
+    // Close the file and the handle to the file server
+    CloseFsAndFile();
+    
+    // Remove the process with the current PID from the server's array of processes
+    TRAP_IGNORE( iStorageServer.RemoveProcessL( iProcessId ) );
+    
+    // Decrement the server's session count by one (1)
+    iStorageServer.DecSessionCount();
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ServiceL
+// This function is called by the client/server framework
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::ServiceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::ServiceL()" );
+    
+    // If logging has been cancelled for this session, return immediately
+    if( iLogOption == EATLoggingOff )
+        {
+        aMessage.Complete( KErrCancel );
+        return;
+        }
+    
+    switch ( aMessage.Function() )
+        {
+        case CATStorageServer::EProcessStarted:
+            {
+            // If logging is not ongoing, set the log option
+            if( !iLoggingOngoing )
+                {
+                // Set the operation mode
+                SetLogOption( aMessage );
+                }
+
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogProcessStartTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogProcessStartedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            } 
+        break;
+        
+        
+        case CATStorageServer::EDllLoaded:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogDllLoadTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogDllLoadedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EDllUnloaded:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogDllUnloadTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogDllUnloadedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EMemoryAllocated:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogMemoryAllocTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogMemoryAllocatedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EMemoryFreed:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogMemoryFreedTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogMemoryFreedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EProcessEnded:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = LogProcessEndTraceL( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = LogProcessEndedL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EMemoryCheck:
+            {
+            switch ( iLogOption )
+                {
+                case EATLogToTrace:
+                    {
+                    iError = CheckMemoryAddressTrace( aMessage );
+                    }
+                break;
+                
+                case EATLogToFile:
+                    {
+                    iError = CheckMemoryAddressL( aMessage );
+                    }
+                break;
+                
+                default:
+                    {
+                    // Panic the client and set iError KErrCancel, because being
+                    // here implies that an illegal log option has been given.
+                    PanicClient( EAToolIllegalLogOption, aMessage );
+                    iError = KErrCancel;
+                    }
+                break;
+                }
+            }
+        break;
+        
+        
+        case CATStorageServer::EGetProcesses:
+            {
+            iError = GetProcessesL( aMessage );
+            }
+        break;
+        
+        
+        case CATStorageServer::EGetDlls:
+            {
+            iError = GetDllsL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::EGetLoggingMode:
+            {
+            iError = GetLoggingModeL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::ESubtestStart:
+            {
+            iError = StartSubtestL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::ESubtestStop:
+            {
+            iError = StopSubtestL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::ESubtestStart2:
+            {
+            iError = StartSubtest2L( aMessage );
+            }
+        break;
+               
+        case CATStorageServer::ESubtestStop2:
+            {
+            iError = StopSubtest2( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::EGetCurrentAllocs:
+            {
+            iError = GetCurrentAllocsL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::EGetMaxAllocs:
+            {
+            iError = GetMaxAllocsL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::ECancelLogging:
+            {
+            iError = CancelLoggingL( aMessage );
+            }
+        break;
+
+        case CATStorageServer::EGetUdeb:
+            {
+            iError = GetUdebL( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::EGetLoggingFile:
+            {
+            iError = GetLoggingFileL( aMessage );
+            }
+        break;
+
+        case CATStorageServer::EProcessUdeb:
+            {
+            SetUdeb( aMessage );
+            }
+        break;
+        
+        case CATStorageServer::EIsMemoryAdded:
+            {
+            iError = IsMemoryAdded( aMessage );
+            LOGSTR2( "STSE > IsMemoryAdded err = %i", iError );
+            }
+        break;       
+        
+        default:
+            {
+            // Panic both the client and server, because being here implies
+            // that there is an internal error in the client/server.
+            PanicClient( EAToolBadRequest, aMessage );
+            StorageServerPanic( KCategoryServer, EAToolBadRequest );
+            }
+        break;
+            
+        }
+    
+    // Complete the message, if it has not been already cancelled.
+    if ( iError != KErrCancel )
+        {
+        // Log the error code. Only KErrNoMemory errors are logged.
+        if ( iLogOption == EATLogToFile && iError == KErrNoMemory  )
+            {
+            HandleError( iError );
+            }
+        else if ( iLogOption == EATLogToTrace && iError == KErrNoMemory )
+            {
+            HandleErrorTrace( iError );
+            }
+               
+        // Complete serving the message 
+        aMessage.Complete( iError );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessStartedL()
+// Opens a logging file with the requested name and then writes information
+// on process start into the file.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessStartedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartedL()" );
+    
+    // Panic the client and return, if this method has already been called for this
+    // session object (and a logging file has been opened)
+    if ( iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    LOGMEM;
+    
+    // READ THE FIRST ARGUMENT (descriptor)  
+    
+    // Length of the first argument (index 0)
+    TInt length = aMessage.GetDesLength( 0 );
+    
+    LOGSTR2( "STSE length of the fileName: %i", length );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+    
+    // Construct a buffer for file name, and leave the pointer on Cleanup Stack
+    HBufC* fileName = HBufC::NewLC( length );
+    TPtr fileNamePtr( fileName->Des() );
+     
+    // Read the client side's descriptor at index 0
+    iError = aMessage.Read( 0, fileNamePtr );
+    
+    if ( iError != KErrNone )
+        {
+        CleanupStack::PopAndDestroy( fileName );
+        return iError;
+        }
+    
+    // READ THE SECOND ARGUMENT (descriptor)  
+    
+    // Length of the second argument (index 1)   
+    length = aMessage.GetDesLength( 1 );
+    
+    LOGSTR2( "STSE length of the processName: %i", length );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        CleanupStack::PopAndDestroy( fileName );
+        return length;
+        }
+    
+    HBufC8* processName = HBufC8::NewL( length );
+    TPtr8 bufPtr( processName->Des() );
+
+    // Read the client side's descriptor at index 1 
+    iError = aMessage.Read( 1, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        delete processName;
+        CleanupStack::PopAndDestroy( fileName );
+        return iError;
+        }
+    
+    // READ THE THIRD ARGUMENT (integer, a process ID)    
+    TInt processId = aMessage.Int2();
+    
+    // Open a file server session and a file. The file
+    // will be opened with the name received from the client
+    iError = OpenFsAndFile( *fileName, *processName );
+    CleanupStack::PopAndDestroy( fileName );
+    // Return without logging, if an error occured
+    if ( iError != KErrNone )
+        {
+        // Delete the local objects
+        delete processName;
+        return iError;
+        }
+    
+    // Get the home time for the configuration UI
+    iTime.HomeTime();
+    
+    // Add the process into the server's array of processes
+    iError = iStorageServer.AddProcessL( *processName,
+                                        processId,
+                                        this,
+                                        iTime.Int64() );
+
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        // Remove, if something was added regardless of the error
+        // However, we must not remove an existing process
+        if ( iError != KErrAlreadyExists )
+            {
+            iStorageServer.RemoveProcessL( processId );
+            }
+        return iError;
+        }
+      
+    // Make a buffer that will be logged into the opened logging file
+    TBuf8<KProcessStartBufLength> loggingBuf;
+    loggingBuf.Format( KProcessStart, processName, processId );
+    
+    delete processName;
+    
+    // Get the current universal time       
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append udeb/urel information to the process start
+    loggingBuf.Append( KSpace );  
+    loggingBuf.AppendNum( iIsUdeb, EHex );
+    
+    // Append trace version information
+    loggingBuf.Append( KSpace );
+    loggingBuf.AppendNum( KATTraceVersion, EHex );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLine );
+    
+    // Write the buffer into the file  
+    iError = iFile.Write( loggingBuf );
+    
+    // Return, if an error occured
+    if ( iError )
+        {
+        iStorageServer.RemoveProcessL( processId );
+        return iError;
+        }
+    
+    LOGMEM;
+    
+    // Set the process ID value for this logging session
+    iProcessId = processId;
+    // Set logging session started
+    iLoggingOngoing = ETrue;
+    
+    return iError;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessStartTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogProcessStartTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartTraceL()" );
+    
+    // Panic the client and return, if this method has already been called for this
+    // session object
+    if ( iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    LOGMEM;
+    
+    // READ THE SECOND ARGUMENT (descriptor)
+    // The first argument, file name, is ignored when logging thru trace  
+    
+    // Length of the second argument (index 1)
+    TInt length = aMessage.GetDesLength( 1 );
+    
+    LOGSTR2( "STSE length of the processName: %i", length );
+
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+
+    HBufC8* processName = HBufC8::NewL( length );
+    TPtr8 bufPtr( processName->Des() );
+
+    // Read the client side's descriptor at index 1 
+    iError = aMessage.Read( 1, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        // Delete local objects and return
+        delete processName;
+        return iError;
+        }
+    
+    // READ THE THIRD ARGUMENT (integer, a process ID)    
+    TInt processId = aMessage.Int2();
+
+    // Get the home time for the configuration UI
+    iTime.HomeTime();
+    
+    // Add the process into the server's array of processes
+    iError = iStorageServer.AddProcessL( *processName, processId, this,
+                                             iTime.Int64() );
+    
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        // Remove, if something was added regardless of the error
+        // However, we must not remove an existing process
+        if ( iError != KErrAlreadyExists )
+            {
+            iStorageServer.RemoveProcessL( processId );
+            }
+        return iError;
+        }
+
+    // Make a buffer that will be logged
+    TBuf8<KProcessStartBufLength> loggingBuf;
+    
+    loggingBuf.Format( KProcessStart, processName, processId );
+    
+    delete processName;
+    
+    // Get the current universal time      
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append udeb/urel information to the process start
+    loggingBuf.Append( KSpace );
+    loggingBuf.AppendNum( iIsUdeb, EHex );
+    
+    // Append version number
+    loggingBuf.Append( KSpace );  
+    loggingBuf.AppendNum( KATTraceVersion, EHex );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLine );
+    
+    // Log to trace
+    TBuf<KProcessStartBufLength> traceBuf;
+    traceBuf.Copy( loggingBuf );
+    RDebug::Print( KTraceMessage, processId ,&traceBuf );
+    
+    LOGMEM;
+    
+    // Set the process ID value for this logging session
+    iProcessId = processId;
+    // Set logging session started
+    iLoggingOngoing = ETrue;
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllLoadedL()
+// Logs to the file opened by the function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllLoadedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadedL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Read the length of the first argument (index 0)   
+    TInt length = aMessage.GetDesLength( 0 );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+    
+    HBufC8* dllName = HBufC8::NewL( length );
+    TPtr8 bufPtr( dllName->Des() );
+
+    // Read the client side's descriptor (the argument 0) 
+    iError = aMessage.Read( 0, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        delete dllName;
+        return iError;
+        }
+    
+    // Get the current universal time
+	TInt64 timeFrom1970( GetTime() );
+        
+    // Add this dll into the server's array
+    TUint32 startAddress( aMessage.Int1() );        
+    TUint32 endAddress( aMessage.Int2() );
+    iError = iStorageServer.AddDllL( iProcessId, 
+    		TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
+    
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        delete dllName;
+        return iError;
+        }
+    
+    // Make a buffer that will be logged into the opened logging file
+    TBuf8<KDllLoadBufLength> loggingBuf;
+    loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
+    
+    delete dllName;
+    
+    // Write the buffer into a file and return the error code   
+    return iFile.Write( loggingBuf );
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllLoadTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogDllLoadTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadTraceL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Read the length of the first argument (index 0)
+    TInt length = aMessage.GetDesLength( 0 );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+    
+    HBufC8* dllName = HBufC8::NewL( length );
+    TPtr8 bufPtr( dllName->Des() );
+
+    // Read the client side's descriptor (the argument 0) 
+    iError = aMessage.Read( 0, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        delete dllName;
+        return iError;
+        }
+    // Get the current universal time
+	TInt64 timeFrom1970( GetTime() );
+    	
+    TUint32 startAddress( aMessage.Int1() );
+    TUint32 endAddress( aMessage.Int2() );
+        
+    // Add this dll into the server's array 
+    iError = iStorageServer.AddDllL( iProcessId, 
+    		TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
+    
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        delete dllName;
+        return iError;
+        }
+    
+    // Make a buffer that will be logged
+    TBuf8<KDllLoadBufLength> loggingBuf;
+    loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
+    
+    delete dllName;
+    
+    TBuf<KDllLoadBufLength> traceBuf;
+    traceBuf.Copy( loggingBuf );
+    RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
+    return iError;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllUnloadedL()
+// Logs to the file opened by the function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllUnloadedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadedL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Read the length of the first argument (index 0)   
+    TInt length = aMessage.GetDesLength( 0 );
+    
+    LOGSTR2( "STSE length %i", length );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+    
+    HBufC8* dllName = HBufC8::NewL( length );
+    TPtr8 bufPtr( dllName->Des() );
+
+    // Read the client side's descriptor (the argument 0) 
+    iError = aMessage.Read( 0, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        delete dllName;
+        return iError;
+        }
+       
+    TUint32 startAddress = aMessage.Int1();
+    TUint32 endAddress = aMessage.Int2();
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+        
+    // Make a buffer that will be logged into the opened logging file
+    TBuf8<KDllUnloadBufLength> loggingBuf;
+    loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
+    
+    // Remove this dll from the server's array
+    iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
+    
+    delete dllName;
+    
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        return iError;
+        }
+     
+    // Write the buffer into a file and return the error code   
+    return iFile.Write( loggingBuf );
+    }
+ 
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllUnloadTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogDllUnloadTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadTraceL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+        
+    iError = KErrNone;
+    
+    // Read the length of the first argument (index 0)   
+    TInt length = aMessage.GetDesLength( 0 );
+    
+    LOGSTR2( "STSE length %i", length );
+    
+    // Return if errors
+    if ( length == KErrArgument || length == KErrBadDescriptor )
+        {
+        return length;
+        }
+    
+    HBufC8* dllName = HBufC8::NewL( length );
+    TPtr8 bufPtr( dllName->Des() );
+
+    // Read the client side's descriptor (the argument 0) 
+    iError = aMessage.Read( 0, bufPtr );
+  
+    if ( iError != KErrNone )
+        {
+        delete dllName;
+        return iError;
+        }
+    
+    TUint32 startAddress = aMessage.Int1();
+    TUint32 endAddress = aMessage.Int2();
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+        
+    // Make a buffer that will be logged
+    TBuf8<KDllUnloadBufLength> loggingBuf;
+    loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
+    
+    // Remove this dll from the server's array
+    iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
+    
+    delete dllName;
+    
+    // Return without logging, if an error occured
+    if ( iError )
+        {
+        return iError;
+        }
+    
+    TBuf<KDllLoadBufLength> traceBuf;
+    traceBuf.Copy( loggingBuf );
+    RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
+    return iError;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryAllocatedL()
+// Constructs a CATMemoryEntry object and appends it into iLeakArray.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryAllocatedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocatedL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }     
+    
+    // A pointer to a buffer of call stack's memory addresses
+    CBufFlat* stackBuf = NULL;
+    
+    iError = KErrNone;
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Read the first argument (index 0)
+    TUint32 memAddress = aMessage.Int0();
+    if ( memAddress == 0 )
+        {
+        return KErrNotSupported;
+        }
+    
+    // Read the length of the descriptor argument (index 1) that should include
+    // call stack memory addresses associated with this memory allocation
+    TInt bufferLength = aMessage.GetDesLength( 1 );
+    
+    // Construct a buffer for aCallstack
+    stackBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( stackBuf );
+    
+    // Buffer position
+    TInt pos = 0;
+    
+    stackBuf->ExpandL( pos, bufferLength );
+
+    TPtr8 bufPtr = stackBuf->Ptr( pos );
+
+    // Read the descriptor argument into the buffer
+    aMessage.ReadL( 1, bufPtr );
+
+    // Read the third argument (index 2) that tells the size of this allocation
+    TInt size = aMessage.Int2();
+    
+    // Construct a new CATMemoryEntry object.   
+    // The ownership of the current stackBuf object is given to the "entry" object.
+    CATMemoryEntry* entry = 
+        new (ELeave) CATMemoryEntry( memAddress, stackBuf, timeFrom1970, size );
+    
+    // Pop stackBuf from CleanupStack and set it to NULL, because it is not used anymore.
+    CleanupStack::Pop( stackBuf );
+    stackBuf = NULL;
+    
+    // Make sure that the same memory area is not tryed to be allocated a second time
+    TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+
+    TInt index = iLeakArray.Find( entry, matcher );
+    
+    if ( index == KErrNotFound )
+        {
+        TLinearOrder<CATMemoryEntry> order( CATMemoryEntry::Compare );
+        
+        // Insert the "entry" object into "iLeakArray". The ownership of
+        // the "entry" object is given to the array.
+        iError = iLeakArray.InsertInOrderAllowRepeats( entry, order );
+               
+        // If an insertion to the array was not successful, delete the created
+        // entry manually and return.
+        if ( iError )
+            {
+            delete entry;
+            return iError;
+            }
+        
+        // Make a TAllocInfo object, and give values for its members.
+        TAllocInfo allocInfo( memAddress, size );
+
+        // Insert the allocInfo object into iAllocInfoArray
+        iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
+    
+        // If an insertion to the array was not successful, delete the created entry
+        // and remove its pointer from iLeakArray.
+        if ( iError )
+            {
+            index = iLeakArray.Find( entry, matcher );
+            // Delete the entry object and remove remove the pointer from the array
+            delete entry;
+            // The index should be in a legal range, because the earlier insertion of
+            // the entry was successful
+            iLeakArray.Remove( index );
+            }
+        
+        // Otherwise update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables
+        
+        iCurAllocSize += size;
+        
+        // The count can never be negative => associate it to an unsigned int
+        TUint allocCount = iAllocInfoArray.Count();
+        if ( allocCount > iMaxAllocs )
+            {
+            iMaxAllocs = allocCount;
+            }
+        
+        if ( iCurAllocSize > iMaxAllocSize )
+            {
+            iMaxAllocSize = iCurAllocSize;
+            }
+        
+        return iError;
+        }
+        
+    // This shouldn't happen, because the same memory area shouldn't be allocated
+    // more than once (without deallocating it first)
+    else
+        {
+        delete entry;
+        return KErrAlreadyExists;
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryAllocTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogMemoryAllocTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    // Read the first argument (index 0)
+    TUint32 memAddress = aMessage.Int0();
+    if ( memAddress == 0 )
+        {
+        return KErrNotSupported;
+        }
+    
+    // Read the third argument (index 2) that tells the size of this allocation
+    TInt size = aMessage.Int2();
+    
+    // Append this allocation into the iAllocInfoArray array. This array is for
+    // providing the configuration UI with information on allocations
+    
+    // Make a TAllocInfo object, and give values for its members.
+    TAllocInfo allocInfo( memAddress, size );
+
+    // Insert the allocInfo object into iAllocInfoArray
+    iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
+    
+    // Log debug message if duplicated allocation.
+    if ( iError == KErrAlreadyExists )
+        {
+        LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL() Error, duplicate allocation :%i", memAddress );
+        }
+
+    // A pointer to a buffer of call stack's memory addresses
+    CBufFlat* stackBuf = NULL;
+    
+    // Get the current universal time           
+    TInt64 timeFrom1970( GetTime() );     
+    
+    // Read the length of the descriptor argument (index 1) that should include
+    // call stack memory addresses associated with this memory allocation
+    TInt bufferLength = aMessage.GetDesLength( 1 );
+    
+    // Construct a buffer for aCallstack
+    stackBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( stackBuf );
+    
+    // Buffer position
+    TInt pos( 0 );    
+    stackBuf->ExpandL( pos, bufferLength );
+    
+    TPtr8 bufPtr = stackBuf->Ptr( pos );
+    
+    // Read the descriptor argument (index 1) into the buffer
+    aMessage.ReadL( 1, bufPtr );
+    
+    // Variable for the number of memory addresses in the call stack
+    TInt addrCount( 0 );    
+    TUint32 callStackAddr;
+    
+    // Read the first word of the buffer. This includes the number of
+    // memory addresses stored in the current stackBuf   
+    stackBuf->Read( pos, &addrCount, KWordSize );
+    
+    // Move the position one word onwards.    
+    pos += KWordSize;
+    
+    // Create a 16-bit buffer, and a pointer descriptor for it    
+    // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count> 
+    // <Call stack address> <Call stack address> ...
+    HBufC* traceBuf = HBufC::NewL( KMemAllocBufLength );
+    TPtr tracePtr( traceBuf->Des() );
+    
+    // Pop stackBuf from CleanupStack, since no leavable operations will be done
+    // anymore
+    CleanupStack::Pop( stackBuf );
+    
+    // Append the tag implying a memory allocation line in the data file
+    tracePtr.Append( KMemoryAllocHeader );
+    
+    // Append the start address of this allocation in the 32-bit (max 8 characters)
+    // hexadecimal text format.
+    tracePtr.AppendNum( memAddress, EHex );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    tracePtr.Append( KSpaceTrace );
+    tracePtr.AppendNum( timeFrom1970, EHex );
+    
+    // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+    // text format.
+    tracePtr.Append( KSpaceTrace );
+    tracePtr.AppendNum( size, EHex );
+    
+    // Append call stack address count
+    tracePtr.Append( KSpaceTrace );
+    tracePtr.AppendNum( addrCount, EHex );
+    
+    // Calculate last item length
+    TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
+            KSpaceLength + KNewlineLength );
+    
+    TUint packetNumber( 1 );
+    
+    // Go through all call stack's memory addresses associated with
+    // this memory allocation 
+    for ( TInt j = 0; j < addrCount; j++ )
+        {
+        // ALLOCF <Memory address> <Time stamp> <Packet number> 
+        // <Call stack address> <Call stack address> ...
+        if ( tracePtr.Length() <= 0 )
+            {                
+            // Create alloc fragment message header
+            tracePtr.Append( KMemoryAllocFragment );
+            tracePtr.AppendNum( memAddress, EHex );
+            tracePtr.Append( KSpaceTrace );
+            tracePtr.AppendNum( timeFrom1970, EHex );
+            tracePtr.Append( KSpaceTrace );        
+            tracePtr.AppendNum( packetNumber, EHex );
+            // Increase packet number
+            packetNumber++;
+            }
+        
+        // Read the next call stack's memory address stored in the buffer.
+        stackBuf->Read( pos, &callStackAddr, KWordSize );
+        
+        // Append the read memory address as a hexadecimal number
+        tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
+        
+        // Move the pos variable one word onwards.
+        pos += KWordSize;
+        
+        // Check if buffer max length exceed
+        if ( lastItemLength + tracePtr.Length() >= KMemAllocBufLength )
+            {
+            tracePtr.Append( KNewLineTrace );
+            // Log through debug channel 
+            RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+            // Empty trace buffer
+            tracePtr.Delete( 0, tracePtr.MaxLength() );
+            }
+        }
+    
+    // Send the last message if exists
+    if ( tracePtr.Length() > 0 )
+        {
+        tracePtr.Append( KNewLineTrace );
+        
+        // Log through debug channel 
+        RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+        }
+    
+    delete traceBuf;
+    delete stackBuf;
+    
+    // Update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables            
+    iCurAllocSize += size;
+    
+    // The count can never be negative => associate it to an unsigned int
+    TUint allocCount = iAllocInfoArray.Count();
+    if ( allocCount > iMaxAllocs )
+        {
+        iMaxAllocs = allocCount;
+        }
+    
+    if ( iCurAllocSize > iMaxAllocSize )
+        {
+        iMaxAllocSize = iCurAllocSize;
+        }
+    
+    return KErrNone;    
+    }    
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryFreedL()
+// Removes a TATMemoryEntry object with the specified memory address from 
+// iLeakArray, if found.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryFreedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    // Get the memory address
+    TUint32 memAddress = aMessage.Int0();
+    
+    // Remove this memory allocation from the leak array
+    TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+    CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
+    TInt index = iLeakArray.Find( entry, matcher );
+    delete entry;
+    
+    // Return, if the requested memory address was not found
+    // (had not been allocated)
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Delete the CATMemoryEntry object at "index" and remove from the array
+    delete iLeakArray[index];
+    iLeakArray.Remove( index );
+    
+    // Remove this memory allocation also from the allocation info array
+    // Make a TAllocInfo object for a "find" operation
+    TAllocInfo allocInfo( memAddress, 0 );
+    index = iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo );
+    
+    // The index should not be KErrNotFound, because an object with this memory address
+    // was found in the iLeakArray array. If the index is out of range, something is
+    // badly wrong, so it would be alright to panic in that case.
+    if ( index == KErrNotFound )
+        {
+        PanicClient( EAToolInternalError, aMessage );
+        return KErrCancel;
+        }
+    
+    // Decrease the current alloc size and remove the requested allocation
+    // from iAllocInfoArray
+    iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+    iAllocInfoArray.Remove( index );
+    
+    // If we are here, everything has gone alright
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::IsMemoryAdded()
+// Check a memory allocation (memory address) from an internal array.
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::IsMemoryAdded( const RMessage2& aMessage, 
+    const TBool aRemoveAlloc )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::IsMemoryAdded()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+        
+    // Read the first argument (index 0)
+    TUint32 memAddress = aMessage.Int0();
+    
+    // Try to find this memory allocation from the allocation info array
+    
+    // Make a TAllocInfo object for a "find" operation
+    TAllocInfo allocInfo( memAddress, 0 );
+    TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
+    
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    else if ( aRemoveAlloc )
+        {
+        // Otherwise decrease the current alloc size and remove the requested allocation
+        // from iAllocInfoArray
+        iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+        iAllocInfoArray.Remove( index );
+        }
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryFreedTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogMemoryFreedTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedTraceL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    // A pointer to a buffer of call stack's memory addresses
+    CBufFlat* stackBuf = NULL;        
+    iError = KErrNone;    
+    
+    // Read the first argument (index 0)
+    TUint32 memAddress = aMessage.Int0();
+
+    // Remove address from allocation table and its size from alloc size,
+    // if found from table.
+    TAllocInfo allocInfo( memAddress, 0 ); // Dummy info for search.
+    TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
+    if ( index != KErrNotFound )
+        {
+        // Decrease the current alloc size and remove the requested allocation
+        // from table.
+        iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+        iAllocInfoArray.Remove( index );
+        }
+    else
+        {
+        LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryFreedTrace() Error, cannot find alloc for free: %i", memAddress );
+        }
+    
+    // Read the length of the descriptor argument (index 1) that should include
+    // call stack memory addresses associated with this memory allocation
+    TInt bufferLength = aMessage.GetDesLength( 1 );
+    
+    // Construct a buffer for aCallstack
+    stackBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( stackBuf );
+    
+    // Buffer position
+    TInt pos = 0;
+    
+    stackBuf->ExpandL( pos, bufferLength );
+
+    TPtr8 bufPtr = stackBuf->Ptr( pos );
+
+    // Read the descriptor argument (index 1) into the buffer
+    aMessage.ReadL( 1, bufPtr );
+    
+    // Variable for the number of memory addresses in the call stack
+    TInt addrCount( 0 );    
+    TUint32 callStackAddr( 0 );
+
+    // Read the first word of the buffer. This includes the number of
+    // memory addresses stored in the current stackBuf
+    stackBuf->Read( pos, &addrCount, KWordSize );
+
+    // Move the position one word onwards.
+    pos += KWordSize;
+    
+    // Create a 16-bit buffer, and a pointer descriptor for it
+    HBufC* traceBuf = HBufC::NewL( KMemFreedBufLength );
+    TPtr tracePtr( traceBuf->Des() );
+    
+    // Pop stackBuf from CleanupStack, since no leavable operations will be done
+    // anymore
+    CleanupStack::Pop( stackBuf );
+    
+	// Get the current universal time		
+	TInt64 timeFrom1970( GetTime() );
+			
+    // Memory deallocation header message.
+    // FREEH <Memory address> <Time stamp> <Call stack address count> <Call stack address>
+    // <Call stack address> ...
+
+    // Append the tag implying a memory free line in the data file
+    tracePtr.Append( KMemoryFreedHeader );
+    
+    // Append the start address of this allocation in the 32-bit (max 8 characters)
+    // hexadecimal text format.
+    tracePtr.AppendNum( memAddress, EHex );    
+    
+	// Append the current time in the 64-bit (max 16 characters) hexadecimal text
+	// format
+	tracePtr.Append( KSpaceTrace );
+	tracePtr.AppendNum( timeFrom1970, EHex );
+			
+    // Append call stack address count
+    tracePtr.Append( KSpaceTrace );
+    tracePtr.AppendNum( addrCount, EHex );
+    
+    // Packet number
+    TUint packetNumber( 1 );
+    
+    // Calculate last item length
+    TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + 
+            KSpaceLength + KNewlineLength );
+    
+    // Go through all call stack's memory addresses associated with
+    // this memory allocation 
+    for ( TInt j = 0; j < addrCount; j++ )
+        {
+        if ( tracePtr.Length() <= 0 )
+            {
+            // Memory deallocation fragment message.
+            // FREEF <Memory address> <Time stamp> <Packet number> <Call stack address count>
+            // <Call stack address>...
+            // Create free fragment message header
+            tracePtr.Append( KMemoryFreedFragment );
+            tracePtr.AppendNum( memAddress, EHex );
+            tracePtr.Append( KSpaceTrace );    
+			tracePtr.AppendNum( timeFrom1970, EHex );
+			tracePtr.Append( KSpaceTrace );	
+            tracePtr.AppendNum( packetNumber, EHex );
+            // Increase packet number
+            packetNumber++;
+            }
+        
+        // Read the next call stack's memory address stored in the buffer.
+        stackBuf->Read( pos, &callStackAddr, KWordSize );
+        
+        // Append the read memory address as a hexadecimal number
+        tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
+        
+        // Move the pos variable one word onwards.
+        pos += KWordSize;
+        
+        // Check if buffer max length exceed
+        if ( lastItemLength + tracePtr.Length() >= KMemFreedBufLength )
+            {
+            tracePtr.Append( KNewLineTrace );
+            // Log through debug channel 
+            RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+            // Empty trace buffer
+            tracePtr.Delete( 0, tracePtr.MaxLength() );
+            }
+        }
+    
+    // Send the last message if exists
+    if ( tracePtr.Length() > 0 )
+        {
+        tracePtr.Append( KNewLineTrace );
+        
+        // Log through debug channel 
+        RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+        }
+        
+    delete traceBuf;
+    delete stackBuf;
+    // If we are here, everything has gone alright
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessEndedL()
+// Prints memory leaks and information on process end into a file opened by the
+// function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessEndedL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Read the sent process ID
+    TUint processId = aMessage.Int0();
+ 
+    // The process ID got from the client should equal iProcessId.
+    // If it does not, return KErrNotSupported
+    if ( processId != iProcessId )
+        {
+        return KErrNotSupported;
+        }
+    
+    //////////////////////////////////////////////
+    // Log memory leaks
+    //////////////////////////////////////////////  
+    
+    // Print the information on the memory allocations that were never freed
+    iError = PrintLeaksL( aMessage );
+    
+    if ( iError != KErrNone )
+        {
+        return iError;
+        }    
+    
+    //////////////////////////////////////////////
+    // Log handle leaks
+    ////////////////////////////////////////////// 
+
+    TUint handleLeakCount = aMessage.Int1();
+    
+    if( handleLeakCount == 0 )
+        {
+        LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL() No handle leaks to report" );
+        }
+    else
+        {
+        // Make a buffer that will be logged
+        TBuf8<KHandleLeakBufLength> loggingBuf;
+        
+        // Set handle leak module name to unknown since it can not be defined.
+        // Write the handle leak count from aMessage.
+        loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
+    
+        // Write the constructed string into the data file and return if error
+        iError = iFile.Write( loggingBuf );
+    
+        if ( iError != KErrNone )
+            {
+            return iError;
+            }
+        }
+    
+    //////////////////////////////////////////////
+    // Log process end
+    //////////////////////////////////////////////
+           
+    // Make a buffer that will be logged into the opened logging file
+    TBufC8<KProcessEndBufLength> processEndBuf;
+    
+    TPtr8 bufPtr = processEndBuf.Des();
+    
+    bufPtr.AppendFormat( KProcessEnd, iProcessId );
+    
+    // Get the current universal time       
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format         
+    bufPtr.AppendNum( timeFrom1970, EHex );
+    
+    // Append a new line
+    bufPtr.Append( KNewLine );
+    
+    // Write the buffer into a file and return the error code   
+    iError = iFile.Write( processEndBuf );
+    
+    // Close the file and the handle to the file server
+    CloseFsAndFile();
+    
+    // Remove the process from the server's array of processes
+    iError = iStorageServer.RemoveProcessL( processId );
+    
+    // Reset iProcesssId and set the logging flag false
+    iProcessId = KNullProcessId;
+    iLoggingOngoing = EFalse;
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessEndTraceL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::LogProcessEndTraceL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Read the sent process ID
+    TUint processId = aMessage.Int0();
+ 
+    // The process ID got from the client should equal iProcessId.
+    // If it does not, return KErrNotSupported
+    if ( processId != iProcessId )
+        {
+        return KErrNotSupported;
+        }
+    
+    //////////////////////////////////////////////
+    // Log handle leaks
+    ////////////////////////////////////////////// 
+
+    TUint handleLeakCount = aMessage.Int1();
+
+    if( handleLeakCount == 0 )
+        {
+        LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL() No handle leaks to report" );
+        }
+    else
+        {
+        // Make a buffer that will be logged
+        TBuf8<KHandleLeakBufLength> loggingBuf;
+        
+        // Make a 16-bit buffer that can be logged using RDebug
+        TBuf<KHandleLeakBufLength> traceBuf;
+        
+        // Set handle leak module name to unknown since it can not be defined.
+        // Write the handle leak count from aMessage.
+        loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
+        
+        traceBuf.Copy( loggingBuf );
+    
+        // Log through debug channel 
+        RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
+        }
+
+    //////////////////////////////////////////////
+    // Log process end
+    //////////////////////////////////////////////
+    
+    // Make a buffer that will be logged
+    TBuf<KProcessEndBufLength> processEndBuf;    
+    processEndBuf.AppendFormat( KProcessEndTrace, iProcessId );
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    processEndBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a new line
+    processEndBuf.Append( KNewLineTrace );
+    
+    // Log through debug channel
+    RDebug::Print( KTraceMessage, iProcessId, &processEndBuf );
+
+    // Remove the process from the server's array of processes
+    iError = iStorageServer.RemoveProcessL( iProcessId );
+
+    // Reset iProcesssId and set the logging flag false
+    iProcessId = KNullProcessId;
+    iLoggingOngoing = EFalse;
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckMemoryAddressL()
+// Checks if given memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::CheckMemoryAddressL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressL()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    iError = KErrNone;
+    
+    // Check if memory address can be found in iLeakArray
+    TUint32 memAddress = aMessage.Int0();
+    TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+    CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
+    
+    // Get the index or an error code
+    iError = iLeakArray.Find( entry, matcher );
+    delete entry;
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckMemoryAddressTrace()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::CheckMemoryAddressTrace( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressTrace()" );
+    
+    // Panic the client and return, if a logging session is not ongoing
+    // ( can be started by calling the client's LogProcessStarted() )
+    if ( !iLoggingOngoing )
+        {
+        PanicClient( EAToolNotAllowed, aMessage );
+        return KErrCancel;
+        }
+    
+    // Always return KErrNone in this mode
+    return KErrNone;
+    }
+ 
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetProcessesL()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetProcessesL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetProcessesL()" );
+    
+    iError = KErrNone;
+    
+    TInt processInfoSize = sizeof( TATProcessInfo );
+    
+    CBufFlat* processInfoBuf;
+    
+    // Buffer position
+    TInt pos( 0 );
+    
+    // Calculate the length of the buffer to be constructed for processes
+    // One word will be reserved for the length of the array.
+    TInt bufferLength = KWordSize + KATMaxProcesses * processInfoSize;
+    
+    // Construct processInfoBuf and expand it before the beginning (index 0)
+    processInfoBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( processInfoBuf );
+    processInfoBuf->ExpandL( pos, bufferLength );
+    
+    RArray<TATProcessInfo> processArray = iStorageServer.ProcessInfoArray();
+
+    // Variable for the number of TATProcessInfo objects in processArray
+    TInt count = processArray.Count();
+    
+    // The count cannot be greater than KATMaxProcesses, because the client
+    // has reserved a buffer of this size to be filled by the server
+    if ( count > KATMaxProcesses )
+        {
+        count = KATMaxProcesses;
+        }
+
+    // Write the count (4 bytes) into the beginning of processInfoBuf
+    processInfoBuf->Write( pos, &count, KWordSize );
+    
+    // Move the position one word onwards.    
+    pos += KWordSize;
+    
+    // Write all the process info objects into the buffer 
+    for ( TInt i = 0; i < count; i++ )
+        {
+        TATProcessInfo& processInfo = processArray[i];
+        
+        // Write the current process info into the buffer
+        processInfoBuf->Write( pos, &processInfo, processInfoSize );
+        
+        // Move the pos variable onwards.
+        pos += processInfoSize;
+        }
+    
+    // Make a pointer descriptor pointing to the start of processInfoBuf
+    TPtr8 bufPtr( processInfoBuf->Ptr(0) );
+    
+    // Write the buffer into aMessage at index 0 for the client
+    aMessage.WriteL( 0, bufPtr );
+    
+    CleanupStack::PopAndDestroy( processInfoBuf );
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetDllsL()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetDllsL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetDllsL()" );
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Size of a DLL descriptor
+    TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> );
+    
+    // Buffer position
+    TInt pos( 0 );
+    
+    // Calculate the length of the buffer to be constructed for DLL names.
+    // One word will be reserved for the length of the array.
+    TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc;
+    
+    CBufFlat* dllBuf;
+    // Construct dllBuf and expand it before the beginning (index 0)
+    dllBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( dllBuf );
+    dllBuf->ExpandL( pos, bufferLength );
+
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        CleanupStack::PopAndDestroy( dllBuf );
+        return index;
+        }
+    
+    // Get the wanted dynamic process info 
+    dynProcessInfo = dynProcessArray[index];
+ 
+    // Fetch a reference to the desired DLL array
+    RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+    
+    // Take the count of names in the array 
+    TInt count = dllArray.Count();
+
+    // The count cannot be greater than KATMaxDlls, because the client
+    // has reserved a buffer of this size to be filled by the server
+    if ( count > KATMaxDlls )
+        {
+        count = KATMaxDlls;
+        }
+
+    // Write the count (4 bytes) into the beginning of dllBuf
+    dllBuf->Write( pos, &count, KWordSize );
+    
+    // Move the position one word onwards.
+    pos += KWordSize;
+
+    // Go through all DLL names objects sent to the server 
+    for ( TInt i = 0; i < count; i++ )
+        {
+        TBuf8<KMaxLibraryName>& dllName = dllArray[i].iName;
+        
+        // Write the current DLL name into the buffer
+        dllBuf->Write( pos, &dllName, sizeOfDllDesc );
+        
+        // Move the pos variable onwards.
+        pos += sizeOfDllDesc;
+        }  
+    
+    // Make a pointer descriptor pointing to the start of dllBuf
+    TPtr8 bufPtr( dllBuf->Ptr(0) );
+    
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, bufPtr );
+    
+    CleanupStack::PopAndDestroy( dllBuf );
+
+    // The dynProcessInfo object will not be deleted, because it is still owned by the
+    // server object's dynamic process info array.  
+    dynProcessInfo = NULL;
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetLoggingModeL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::GetLoggingModeL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingModeL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Buffer position
+    TInt pos( 0 );
+    
+    // The length of the buffer to be constructed for logging mode
+    TInt bufferLength = KWordSize;
+    
+    // Get the dynamic process info array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+
+    // Get the desired process's associated session object
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+    CBufFlat* loggingModeBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    loggingModeBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( loggingModeBuf );
+    loggingModeBuf->ExpandL( 0, bufferLength );
+    
+    // Write the current logging mode of the requested process into the buffer.
+    loggingModeBuf->Write( pos, &sessionObject->iLogOption, KWordSize );
+    
+    // Make a pointer descriptor that points to the data of allocInfoBuf
+    TPtr8 bufPtr( loggingModeBuf->Ptr(0) );
+    
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, bufPtr );
+    
+    CleanupStack::PopAndDestroy( loggingModeBuf );
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StartSubtestL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::StartSubtestL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtestL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Read the sub test ID at index 1
+    TBuf8<KATMaxSubtestIdLength> subTestName;
+    iError = aMessage.Read( 1, subTestName );
+    
+    // Return if reading was not successful
+    if ( iError != KErrNone )
+        {
+        return iError;
+        }
+    
+    // Create another (non-8-bit) descriptor for logging to trace
+    // and copy the contents
+    TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+    subTestNameTrace.Copy( subTestName );
+
+    // Read the handle count at index 2
+    TInt handleCount = aMessage.Int2();
+    
+    // FIND THE REQUESTED PROCESS
+    
+    // Get the dynamic process array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+    
+    // Get the desired process's associated session object
+    const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+  
+    // Make a buffer for logging thru trace
+    TBuf<KTestStartBufLength> loggingBuf;
+    
+    // Copy the line tag into the buffer  
+    loggingBuf.Copy( KSubtestStart );
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append the sub test ID
+    loggingBuf.Append( subTestNameTrace );
+
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append current handle leak count
+    loggingBuf.AppendNum( handleCount );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLineTrace );
+    
+    // Log the string through trace
+    iError = sessionObject->LogThroughTrace( loggingBuf );
+        
+    // *******************
+    // Send loaded DLL's
+    // *******************
+    
+    // Fetch a reference to the desired DLL array
+	RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+	
+	// Take the count of dll info items
+	TInt count( dllArray.Count() );
+	LOGSTR2( "STSE > dllArray.Count( %i )", count );
+	
+	// Create buffers
+	TBuf<KDllLoadBufLength> traceBuf;
+	TBuf8<KDllLoadBufLength> dllBuf;
+	
+	for ( TInt x = 0; x < count; x++ )
+		{
+		dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
+				dllArray[x].iStartAddress, dllArray[x].iEndAddress );
+		traceBuf.Copy( dllBuf );
+		
+		// Log the string through trace
+		iError = sessionObject->LogThroughTrace( traceBuf );
+		if ( iError != KErrNone )
+			{
+			LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
+			}
+		}
+    sessionObject = NULL;
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StopSubtestL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StopSubtestL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtestL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Read the sub test ID at index 1
+    TBuf8<KATMaxSubtestIdLength> subTestName;
+    iError = aMessage.Read( 1, subTestName );
+    
+    // Return if reading was not successful
+    if ( iError != KErrNone )
+        {
+        return iError;
+        }
+
+    // Create another (non-8-bit) descriptor for logging to trace,
+    // and copy the contents
+    TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+    subTestNameTrace.Copy( subTestName );
+
+    // Read the handle count at index 2
+    TInt handleCount = aMessage.Int2();
+    
+    // FIND THE REQUESTED PROCESS
+    
+    // Get the dynamic process array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+    
+    // Get the desired process's associated session object
+    const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+  
+    // Make a buffer for logging thru trace
+    TBuf<KTestEndBufLength> loggingBuf;
+    
+    // Copy the line tag into the buffer  
+    loggingBuf.Copy( KSubtestEnd );
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append the sub test ID
+    loggingBuf.Append( subTestNameTrace );
+
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append current handle leak count
+    loggingBuf.AppendNum( handleCount );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLineTrace );
+    
+    // Log the string through trace
+    iError = sessionObject->LogThroughTrace( loggingBuf );
+    
+    sessionObject = NULL;
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StartSubtest2L()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::StartSubtest2L( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtest2L()" );
+    
+    iError = KErrNone;
+    
+    // Read the sub test ID at index 0
+    TBuf8<KATMaxSubtestIdLength> subTestName;
+    iError = aMessage.Read( 0, subTestName );
+    
+    // Return if reading was not successful
+    if ( iError != KErrNone )
+        {
+        return iError;
+        }
+    
+    // Create another (non-8-bit) descriptor for logging to trace
+    // and copy the contents
+    TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+    subTestNameTrace.Copy( subTestName );
+
+    // Make a buffer for logging thru trace
+    TBuf<KTestStartBufLength> loggingBuf;
+    
+    // Copy the line tag into the buffer  
+    loggingBuf.Copy( KSubtestStart );
+    
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append the sub test ID
+    loggingBuf.Append( subTestNameTrace );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLineTrace );
+    
+    // Log the string through trace
+    iError = LogThroughTrace( loggingBuf );
+    
+    // *******************
+	// Send loaded DLL's
+	// *******************
+	
+    // Get the dynamic process array
+	RPointerArray<CATDynProcessInfo> dynProcessArray =
+		iStorageServer.DynProcessInfoArray();
+	
+	// Construct a CATDynProcessInfo object with the given process ID for searching
+	CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( iProcessId );
+	
+	// Find the index of a CATDynProcessInfo object with the given process ID
+	TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+	TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+	delete dynProcessInfo;
+	dynProcessInfo = NULL;
+	 
+	// Return, if a process with the requested process ID was not found
+	if ( index == KErrNotFound )
+		{
+		return index;
+		}
+	
+	// Get the wanted dynamic process info
+	dynProcessInfo = dynProcessArray[index];
+        
+	// Fetch a reference to the desired DLL array
+	RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+	
+	// Take the count of dll info items
+	TInt count( dllArray.Count() );
+	LOGSTR2( "STSE > dllArray.Count( %i )", count );
+	
+	// Create buffers
+	TBuf<KDllLoadBufLength> traceBuf;
+	TBuf8<KDllLoadBufLength> dllBuf;
+	
+	for ( TInt x = 0; x < count; x++ )
+		{
+		dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
+				dllArray[x].iStartAddress, dllArray[x].iEndAddress );
+		traceBuf.Copy( dllBuf );
+		
+		// Log the string through trace
+		iError = LogThroughTrace( traceBuf );
+		if ( iError != KErrNone )
+			{
+			LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
+			}
+		}
+    	
+    return iError;
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StopSubtest2()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StopSubtest2( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtest2()" );
+    
+    iError = KErrNone;
+    
+    // Read the sub test ID at index 0
+    TBuf8<KATMaxSubtestIdLength> subTestName;
+    iError = aMessage.Read( 0, subTestName );
+    
+    // Return if reading was not successful
+    if ( iError != KErrNone )
+        {
+        return iError;
+        }
+
+    // Create another (non-8-bit) descriptor for logging to trace,
+    // and copy the contents
+    TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+    subTestNameTrace.Copy( subTestName );
+
+    // Make a buffer for logging thru trace
+    TBuf<KTestEndBufLength> loggingBuf;
+    
+    // Copy the line tag into the buffer  
+    loggingBuf.Copy( KSubtestEnd );
+    
+    // Get the current universal time    
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    loggingBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a space
+    loggingBuf.Append( KSpaceTrace );
+    
+    // Append the sub test ID
+    loggingBuf.Append( subTestNameTrace );
+    
+    // Append a new line
+    loggingBuf.Append( KNewLineTrace );
+    
+    // Log the string through trace
+    iError = LogThroughTrace( loggingBuf );
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetCurrentAllocsL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::GetCurrentAllocsL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetCurrentAllocsL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    TUint32 allocNumber( 0 );
+    TUint32 allocSize( 0 );
+    
+    // Buffer position
+    TInt pos( 0 );
+    
+    // The length of the buffer to be constructed for allocation number and size
+    TInt bufferLength = KWordSize + KWordSize;
+    
+    // Get the dynamic process info array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+
+    // Get the desired process's associated session object
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+    
+    // Get the alloc info array of that session object
+    RArray<TAllocInfo> allocInfo = sessionObject->AllocInfoArray();
+    
+    // Get the values for current allocations number and size
+    allocNumber = allocInfo.Count();
+    
+    // Calculate the total size of the current allocations
+    for ( TUint32 i = 0; i < allocNumber; i++ )
+        {
+        allocSize += allocInfo[i].iAllocSize;
+        }
+    
+    LOGSTR2( "STSE allocSize: %u", allocSize );
+    LOGSTR2( "STSE iCurAllocSize: %u", iCurAllocSize );
+    
+    CBufFlat* allocInfoBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    allocInfoBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( allocInfoBuf );
+    allocInfoBuf->ExpandL( 0, bufferLength );
+    
+    // Write the current number of allocations of the requested process into the buffer.
+    allocInfoBuf->Write( pos, &allocNumber, KWordSize );
+    
+    // Move the position one word onwards
+    pos += KWordSize;
+    
+    // Write the current total size of the allocations of the requested process into the
+    // buffer.
+    allocInfoBuf->Write( pos, &allocSize, KWordSize );
+    
+    // Make a pointer descriptor that points to the data of allocInfoBuf
+    TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+    
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, bufPtr );
+    
+    CleanupStack::PopAndDestroy( allocInfoBuf );
+                    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetMaxAllocsL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::GetMaxAllocsL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetMaxAllocsL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    TUint32 allocNumber( 0 );
+    TUint32 allocSize( 0 );
+    
+    // Buffer position
+    TInt pos( 0 );
+    
+    // The length of the buffer to be constructed for allocation number and size
+    TInt bufferLength = KWordSize + KWordSize;
+    
+    // Get the dynamic process info array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info 
+    dynProcessInfo = dynProcessArray[index];
+
+    // Get the desired process's associated session object
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+    
+    // Get values for the maximum allocations number and size
+    allocNumber = sessionObject->iMaxAllocs;
+    allocSize = sessionObject->iMaxAllocSize;
+    
+    CBufFlat* allocInfoBuf;
+    // Construct allocInfoBuf and expand it before the beginning (index 0)
+    allocInfoBuf = CBufFlat::NewL( bufferLength );
+    CleanupStack::PushL( allocInfoBuf );
+    allocInfoBuf->ExpandL( 0, bufferLength );
+    
+    // Write the maximum number of allocations of the requested process into the buffer.
+    allocInfoBuf->Write( pos, &allocNumber, KWordSize );
+    
+    // Move the position one word onwards
+    pos += KWordSize;
+    
+    // Write the maximum total size of the allocations of the requested process into the
+    // buffer.
+    allocInfoBuf->Write( pos, &allocSize, KWordSize );
+    
+    // Make a pointer descriptor that points to the data of allocInfoBuf
+    TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+    
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, bufPtr );
+    
+    CleanupStack::PopAndDestroy( allocInfoBuf );
+                    
+    return iError;
+    }
+  
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CancelLoggingL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::CancelLoggingL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::CancelLoggingL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+        
+    // FIND THE REQUESTED PROCESS
+    
+    // Get the dynamic process array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+     
+    // Return, if a process with the requested process ID was not found
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+    
+    // Get the session object of the requested process
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+      
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+    
+    // Make a buffer for logging "logging cancelled"
+    TBuf8<KCancelBufLength> loggingBuf;
+    
+    // Copy the "logging cancelled" tag into the buffer with the current time 
+    loggingBuf.AppendFormat( KLoggingCancelled, timeFrom1970 );
+    
+    // Log the buffer eather to a file or to debug channel depending on the current
+    // logging mode
+    
+    if ( sessionObject->iLoggingOngoing && 
+         sessionObject->iLogOption == EATLogToFile )
+        {
+        // Write the buffer into the file  
+        sessionObject->iFile.Write( loggingBuf );
+        }
+    
+    else if ( sessionObject->iLoggingOngoing &&
+              sessionObject->iLogOption == EATLogToTrace )
+        {
+        // Make a buffer for logging to trace
+        TBuf<KCancelBufLength> traceBuf;
+        traceBuf.Copy( loggingBuf );
+        
+        // Write the buffer into the debug channel
+        RDebug::Print( KTraceMessage, processId ,&traceBuf );
+        }
+    
+    // Switch off logging of the requested process 
+    sessionObject->iLogOption = EATLoggingOff;
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::HandleError
+// Internally used for handling error situations.
+// -----------------------------------------------------------------------------
+// 
+void CATStorageServerSession::HandleError( TInt aError )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::HandleError()" );
+      
+    // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+        
+    // Make a buffer that will be logged into the opened logging file
+    TBufC8<KErrOccuredBufLength> loggingBuf;
+    
+    TPtr8 bufPtr( loggingBuf.Des() );
+     
+    // Write the error code to the buffer  
+    bufPtr.Format( KErrorOccured, aError );
+       
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    bufPtr.AppendNum( timeFrom1970, EHex );
+    
+    // Append a new line
+    bufPtr.Append( KNewLine );
+            
+    // Write the buffer into a file (if possible in the current condition)
+    iFile.Write( loggingBuf );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::HandleErrorTrace()
+// Internally used for handling error situations.
+// -----------------------------------------------------------------------------
+//    
+void CATStorageServerSession::HandleErrorTrace( TInt aError )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::HandleErrorTrace()" );
+    
+     // Get the current universal time
+    TInt64 timeFrom1970( GetTime() );
+        
+    // Make a buffer that will be logged
+    TBuf<KErrOccuredBufLength> traceBuf;
+     
+    // Write the error code to the buffer  
+    traceBuf.Format( KErrorOccuredTrace, aError );
+       
+    // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+    // format
+    traceBuf.AppendNum( timeFrom1970, EHex );
+    
+    // Append a new line
+    traceBuf.Append( KNewLineTrace );
+                 
+    RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::OpenFsAndFile
+// Internally used for opening a handle to the file server and a file
+// -----------------------------------------------------------------------------
+// 
+TInt CATStorageServerSession::OpenFsAndFile( const TDesC& aFileName, 
+    const TDesC8& aProcessName )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::OpenFsAndFile()" );
+    
+    // Connect file server, return if error occured
+    iError = iFileServer.Connect();
+    if ( iError )
+        {
+        iFileServer.Close();
+        return iError;
+        }
+
+    // Open a file
+    TBuf<KMaxFileName> fileNameBuf;    
+    iError = TATDriveInfo::CreatePath( fileNameBuf, aFileName, iFileServer );
+                        
+    // Return, if an error occured, and it
+    // is not KErrAlreadyExists
+    if ( iError && iError != KErrAlreadyExists )
+        {
+        iFileServer.Close();
+        return iError;
+        }
+    
+    // Save the file name for this session
+    CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
+        
+    // Try to open file
+    CheckIfFileAlreadyExist( fileNameBuf );
+    
+    // If a data file with the requested name already existed, and was opened
+    // successfully, check the version of the file. If the line telling the version of
+    // the file is not the expected, replace the file
+    // If cannot open the file(error is KErrInUse), generate new filename and 
+    // then try to create new file.
+    if ( iError == KErrNone )
+        {
+        CheckFileVersion( fileNameBuf );
+        }    
+    else if ( iError == KErrInUse )
+        {
+        GenerateNewFileName( fileNameBuf, aProcessName );
+        
+        // Save the file name for this session
+        CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
+        }
+    LOGSTR2( "STSE > iError(%i)", iError );
+        
+    // If the file does not exist, create it. Write also the version number of
+    // the file at the beginning of the new file
+    if ( iError == KErrNotFound )
+        {
+        iError = iFile.Create( iFileServer, fileNameBuf, EFileWrite );
+        
+        if ( !iError )
+            {
+            iError = iFile.Write( KDataFileVersion );
+            }
+        }   
+       
+    if ( iError )
+        {
+        iFile.Close();
+        iFileServer.Close();
+        return iError;
+        }
+        
+    // Seek the end of the file and set the current file position there
+    TInt offset = 0;
+    iError = iFile.Seek( ESeekEnd, offset );
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GenerateNewFileName
+// Called internally when need generate new file name.
+// -----------------------------------------------------------------------------
+//                     
+void CATStorageServerSession::GenerateNewFileName( TDes& aFileName,
+    const TDesC8& aProcessName )
+    {    
+    LOGSTR1( "STSE void CATStorageServerSession::GenerateNewFileName()" );
+        
+    // Extension
+    TBuf<KExtensionLength> extension;
+
+    // Parse file extension
+    ParseExtension( aFileName, extension );
+
+    // Try to find UID3 from current process name
+    TInt uidErr( KErrBadName );
+    TBuf<KMaxFileName> unicodeFile;
+
+    // Converts text encoded using the Unicode transformation format UTF-8 
+    // into the Unicode UCS-2 character set. 
+    CnvUtfConverter::ConvertToUnicodeFromUtf8( unicodeFile, aProcessName );
+    LOGSTR2( "STSE > unicodeFile(%S)", &unicodeFile );
+
+    // Find square brackets
+    TInt sPos( unicodeFile.Find( KOpenSquareBracket ) );
+    TInt ePos( unicodeFile.Find( KCloseSquareBracket ) );
+    LOGSTR3( "STSE > sPos(%i), ePos(%i)", sPos, ePos );
+            
+    if ( sPos != KErrNotFound && ePos != KErrNotFound )
+        {
+        TBuf<KProcessUidLength> processUid;
+        TInt pEnd( ePos - sPos - KOpenSquareBracket().Length() );
+        LOGSTR2( "STSE > pEnd(%i)", pEnd );
+        
+        // Copy UID value
+        if ( pEnd > 0 )
+            {
+            processUid.Copy( unicodeFile.Mid( 
+                    sPos + KOpenSquareBracket().Length(), pEnd ) );
+            LOGSTR2( "STSE > processUid(%S)", &processUid );
+            }
+        
+        if ( aFileName.Find( processUid ) == KErrNotFound )
+            {
+            // UID not exist, create new filename
+            // Append uid to filename (<file name>_<uid>.<extension>)
+            aFileName.Append( KUnderLine );
+            aFileName.Append( processUid );
+            aFileName.Append( extension );
+            // Try to open file
+            CheckIfFileAlreadyExist( aFileName );
+
+            if ( iError == KErrNone )
+                {
+                uidErr = KErrNone;
+                CheckFileVersion( aFileName );
+                }
+            }
+        }
+
+    if ( uidErr == KErrBadName && iError != KErrNotFound )
+        {
+        // Need re-create file name, add end off file _xx (xx=01, 02...)
+        LOGSTR2( "STSE > Re-create file name, aFileName(%S)", &aFileName );
+                
+        // Parse file extension if exists.
+        ParseExtension( aFileName, extension );
+        
+        // Temp file name
+        TBuf<KMaxFileName> tempName;
+        
+        for ( TInt i = KNameIndexStart; i < KNameIndexEnd; i++ )
+            {
+            tempName.Delete( 0, tempName.MaxLength() );
+            tempName.Format( KFormat, &aFileName, &KUnderLine, i, &extension );
+            LOGSTR2( "STSE > tempName(%S)", &tempName );
+            // Try to open file
+            CheckIfFileAlreadyExist( tempName );
+            
+            if ( iError == KErrNone || iError == KErrNotFound )
+                {
+                aFileName.Copy( tempName );
+                break;
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ParseExtension
+// Method is used to parse file name extension.
+// -----------------------------------------------------------------------------
+//                     
+void CATStorageServerSession::ParseExtension( 
+    TDes& aFileName, TDes& aExtension )
+    {    
+    LOGSTR2( "STSE void CATStorageServerSession::ParseExtension(%S)", 
+            &aFileName );
+
+    // Parse current file name
+    TParse parse;
+    // Set up the TParse object 
+    parse.Set( aFileName, NULL, NULL );
+
+    // Tests whether an extension is present.
+    if ( parse.ExtPresent() )
+        {
+        // Gets the extension
+        aExtension.Copy( parse.Ext() );
+        // Remove extension from file name
+        TInt pos( aFileName.Find( aExtension ) );
+        aFileName.Delete( pos, aFileName.Length() );
+        LOGSTR3( "STSE > aFileName(%S), aExtension(%S)", 
+                &aFileName, &aExtension );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckIfFileAlreadyExist
+// Method is used to check that file exists and is valid.
+// -----------------------------------------------------------------------------
+//                     
+void CATStorageServerSession::CheckIfFileAlreadyExist( 
+    const TDes& aFileName )
+    {    
+    LOGSTR2( "STSE void CATStorageServerSession::CheckIfFileAlreadyExist(%S)", 
+            &aFileName );
+    
+    iError = iFile.Open( iFileServer, aFileName, EFileWrite );
+    LOGSTR2( "STSE > iError(%i)", iError );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckFileVersion
+// Method is used to check file version.
+// -----------------------------------------------------------------------------
+//                     
+void CATStorageServerSession::CheckFileVersion( 
+    const TDes& aFileName )
+    {    
+    LOGSTR2( "STSE void CATStorageServerSession::CheckFileVersion(%S)", 
+            &aFileName );
+
+    TBuf8<KVersionStringLength> versionString;
+
+    // Read version information from the beginning of the file (offset 0)
+    iFile.Read( 0, versionString, KVersionStringLength );
+
+    // Delete the existing file, if the version string read from the file does not
+    // match with KDataFileVersion.
+    if ( versionString.Compare( KDataFileVersion ) != 0 )
+        {
+        // Close the existing, opened file, and delete it
+        iFile.Close();
+        iError = iFileServer.Delete( aFileName );
+        
+        // If the deletion was successful, set iError = KErrNotFound, so a new
+        // file will be created in the next few lines 
+        if ( iError == KErrNone )
+            {
+            iError = KErrNotFound;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CloseFsAndFile
+// Internally used for closing a handle to the file server and a file
+// -----------------------------------------------------------------------------
+// 
+void CATStorageServerSession::CloseFsAndFile()
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::CloseFsAndFile()" );
+    
+    // Close the file    
+    iFile.Close();
+                 
+    // Close the server session and return the error code   
+    iFileServer.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::PrintLeaksL()
+// Called internally when a process is closed. Prints possible memory leaks
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::PrintLeaksL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::PrintLeaksL()" );
+    
+    // Panic both the client and the server, if this method is called in a wrong
+    // state (logging should be ongoing, and the system should be logging into a file,
+    // not into debug channel)
+    if ( !iLoggingOngoing || iLogOption != EATLogToFile )
+        {
+        PanicClient( EAToolInternalError, aMessage );
+        StorageServerPanic( KCategoryServer, EAToolInternalError );
+        }
+   
+    LOGMEM;
+
+    // A pointer to a buffer of call stack's memory addresses
+    CBufFlat* stackBuf = NULL;
+    
+    iError = KErrNone;
+    
+    TUint32 callStackAddr;
+    
+    // Number of leaks
+    TInt leakCount = iLeakArray.Count();
+    
+    // Variable for the number of memory addresses in the call stack
+    TInt addrCount( 0 );
+    
+    // Buffer position
+    TInt pos( 0 );
+                     
+    // Go through all the leaks 
+    for ( TInt i = 0; i < leakCount; i++ ) 
+        {   
+        pos = 0;
+        
+        // Get the call stack buffer of the the leak i.
+        stackBuf = const_cast<CBufFlat*>( iLeakArray[i]->iCallstackBuf );
+    
+        // Read the first word of the buffer. This includes the number of
+        // memory addresses stored in the current stackBuf
+        stackBuf->Read( pos, &addrCount, KWordSize );
+    
+        // Move the position one word onwards.
+        pos += KWordSize;
+         
+        // Construct a buffer for the string to be written into the logging file
+        // because of this memory leak. MEM_LEAK: <Memory address> <Time stamp>
+        // <Allocation size> <Call stack address> <Call stack address> ...
+        HBufC8* leakString = 
+            HBufC8::NewL( KMemleakLength +
+                          KHexa32Length +
+                          KSpaceLength + KHexa64Length +
+                          KSpaceLength + KHexa32Length +
+                          ( addrCount * (KSpaceLength + KHexa32Length) ) +
+                          KNewlineLength 
+                        );
+            
+        // Make a pointer descriptor that points to leakString
+        TPtr8 leakStringPtr( leakString->Des() );
+        
+        // Append the tag implying a memory leak line in the data file
+        leakStringPtr.Append( KMemoryLeak );
+        
+        // Append the address of the memory leak         
+        TUint32 memAddress = iLeakArray[i]->iMemAddress;
+        leakStringPtr.AppendNum( memAddress, EHex );
+        
+        // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+        // format
+        leakStringPtr.Append( KSpace );
+        TInt64 allocTime = iLeakArray[i]->iAllocTime;
+        leakStringPtr.AppendNum( allocTime, EHex );
+        
+        // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+        // text format.
+        leakStringPtr.Append( KSpace );
+        TInt allocSize = iLeakArray[i]->iAllocSize;
+        leakStringPtr.AppendNum( allocSize, EHex );
+        
+        // Go through all call stack's memory addresses associated with
+        // the current memory leak 
+        for ( TInt j = 0; j < addrCount; j++ )
+            {
+            // Read the next call stack's memory address stored in the buffer.
+            stackBuf->Read( pos, &callStackAddr, KWordSize );
+            
+            // Append the read memory address as a hexadecimal number
+            leakStringPtr.AppendFormat( KHexaNumber,  callStackAddr );
+    
+            // Move the pos variable one word onwards.
+            pos += KWordSize;
+            }
+        
+        leakStringPtr.Append( KNewLine );
+        
+        // Set stackBuf to NULL, because it is not used anymore.
+        stackBuf = NULL;
+        
+        // Write the constructed string into the data file and return if error
+        iError = iFile.Write( *leakString );
+        
+        delete leakString;
+          
+        if ( iError != KErrNone )
+            {
+            return iError;
+            }
+              
+        } // The outer for
+   
+    LOGSTR1( "STSE End of CATStorageServerSession::PrintLeaks()" );
+    LOGMEM;
+   
+    // Empty the leak array and delete the referenced objects
+    iLeakArray.ResetAndDestroy();
+   
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::SetLogOption()
+// For setting the logging mode.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::SetLogOption( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::SetLogOption()" );
+        
+    // Panic both the client and the server, if this method is called in a wrong
+    // state (logging must not be ongoing when changing the mode of operation).
+    // So, the mode cannot be changed "on the fly".
+    if ( iLoggingOngoing )
+        {
+        PanicClient( EAToolInternalError, aMessage );
+        StorageServerPanic( KCategoryServer, EAToolInternalError );
+        }    
+
+    iLogOption = static_cast<TATLogOption>( aMessage.Int3() );
+    
+    // The default is EATLogToFile
+    if ( iLogOption == EATUseDefault )
+        {
+        iLogOption = KDefaultLoggingMode;
+        } 
+    }
+    
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogThroughTrace()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogThroughTrace( const TDesC& aLogString ) const
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::LogThroughTrace()" );
+
+    // Return KErrNotSupported, if a logging session is not currently ongoing, or
+    // the logging mode is not EATLogToTrace
+    if ( !iLoggingOngoing || iLogOption != EATLogToTrace)
+        {
+        return KErrNotSupported;
+        }
+        
+    RDebug::Print( KTraceMessage, iProcessId, &aLogString );
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::AllocInfoArray
+// -----------------------------------------------------------------------------
+// 
+RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()
+    {
+    LOGSTR1( "STSE RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()" );
+     
+    return iAllocInfoArray;
+    }    
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::PanicClient
+// Creates a panic in the associated client's code.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::PanicClient( TInt aPanic, const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::PanicClient()" );
+    
+    aMessage.Panic( KCategoryClient, aPanic );
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetLoggingFileL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::GetLoggingFileL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingFileL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Get the dynamic process info array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+
+    // Get the desired process's associated session object
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+            
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, sessionObject->iLogFile );
+                    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetUdebL()
+// -----------------------------------------------------------------------------
+//    
+TInt CATStorageServerSession::GetUdebL( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE TInt CATStorageServerSession::GetUdebL()" );
+    
+    iError = KErrNone;
+    
+    // Read the process ID at index 0
+    TUint processId = aMessage.Int0();
+    
+    // Get the dynamic process info array
+    RPointerArray<CATDynProcessInfo> dynProcessArray =
+                                             iStorageServer.DynProcessInfoArray();
+    
+    // Construct a CATDynProcessInfo object with the given process ID for searching
+    CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+    
+    // Find the index of a CATDynProcessInfo object with the given process ID
+    TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+    TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+    delete dynProcessInfo;
+    dynProcessInfo = NULL;
+    
+    // Return, if a process with the requested process ID was not found 
+    if ( index == KErrNotFound )
+        {
+        return index;
+        }
+    
+    // Otherwise get the wanted dynamic process info
+    dynProcessInfo = dynProcessArray[index];
+
+    // Get the desired process's associated session object
+    CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+    
+    TBuf8<KMaxVersionName> isUdeb;
+    if ( sessionObject->iIsUdeb == 1 )
+        {
+        isUdeb.Copy( KUdeb() );
+        }
+    else if ( sessionObject->iIsUdeb == 0 )
+        {
+        isUdeb.Copy( KUrel() );
+        }
+    else
+        {
+        return KErrNotFound;
+        }
+    // Write the whole buffer into aMessage at index 1 for the client
+    aMessage.WriteL( 1, isUdeb );
+    
+    return iError;
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::SetUdeb()
+// -----------------------------------------------------------------------------
+//    
+void CATStorageServerSession::SetUdeb( const RMessage2& aMessage )
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::SetUdeb()" );
+ 
+    iIsUdeb = aMessage.Int0();
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogAbnormalEnd()
+// -----------------------------------------------------------------------------
+//    
+void CATStorageServerSession::LogAbnormalEnd()
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::LogAbnormalEnd()" );
+    
+    // Get the current universal time     
+    TInt64 timeFrom1970( GetTime() );
+        
+    switch ( iLogOption )
+        {
+        case EATLogToTrace:
+            {            
+            // Make a buffer that will be logged
+            TBuf<KEndAbnormalBufLength> traceBuf;
+            
+            // Write the process id to the buffer  
+            traceBuf.Format( KProcessEndAbnormalTrace, iProcessId );
+            
+            // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+            // format         
+            traceBuf.AppendNum( timeFrom1970, EHex );
+                
+            // Append a new line
+            traceBuf.Append( KNewLineTrace );
+            
+            // Write the buffer into the debug channel
+            RDebug::Print( KTraceMessage, iProcessId, &traceBuf );
+            }
+        break;
+        
+        case EATLogToFile:
+            {            
+            // Make a buffer that will be logged
+            TBuf8<KEndAbnormalBufLength> loggingBuf;
+            
+            // Write the process id to the buffer  
+            loggingBuf.Format( KProcessEndAbnormal, iProcessId );
+            
+            // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+            // format         
+            loggingBuf.AppendNum( timeFrom1970, EHex );
+                
+            // Append a new line
+            loggingBuf.Append( KNewLine );
+            
+            // Write the buffer into a file (if possible in the current condition)
+            iFile.Write( loggingBuf );
+            }
+        break;
+              
+        default:
+            break;
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetTime()
+// Get the current universal time
+// -----------------------------------------------------------------------------
+//    
+TInt64 CATStorageServerSession::GetTime()
+    {
+    LOGSTR1( "STSE void CATStorageServerSession::GetTime()" );
+    
+    // Get the current universal time
+    iTime.UniversalTime();
+        
+    // Change the time format that tells the number of microseconds from January First,
+    // 0 AD nominal Gregorian, into a format that tells the number of microseconds from
+    // January First, 1970 AD nominal Gregorian. This is a more generic format and
+    // can be directly exploited by the PC code parsing the data file that this
+    // server generates.        
+    return ( iTime.Int64() - iMicroSecondsAt1970 );        
+    }
+
+//  End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/sis/atstorageserver.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,37 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+;
+; An installation file for AnalyzeTool StorageServer
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"ATStorageServer"},(0xA22E6C80),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 4 Files to install
+"\epoc32\release\armv5\urel\atoolstorageserver.exe"-"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\urel\atoolstorageserverclnt.dll"-"!:\sys\bin\atoolstorageserverclnt.dll"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/sis/atstorageserver_udeb.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,37 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+;
+; An installation file for AnalyzeTool StorageServer
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"ATStorageServer"},(0xA22E6C80),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 4 Files to install
+"\epoc32\release\armv5\udeb\atoolstorageserver.exe"-"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\udeb\atoolstorageserverclnt.dll"-"!:\sys\bin\atoolstorageserverclnt.dll"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/symbian_version.hrh	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Symbian version configuration file 
+*
+*/
+
+#ifndef __SYMBIAN_VERSION_HRH
+#define __SYMBIAN_VERSION_HRH
+
+// S60 and Symbian version number enumeration definitions
+
+#define S60_30                                              30
+#define S60_31                                              31
+#define S60_32                                              32
+#define S60_50                                              50
+#define S60_51                                              91
+#define S60_52                                              92
+#define SYMBIAN_1                                           50
+#define SYMBIAN_2                                           91
+#define SYMBIAN_3                                           92
+#define SYMBIAN_4                                           101
+
+
+/**
+ * Defines the S60 or Symbian version used by this component. This flag can be
+ * used to variate the source code based on the SDK in use. The value of the
+ * flag should be always changed to reflect the current build environment.
+ */
+#define SYMBIAN_VERSION_SUPPORT                              SYMBIAN_3
+
+
+#endif  // __SYMBIAN_VERSION_HRH
--- a/group/bld.inf	Tue May 11 17:39:09 2010 +0300
+++ b/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -21,4 +21,6 @@
 #include "../osrndtools_plat/group/bld.inf"
 #include "../stif/group/bld.inf"
 #include "../memspy/group/bld.inf"
-#include "../hti/group/bld.inf"
\ No newline at end of file
+#include "../hti/group/bld.inf"
+#include "../piprofiler/group/bld.inf"
+#include "../analyzetool/group/bld.inf"
\ No newline at end of file
--- a/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h	Tue May 11 17:39:09 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h	Tue May 25 14:22:58 2010 +0300
@@ -113,6 +113,6 @@
     TUid iDtor_ID_Key;
     };
 
-#include <HTICommPluginInterface.inl>
+#include <HtiCommPluginInterface.inl>
 
 #endif
--- a/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h	Tue May 11 17:39:09 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h	Tue May 25 14:22:58 2010 +0300
@@ -110,6 +110,6 @@
     TUid iDtor_ID_Key;
     };
 
-#include <HTIServicePluginInterface.inl>
+#include <HtiServicePluginInterface.inl>
 
 #endif
--- a/hti/hti_plat/hti_api/inc/HtiVersion.h	Tue May 11 17:39:09 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiVersion.h	Tue May 25 14:22:58 2010 +0300
@@ -25,13 +25,13 @@
 // CONSTANTS
 
 const TUint8 KHtiVersionMajor = 2;
-const TUint8 KHtiVersionMinor = 21;
+const TUint8 KHtiVersionMinor = 22;
 const TUint8 KHtiVersionBuild = 0;
 
 const TUint16 KHtiVersionYear  = 2010;
 const TUint8  KHtiVersionMonth = 4;
-const TUint8  KHtiVersionWeek  = 15;
-const TUint8  KHtiVersionDay   = 16;
+const TUint8  KHtiVersionWeek  = 17;
+const TUint8  KHtiVersionDay   = 30;
 
 //  MACROS
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/ProfilerEngine.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET      PIProfilerEngine.exe
+TARGETTYPE  EXE
+UID         0x100039CE 0x2001E5AD
+VENDORID    VID_DEFAULT
+CAPABILITY  ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE     	0x10000
+EPOCHEAPSIZE        0x100000 0x2000000  // Min 1MB, Max 32MB
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE     ../inc
+SOURCEPATH      ../src
+
+SOURCE		ProfilerErrorChecker.cpp
+SOURCE      ProfilerEngine.cpp 
+SOURCE      SamplerController.cpp
+SOURCE      SamplerPluginLoader.cpp 
+SOURCE      WriterController.cpp
+SOURCE      WriterPluginLoader.cpp 
+SOURCE		ProfilerTimer.cpp 
+
+LIBRARY		sysutil.lib 
+LIBRARY     EFSRV.LIB
+LIBRARY     C32.LIB
+LIBRARY     EUSER.LIB 
+LIBRARY     estor.lib 
+LIBRARY     fbscli.lib
+LIBRARY     ws32.lib
+LIBRARY     bafl.lib 
+LIBRARY     charconv.lib
+LIBRARY     ecom.lib
+LIBRARY		PlatformEnv.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/ProfilerEshell.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET      PIProfiler.exe
+TARGETTYPE  EXE
+UID         0x100039CE 0x2021E5AD	// test UID, get an official
+VENDORID    VID_DEFAULT
+CAPABILITY  ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE     	0x10000
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE     ../inc
+SOURCEPATH      ../src
+
+
+SOURCE      ProfilerEshell.cpp 
+
+LIBRARY     C32.LIB
+LIBRARY     EUSER.LIB 
+LIBRARY     bafl.lib 
+LIBRARY		efsrv.lib 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2007 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:  
+*
+*/
+
+
+PRJ_MMPFILES
+ProfilerEngine.mmp
+ProfilerEshell.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerEngine.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,258 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PROFILERENGINE__
+#define __PROFILERENGINE__
+
+#include <e32base.h>
+#include <e32svr.h>
+#include <e32property.h> 
+
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerSession.h>
+#include <piprofiler/ProfilerAttributes.h>	// internal settings format presentations 
+
+#include "SamplerController.h"
+#include "WriterController.h"
+#include "ProfilerErrorChecker.h"
+#include "ProfilerTimer.h"
+
+// CONSTANTS
+const TInt KProfilerPrefixMaxLength = 32;
+const TInt KSettingsFileSize = 4096;
+
+/*
+ * This is an internal interface to the profiling engine which allows
+ * an additional control DLL to be loaded, replacing the profiler's
+ * default console UI
+ */
+
+/**
+ * Implementation class providing access to the profiler engine
+ */
+
+class MProfilerEngine
+{
+public:
+	virtual TInt				ControlL(TInt aCommand) =0;
+	virtual TInt				ControlDataL(TInt aCommand, TAny* data1 = 0, TAny* data2 = 0) = 0; 
+	
+	virtual TInt                GetSamplerAttributesL(const RMessage2& aMessage) = 0;
+    virtual TInt                GetSamplerAttributeCountL(const RMessage2& aMessage) = 0;
+	virtual TInt                SetSamplerAttributesL(const RMessage2& aMessage) = 0;
+	virtual TInt                GetGeneralAttributesL(const RMessage2& aMessage) = 0;
+	virtual TInt                SetGeneralAttributesL(const RMessage2& aMessage) = 0;
+    virtual TInt                 RefreshStatus(const RMessage2& aMessage) = 0;
+	virtual RProfiler::TSamplerState 	State() const =0;
+};
+
+/**
+ * The interface that the extra controller must implement to access
+ * the profiler.
+ */
+class MProfilerController
+{
+	public:
+		/** Release the controller from the profiler. This is invoked when the profiler is unloading. */
+		virtual void				Release() = 0;
+		/** Ask the profiler to change state */
+		inline TInt					ControlL(TInt aCommand) const;
+		/** Ask the profiler to change state */
+		inline TInt					ControlDataL(TInt aCommand, TAny* data1 = 0, TAny* data2 = 0) const;
+		
+		inline TInt                 GetSamplerAttributesL(const RMessage2& aMessage) const;
+        inline TInt                 SetSamplerAttributesL(const RMessage2& aMessage) const;
+        inline TInt                 GetGeneralAttributesL(const RMessage2& aMessage) const;
+        inline TInt                 SetGeneralAttributesL(const RMessage2& aMessage) const;
+        inline TInt                 GetSamplerAttributeCountL(const RMessage2& aMessage) const;
+        inline TInt                 RefreshStatus(const RMessage2& aMessage) const;
+		/* Query the profiler state */
+		inline RProfiler::TSamplerState	GeTComand() const;
+	protected:
+		inline						MProfilerController(MProfilerEngine& aEngine);
+	private:
+		MProfilerEngine& iEngine;
+};
+
+/** The signature of ordinal 1 in the controller DLL */
+typedef MProfilerController* (*TProfilerControllerFactoryL)(TInt aPriority, MProfilerEngine& aEngine);
+/** The second UID required by the controller DLL */
+const TUid KUidProfilerKeys={0x1000945c};
+
+inline MProfilerController::MProfilerController(MProfilerEngine& aEngine)
+	:iEngine(aEngine)
+{
+
+}
+
+inline TInt MProfilerController::ControlL(TInt aCommand) const
+{
+	return iEngine.ControlL(aCommand);
+}
+
+inline TInt MProfilerController::ControlDataL(TInt aCommand,TAny* data1, TAny* data2) const
+{
+	return iEngine.ControlDataL(aCommand,data1,data2);
+}
+
+inline TInt MProfilerController::GetSamplerAttributesL(const RMessage2& aMessage) const
+{
+    return iEngine.GetSamplerAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::SetSamplerAttributesL(const RMessage2& aMessage) const
+{
+    return iEngine.SetSamplerAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::GetGeneralAttributesL(const RMessage2& aMessage) const
+{
+    return iEngine.GetGeneralAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::GetSamplerAttributeCountL(const RMessage2& aMessage) const
+{
+    return iEngine.GetSamplerAttributeCountL(aMessage);
+}
+
+inline TInt MProfilerController::SetGeneralAttributesL(const RMessage2& aMessage) const
+{
+    return iEngine.SetGeneralAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::RefreshStatus(const RMessage2& aMessage) const
+{
+    return iEngine.RefreshStatus(aMessage);
+}
+
+inline RProfiler::TSamplerState MProfilerController::GeTComand() const
+{
+	return iEngine.State();
+}
+
+class CSamplerController;
+class CWriterController;
+class MSamplerControllerObserver;
+class MProfilerErrorObserver;
+
+class CProfiler : public CBase, private MProfilerEngine, 
+    MSamplerControllerObserver, 
+    MProfilerErrorObserver,
+    MProfilerTimerObserver
+{
+	public:
+		
+		static CProfiler*	NewLC(const TDesC& aSettingsFile);
+
+		/**
+		 * Method for control commands, i.e. start, stop and exit 
+		 * 
+		 * @param aCommand command to be parsed and executed
+		 * @return TInt KErrNone if succeed, else error code
+		 */
+		TInt				ControlL(TInt aCommand);
+
+		/**
+         * Method for control data, e.g. settings
+         * 
+         * @param aCommand command to be parsed and executed
+         * @param value1 can contain any value, integer or string, depends on use case 
+         * @param value2 can contain any value, integer or string, depends on use case 
+         * @return TInt KErrNone if succeed, else error code
+         */
+		TInt				ControlDataL(TInt aCommand, TAny* value1 = 0, TAny* value2 = 0);	
+
+		// setting attributes manipulation
+		TInt  GetGeneralAttributesL(const RMessage2& aMessage);
+		TInt  GetSamplerAttributesL(const RMessage2& aMessage);
+		TInt  SetGeneralAttributesL(const RMessage2& aMessage);
+		TInt  SetSamplerAttributesL(const RMessage2& aMessage);
+		TInt  GetSamplerAttributeCountL(const RMessage2& aMessage);
+		TInt  RefreshStatus(const RMessage2& /*aMessage*/);
+
+		// from CProfilerErrorChecker
+		void  HandleSamplerControllerReadyL();
+		void  NotifyRequesterForSettingsUpdate();
+		void  HandleProfilerErrorChangeL( TInt aError );
+		
+		// from MProfilerTimerObserver
+		void HandleTimerExpiresL(TInt aError);
+	    
+		void 				Finalise();
+		CProfilerSampleStream* GetSamplerStream();
+	    void  HandleError(TInt aErr);
+	    static TBool CheckLocationSanity(RFs& fs, const TDesC8& aLocation);
+private:
+							CProfiler(const TDesC& aSettingsFile);
+							~CProfiler();
+		void				ConstructL();
+		TInt 				LoadSettingsL(/*const TDesC& configFile*/);		
+		void                DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TDes8& aValue);
+		void                DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TInt& aValue);
+		void                UpdateSavedGeneralAttributes(CDesC8ArrayFlat* aSavedAttributes);
+		template<class T> CBufFlat* ExternalizeLC(const T& aElements);
+		
+		RProfiler::TSamplerState	State() const;
+
+		void DrainSampleStream();
+		void InstallStreamForActiveTraces(CSamplerPluginInterface& aSampler, CWriterPluginInterface& aWriter, TDesC& totalPrefix);
+		void SaveSettingsL();
+		
+		TInt HandleGeneralSettingsChange();
+		TInt CheckOldProfilerRunning();
+public:
+        // trace file settings
+		TBuf8<KProfilerPrefixMaxLength>	iFilePrefix;
+		TBuf8<KProfilerPrefixMaxLength>	iDriveLetter;
+		TBuf8<KProfilerPrefixMaxLength*2> iTotalPrefix;
+
+		TBuf<256>                       iSettingsFileLocation;
+		
+		MProfilerController*			iServer;
+		RProfiler::TSamplerState		iState;
+		
+		CProfilerSampleStream* 			iUserStream;
+		
+		// plug-in controllers
+		CWriterController*				iWriterHandler;
+		CSamplerController*				iSamplerHandler;
+
+		// setting attribute containers
+		TGeneralAttributes				iGeneralAttributes;
+		CArrayFixFlat<TSamplerAttributes>*	iDefaultSamplerAttributesArray;
+		
+		// temporary settings file array container
+		CDesC8ArrayFlat*                iSavedLineArray;	
+		TInt                            iSavedLinesCount;
+	    // saved settings, add extra 1 byte space to end buffer with a '\n'
+	    TBuf8<KSettingsFileSize + 1>   iSettingsBuffer;   
+
+	    // P&S status properties
+		RProperty						iEngineStatus;
+        RProperty                       iUpdateStatus;
+	    TBuf<128>                       iFileNameStream;
+private:
+        TBool                           iSettingsFileLoaded;
+        CProfilerErrorChecker*          iErrorChecker;
+        CProfilerTimer*                 iTimer;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#endif	// __PROFILERENGINE__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerErrorChecker.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILERERRORCHECKER_H_
+#define PROFILERERRORCHECKER_H_
+
+// CLASS DECLARATIONS
+class MProfilerErrorObserver
+    {
+    public: // New
+        virtual void HandleProfilerErrorChangeL( TInt aError ) = 0;
+    };
+
+
+class CProfilerErrorChecker : public CActive
+    {
+public:
+    static CProfilerErrorChecker* CProfilerErrorChecker::NewL();
+    ~CProfilerErrorChecker();
+    void SetObserver(MProfilerErrorObserver* aObserver);
+private:
+    CProfilerErrorChecker();
+    void ConstructL();
+    void RunL();
+    TInt RunError(TInt aError);
+    void DoCancel();
+private:
+    MProfilerErrorObserver*     iObserver;
+    RProperty                   iErrorStatus;
+    };
+
+#endif /* PROFILERERRORCHECKER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerEshell.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+#ifndef PROFILERESHELL_H_
+#define PROFILERESHELL_H_
+
+#include <e32base.h>
+#include <e32std.h>  
+#include <bacline.h>    // CCommandLineArguments
+
+class CProfilerEShell : public CBase
+    {
+public:
+    static CProfilerEShell* NewL();
+    ~CProfilerEShell();
+    
+    void ConstructL();
+private:
+    CProfilerEShell();
+    
+    };
+
+#endif /* PROFILERESHELL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerTimer.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#ifndef PROFILERTIMER_H_
+#define PROFILERTIMER_H_
+
+#include <e32std.h>
+#include <e32base.h>
+
+class MProfilerTimerObserver
+    {
+public:
+    virtual void HandleTimerExpiresL(TInt aError) = 0;
+    };
+
+class CProfilerTimer : public CActive
+    {
+public:
+    static CProfilerTimer* NewL(const TInt aPriority, MProfilerTimerObserver& aObserver);
+    ~CProfilerTimer();
+    
+public:
+    
+    void After(TUint aPeriodInSeconds);
+    
+protected:
+    
+    // From CActive
+    void RunL();
+    void DoCancel();
+    
+private:
+    
+    CProfilerTimer(const TInt aPriority, MProfilerTimerObserver& aObserver);
+    void ConstructL(void);
+    
+private:
+    
+    RTimer      iTimer;
+    MProfilerTimerObserver&    iObserver;
+    };
+
+#endif /* PROFILERTIMER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/SamplerController.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __SAMPLERCONTROLLER_H__
+#define __SAMPLERCONTROLLER_H__
+
+// system includes
+#include <utf.h>
+#include <e32cmn.h>
+
+
+// The user-interface to the sampling device driver sued by the profiling engine
+// user includes
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/SamplerPluginInterface.h>
+
+#include "SamplerPluginLoader.h"
+
+/*
+ *	Forward declarations
+ */
+class TBapBuf;
+class CProfilerSampleStream;
+class CSamplerPluginLoader;
+class CSamplerPluginInterface;
+class MSamplerControllerObserver;
+/**
+ * The sampler controller for handling the actual sampler plugins.
+ */
+
+class CSamplerController : public CBase, MSamplerPluginLoadObserver
+	{
+	
+public:
+	static CSamplerController* NewL(CProfilerSampleStream& aStream);
+	void ConstructL();
+	
+	CSamplerController(CProfilerSampleStream& aStream);
+	~CSamplerController();
+	
+	/** 
+	 * 
+	 * Methods for user mode sampling
+	 * 
+	 **/
+	
+	/** Initialise the user mode samplers **/					
+	void InitialiseSamplerListL();
+		 
+	/* Overrider of MSamplerPluginLoaderObserver class **/
+	void HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus );
+	
+	/* returns the name matching plugin Uid */
+	TUid GetPluginUID(TDesC8& name);
+
+	/** Start enabled samplers **/				
+	void StartSamplerPluginsL();
+
+	/** Stop enabled samplers **/				
+	TInt StopSamplerPlugins();
+
+public:
+
+	CSamplerPluginInterface* GetPlugin(TUid aUid);
+
+	TInt GetPluginList(TDes* aList);
+	
+    TInt SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes);
+
+    void GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+	
+	TInt UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes);
+	
+	/*
+	 * Compose all sampler (sampler or sub-sampler) attributes as text array for saving to settings file, 
+	 * called by CSamplerController (and Profiler Engine) 
+	 * 
+	 * @param aFile settings file where to write the settings 
+	 */
+	void ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes);
+	
+	/*
+	 * Compose all sampler (sampler or sub-sampler) attributes as text array for saving to settings file, 
+	 * called by CSamplerController (and Profiler Engine) 
+	 * 
+     * @param aFile settings file where to write the settings 
+	 * @param aAttrArray is container for saving the text to 
+	 */
+	void ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray);
+	
+	void SetObserver(MSamplerControllerObserver* aObserver);
+	
+	void     Str2Bool(const TDesC8& aBuf, TBool& aValue);
+    
+    void     Str2Int(const TDesC8& aBuf, TInt& aValue);
+    
+    void     Str2Int(const TDesC8& aBuf, TUint32& aValue);
+    
+    TBuf8<16> Bool2Str(const TBool& aValue);
+    
+    TBuf8<16> Int2Str(const TInt& aValue);
+public:
+
+    CArrayPtrFlat<CSamplerPluginInterface>* iPluginArray;
+    
+    // Asynchronous loader for the sampler plug-ins.
+    CSamplerPluginLoader*     iPluginLoader;
+    
+    // UID of the selected plugin in the container's lbx.
+    TUid                      iSelectedPluginUid;
+    
+    // shared sample stream for all plugin samplers
+    CProfilerSampleStream&    iStream;
+
+private:
+	MSamplerControllerObserver* iObserver;
+};
+
+/**
+* Interface for SamplerPluginLoader observer. MSamplerPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib
+* @since Series60_30.1
+*/
+
+class MSamplerControllerObserver
+    {
+    public: // New
+
+        //CSamplerController calls this function when each plug-in is loaded or
+        //loading is finished..
+        
+        virtual void HandleSamplerControllerReadyL() = 0;
+        virtual void HandleError(TInt aError) = 0;
+    };
+    
+#endif	// __SAMPLERCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/SamplerPluginLoader.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,291 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef  SAMPLERPLUGINLOADER_H
+#define  SAMPLERPLUGINLOADER_H
+
+// INCLUDES
+#include    <e32base.h>
+#include    <ecom/implementationinformation.h>
+#include 	<piprofiler/ProfilerConfig.h>
+#include 	<piprofiler/SamplerPluginInterface.h>
+
+// CONSTANTS
+// Value for a to b comparison result when logically a == b.
+const TInt KSamplerComparisonEqual     = 0;
+
+// Value for a to b comparison result when logically a < b.
+const TInt KSamplerComparisonBefore    = -1;
+
+// Value for a to b comparison result when logically a > b.
+const TInt KSamplerComparisonAfter     = 1;
+
+// CLASS DEFINITIONS
+class CSamplerPluginInterface;
+class MSamplerPluginLoadObserver;
+class REComSession;
+
+/**
+* CSamplerPluginLoader. Mechanism used to load plugins asynchronously. Uses
+* MSamplerPluginLoadObserver as a callback.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+class CSamplerPluginLoader : public CActive
+    {
+    public:  // Constructor and destructor
+
+        /**
+        * Two-phased constructor.
+        *
+        * @param aAppUi Pointer to application UI. Does not take ownership.
+        */
+        static CSamplerPluginLoader* NewL();
+
+        /**
+        * Destructor
+        */
+        ~CSamplerPluginLoader();
+
+    private: // Internal construction
+
+        /**
+        * Default C++ contructor
+        */
+        CSamplerPluginLoader();
+
+        /**
+        * Symbian OS default constructor
+        * @return void
+        */
+        void ConstructL();
+
+    public: // API
+
+        /**
+        * Starts loading GS plug-ins asynchronously. Will call
+        * MSamplerPluginLoadObserver::HandlePluginLoaded() each time a plug-in is
+        * loaded and when all plugins are loaded.
+        *
+        * CSamplerPluginLoader transfers the ownership of each loaded plugin view to
+        * CAknViewAppUi. It is client's responsibility to remove the views from
+        * CAknViewAppUi and delete the plugins if necessary.
+        *
+        * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+        * @param aParentUid Uid of the parent. Only children of this parent
+        *        will be loaded.
+        * @param aPluginArray An array for the loaded GS plug-ins.
+        *        CSamplerPluginLoader does not take the ownership of this array.
+        */
+        void LoadAsyncL( CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray );
+
+        /**
+        * Load a specific plugin instance synchronously.
+        *
+        * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+        * @param aImplementationUid Uid of the implementation to load
+        */
+        void LoadSyncL( CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray );
+
+        /**
+        * Sets observer for this loader. Only one observer per loader in one
+        * time is possible.
+        */
+        void SetObserver(MSamplerPluginLoadObserver* aObserver);
+
+        /**
+        * Aborts asynchronous loading of the GS plug-ins.
+        */
+        void AbortAsyncLoad();
+
+
+        /**
+        * Sorts the plugin array.
+        *
+        * Sorting criterias:
+        *
+        * 1. Order number if provider category is Internal.
+        * 2. Provider category. Precedence as follows:
+        *       1. KGSPluginProviderInternal
+        *       2. EGSPluginProviderOEM
+        *       3. EGSPluginProviderOperator
+        *       4. EGSPluginProvider3rdParty
+        * 3. Alphabetical
+        *
+        * @param aPlugins The array which will be sorted.
+        */
+        void SortPluginsL( CArrayPtrFlat<CSamplerPluginInterface>* aPlugins );
+
+    private: // Internal methods
+
+        /**
+        * Starts loading next plugin.
+        */
+        void LoadNextPluginL();
+
+        /**
+        * Creates a plugin instance from given UID. Ownership is transferred.
+        */
+        CSamplerPluginInterface& CreatePluginInstanceL( 
+                const CImplementationInformation& aImpInfo );
+
+        /**
+        * Notifies MPluginLoadObserver.
+        */
+        void NotifyProgress();
+
+        /**
+        * Notifies MPluginLoadObserver.
+        */
+        void NotifyFinished();
+
+        /**
+        * Wait for the next round of CActive execution.
+        */
+        void CompleteOwnRequest();
+
+        // Insertion function used by sorting:
+
+        /**
+        * Inserts plugin in the correct position in the array using sorting 
+        * criterias. Assumes aPlugins is ordered.
+        *
+        * @param aPlugin The plugin to be inserted.
+        * @param aPlugins Array in which the plugin is inserted into the
+        *        corresponding location.
+        */
+        void InsertPluginInOrderL(
+            CSamplerPluginInterface* aPlugin,
+            CArrayPtrFlat<CSamplerPluginInterface>* aPlugins );
+
+        // Comparison functions:
+
+        /**
+        * Compares plugins according to comparison criterias.
+        * 
+        * Note: GS internal comparison constants such as KGSComparisonEqual are 
+        * different from the ones outputted by this function. This is because 
+        * this function is also usable by RArray sort -functionality but BC 
+        * cannot be broken in GS.
+        * 
+        * @return Negative value: If aFirst before aSecond.
+        *                      0: If equal.
+        *         Positive value: If aSecond before aFirst.
+        */
+        static TInt Compare( const CSamplerPluginInterface& aFirst,    
+                             const CSamplerPluginInterface& aSecond );
+
+        /**
+        *
+        * @return   KGSComparisonEqual  = equal indexes
+        *           KGSComparisonBefore = aFirst is before aSecond
+        *           KGSComparisonAfter  = aFirst is after aSecond
+        */
+
+        static TInt CompareIndex( 
+                const CSamplerPluginInterface& aFirst,
+                const CSamplerPluginInterface& aSecond );
+
+    private: // Utility methods
+
+        /**
+        * Parses descriptor to UID.
+        */
+        static TInt ParseToUid( const TDesC8& aSource, TUid& aTarget );
+
+        /**
+        * Parsers plugin's order number
+        */
+        static TInt ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber );
+
+    private: // From CActive
+
+        /**
+        * See base class.
+        */
+        void RunL();
+
+        /**
+        * See base class.
+        */
+        TInt RunError( TInt aError );
+
+        /**
+        * See base class.
+        */
+        void DoCancel();
+
+    private: // Data
+        // Pluginloader goes through this array and loads the plugins into
+        // iPluginArray if they fulfill the criterias.
+        RImplInfoPtrArray iImplInfoArray;
+
+        // Used as an iterator to maintain location in iImplInfoArray.
+        TInt iImplInfoArrayIterator;
+
+        // Array of loaded plugins.Plugins are owned by iAppUi. Only the array
+        // pointers are owned by this class and therefore only reset array.
+        CArrayPtrFlat<CSamplerPluginInterface>* iPluginArray;
+
+        // Pointer to observer. Not owned.
+        MSamplerPluginLoadObserver* iObserver;
+
+        // Number of RunL calls.
+        TInt iRunLDebugCount;
+
+    };
+
+
+/**
+* Interface for SamplerPluginLoader observer. MSamplerPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+
+class MSamplerPluginLoadObserver
+    {
+    public: // Enums
+        enum KSamplerPluginLoaderStatus
+            {
+            // One plugin loaded successfully, continue to next.
+            ESamplerSuccess,
+            // Loading one plugin failed, contiue to next.
+            ESamplerFail,
+            // Client called AbortAsyncLoad(), finished loading.
+            ESamplerAborted,
+            // All plugins loaded successfully, finished loading.
+            ESamplerFinished,
+            // Severe error with loader, finished loading.
+            ESamplerError
+            };
+
+    public: // New
+
+        //CSamplerPluginLoader calls this function when each plug-in is loaded or
+        //loading is finished..
+        
+        IMPORT_C virtual void HandlePluginLoaded(
+            KSamplerPluginLoaderStatus aStatus ) = 0;
+    };
+
+
+#endif // SAMPLERPLUGINLOADER_H
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/WriterController.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __WRITERCONTROLLER_H__
+#define __WRITERCONTROLLER_H__
+
+// system includes
+#include <utf.h>
+#include <e32cmn.h>
+
+
+// The user-interface to the sampling device driver sued by the profiling engine
+// user includes
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/WriterPluginInterface.h>
+
+#include "WriterPluginLoader.h"
+
+/*
+ *	Forward declarations
+ */
+class TBapBuf;
+class CWriterPluginLoader;
+class CWriterPluginInterface;
+
+/**
+ * The writer controller for handling the available Data writer plugins.
+ */
+  
+class CWriterController : public CBase, MWriterPluginLoadObserver
+	{
+	
+public:
+	static CWriterController* NewL(CProfilerSampleStream& aStream);
+	void ConstructL();
+	
+	CWriterController(CProfilerSampleStream& aStream);
+    ~CWriterController();
+	
+	/** 
+	 * 
+	 * Methods for user mode sampling
+	 * 
+	 **/
+	
+	/** Initialise the user mode samplers **/					
+	void InitialiseWriterListL();
+	
+	/* Overrider of MSamplerPluginLoaderObserver class **/
+	void HandlePluginLoaded( KWriterPluginLoaderStatus /*aStatus*/ );
+	
+	/* returns the matching plugin Uid */
+	TUid GetPluginUID(TInt traceId);
+	
+	CWriterPluginInterface* GetActiveWriter();
+	
+	 /** Returns the sampler type (kernel/user) **/
+	TUint32 GetWriterType(TUint32 samplerId);
+
+	/** Set additional settings for a trace **/			
+	TInt AdditionalUserTraceSettings(TInt traceId, TInt settings);
+
+	/** Set data stream for samplers **/
+	//void SetSampleStream(RProfilerSampleStream* iStream);
+
+	TInt StartSelectedPlugin();
+
+	void StopSelectedPlugin();
+
+	/** Set selected plugin active **/
+	void SetPluginActive(TUid uid, const TWriterPluginValueKeys aKey);
+
+	TInt SetPluginSettings(TUid aUid, TDes& aDes);
+	
+	/** Get settings for a specific plugin **/
+	void GetPluginSettings(TUid uid, TDes& aVal);
+	
+	/** Request stream read **/
+	//void FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus);
+	
+	CWriterPluginInterface* GetPlugin(TUid aUid);
+	
+	CArrayPtrFlat<CWriterPluginInterface>* GetPluginList();
+	
+	void InitialisePluginStream();
+public:
+    CArrayPtrFlat<CWriterPluginInterface>* iPluginArray;
+    
+    // Asynchronous loader for the writer plug-ins.
+    CWriterPluginLoader* iPluginLoader;
+    
+    // UID of the selected plugin in the container's lbx.
+    TUid iSelectedPluginUid;
+    
+    CProfilerSampleStream& iStream;
+};
+
+	
+#endif	// __WRITERCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/WriterPluginLoader.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,302 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef  WRITERPLUGINLOADER_H
+#define  WRITERPLUGINLOADER_H
+
+// INCLUDES
+#include    <e32base.h>
+#include    <ecom/implementationinformation.h>
+#include 	<piprofiler/ProfilerConfig.h>
+#include 	<piprofiler/WriterPluginInterface.h>
+#include    <piprofiler/ProfilerTraces.h>
+
+// CONSTANTS
+
+// Value for a to b comparison result when logically a == b.
+const TInt KWriterComparisonEqual     = 0;
+
+// Value for a to b comparison result when logically a < b.
+const TInt KWriterComparisonBefore    = -1;
+
+// Value for a to b comparison result when logically a > b.
+const TInt KWriterComparisonAfter     = 1;
+
+// CLASS DEFINITIONS
+class CWriterPluginInterface;
+class MWriterPluginLoadObserver;
+class REComSession;
+
+/**
+* CWriterPluginLoader. Mechanism used to load plugins asynchronously. Uses
+* MWriterPluginLoadObserver as a callback.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+class CWriterPluginLoader : public CActive
+    {
+    public:  // Constructor and destructor
+
+        /**
+        * Two-phased constructor.
+        *
+        * @param aAppUi Pointer to application UI. Does not take ownership.
+        */
+        static CWriterPluginLoader* NewL();
+
+        /**
+        * Destructor
+        */
+        ~CWriterPluginLoader();
+
+    private: // Internal construction
+
+        /**
+        * Default C++ contructor
+        */
+        CWriterPluginLoader();
+
+        /**
+        * Symbian OS default constructor
+        * @return void
+        */
+        void ConstructL();
+
+    public: // API
+
+        /**
+        * Starts loading GS plug-ins asynchronously. Will call
+        * MWriterPluginLoadObserver::HandlePluginLoaded() each time a plug-in is
+        * loaded and when all plugins are loaded.
+        *
+        * CWriterPluginLoader transfers the ownership of each loaded plugin view to
+        * CAknViewAppUi. It is client's responsibility to remove the views from
+        * CAknViewAppUi and delete the plugins if necessary.
+        *
+        * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+        * @param aParentUid Uid of the parent. Only children of this parent
+        *        will be loaded.
+        * @param aPluginArray An array for the loaded GS plug-ins.
+        *        CWriterPluginLoader does not take the ownership of this array.
+        */
+        void LoadAsyncL( CArrayPtrFlat<CWriterPluginInterface>* aPluginArray );
+
+        /**
+        * Load a specific plugin instance synchronously.
+        *
+        * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+        * @param aImplementationUid Uid of the implementation to load
+        */
+        CWriterPluginInterface& LoadSyncL( TUid aImplementationUid );
+
+        /**
+        * Sets observer for this loader. Only one observer per loader in one
+        * time is possible.
+        */
+        void SetObserver(MWriterPluginLoadObserver* aObserver);
+
+        /**
+        * Aborts asynchronous loading of the GS plug-ins.
+        */
+        void AbortAsyncLoad();
+
+        /**
+        * Sorts the plugin array.
+        *
+        * Sorting criterias:
+        *
+        * 1. Order number if provider category is Internal.
+        * 2. Provider category. Precedence as follows:
+        * 3. Alphabetical
+        *
+        * @param aPlugins The array which will be sorted.
+        */
+        void SortPluginsL( CArrayPtrFlat<CWriterPluginInterface>* aPlugins );
+
+    private: // Internal methods
+
+        /**
+        * Starts loading next plugin.
+        */
+        void LoadNextPluginL();
+
+        /**
+        * Creates a plugin instance from given UID. Ownership is transferred.
+        */
+        CWriterPluginInterface& CreatePluginInstanceL( 
+                const CImplementationInformation& aImpInfo );
+
+        /**
+        * Notifies MGSPluginLoadObserver.
+        */
+        void NotifyProgress();
+
+        /**
+        * Notifies MGSPluginLoadObserver.
+        */
+        void NotifyFinished();
+
+        /**
+        * Wait for the next round of CActive execution.
+        */
+        void CompleteOwnRequest();
+
+        // Insertion function used by sorting:
+
+        /**
+        * Inserts plugin in the correct position in the array using sorting 
+        * criterias. Assumes aPlugins is ordered.
+        *
+        * @param aPlugin The plugin to be inserted.
+        * @param aPlugins Array in which the plugin is inserted into the
+        *        corresponding location.
+        */
+        void InsertPluginInOrderL(
+        		CWriterPluginInterface* aPlugin,
+            CArrayPtrFlat<CWriterPluginInterface>* aPlugins );
+
+        // Comparison functions:
+
+        /**
+        * Compares plugins according to comparison criterias.
+        * 
+        * Note: GS internal comparison constants such as KGSComparisonEqual are 
+        * different from the ones outputted by this function. This is because 
+        * this function is also usable by RArray sort -functionality but BC 
+        * cannot be broken in GS.
+        * 
+        * @return Negative value: If aFirst before aSecond.
+        *                      0: If equal.
+        *         Positive value: If aSecond before aFirst.
+        */
+        static TInt Compare( const CWriterPluginInterface& aFirst,    
+                             const CWriterPluginInterface& aSecond );
+
+        /**
+        *
+        * @return   KGSComparisonEqual  = equal indexes
+        *           KGSComparisonBefore = aFirst is before aSecond
+        *           KGSComparisonAfter  = aFirst is after aSecond
+        */
+
+        static TInt CompareIndex( 
+                const CWriterPluginInterface& aFirst,
+                const CWriterPluginInterface& aSecond );
+
+    private: // Utility methods
+
+        /**
+        * Parses descriptor to UID.
+        */
+        static TInt ParseToUid( const TDesC8& aSource, TUid& aTarget );
+
+        /**
+        * Parsers plugin's order number
+        */
+        static TInt ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber );
+
+        /**
+        * Print debug information.
+        */
+        static void PrintInfoDebug( const CImplementationInformation& aInfo,
+                                    TInt aIterator,
+                                    TInt aPluginCount );
+        
+        /**
+         * Display loading error popup message.
+         */
+        void DisplayErrorPopupL( TInt aError, 
+                                 const CImplementationInformation* aInfo );
+        
+    private: // From CActive
+
+        /**
+        * See base class.
+        */
+        void RunL();
+
+        /**
+        * See base class.
+        */
+        TInt RunError( TInt aError );
+
+        /**
+        * See base class.
+        */
+        void DoCancel();
+
+    private: // Data
+
+
+        // Pluginloader goes through this array and loads the plugins into
+        // iPluginArray if they fulfill the criterias.
+        RImplInfoPtrArray iImplInfoArray;
+
+        // Used as an iterator to maintain location in iImplInfoArray.
+        TInt iImplInfoArrayIterator;
+
+        // Array of loaded plugins.Plugins are owned by iAppUi. Only the array
+        // pointers are owned by this class and therefore only reset array.
+        CArrayPtrFlat<CWriterPluginInterface>* iPluginArray;
+
+        // Pointer to observer. Not owned.
+        MWriterPluginLoadObserver* iObserver;
+
+        // Number of RunL calls.
+        TInt iRunLDebugCount;
+    };
+
+
+/**
+* Interface for WriterPluginLoader observer. MWriterPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+
+class MWriterPluginLoadObserver
+    {
+    public: // Enums
+        enum KWriterPluginLoaderStatus
+            {
+            // One plugin loaded successfully, continue to next.
+            EWriterSuccess,
+            // Loading one plugin failed, contiue to next.
+            EWriterFail,
+            // Client called AbortAsyncLoad(), finished loading.
+            EWriterAborted,
+            // All plugins loaded successfully, finished loading.
+            EWriterFinished,
+            // Severe error with loader, finished loading.
+            EWriterError
+            };
+
+    public: // New
+
+        //CWriterPluginLoader calls this function when each plug-in is loaded or
+        //loading is finished..
+        
+        IMPORT_C virtual void HandlePluginLoaded(
+            KWriterPluginLoaderStatus aStatus ) = 0;
+    };
+
+
+#endif // WRITERPLUGINLOADER_H
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerEngine.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1515 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <e32cons.h>
+#include <e32base.h>
+#include <f32file.h>
+#include <c32comm.h>
+#include <s32file.h>
+#include <pathinfo.h>
+#include <s32mem.h>
+#include <bautils.h>
+#include <sysutil.h>
+#include <piprofiler/ProfilerConfig.h>
+#include "ProfilerEngine.h"
+#include <piprofiler/ProfilerTraces.h>
+
+// properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+	{
+	EProfilerEngineStatus = 8,
+	EProfilerErrorStatus
+	};
+
+static _LIT_SECURITY_POLICY_PASS( KAllowAllPolicy );
+
+// CONSTANTS 
+const TInt KStreamBufferSize = 32768;
+const TInt KSavedLineCount = 64;
+const TInt KFileNameBufSize = 128;
+// Use this UID if plugin belongs to DebOutWriterPlugin:
+const TUid KDebOutWriterPluginUid = { 0x2001E5BA };
+// Use this UID if plugin belongs to MmcOutWriterPlugin:
+const TUid KDiskWriterPluginUid = { 0x2001E5BB };
+
+// LITERALS
+_LIT8(KGenericTraceOutput, "output_type");
+_LIT8(KGenericTraceFilePrefix, "file_prefix");
+_LIT8(KGenericTraceFileSaveDrive, "save_file_location");
+_LIT8(KGenericTimedProfilingPeriod, "profiling_period");
+_LIT8(KEquals, "=");
+_LIT8(KNewLineSeparator, "\n");
+_LIT8(KProfilerVersionTag, "version");
+_LIT8(KEndMark, "[end]");
+_LIT8(KOutputToDebugOutput, "debug_output");
+
+/** 
+ * 
+ * The controller class used to provide the Profiler functions. 
+ * This runs as a server in the engine thread
+ * 
+ */
+class CPServer : public CServer2, public MProfilerController
+    {
+public:
+    static MProfilerController*		NewL(TInt aPriority, MProfilerEngine& aEngine);
+
+private:
+                        CPServer(TInt aPriority, MProfilerEngine& aEngine);
+    void				Release();
+    CSession2*			NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
+    
+public:
+    static TInt         iClientCount;
+    };
+
+TInt CPServer::iClientCount = 0;
+
+// The session class used by the server controller
+class CPSession : public CSession2
+    {
+private:
+    inline const CPServer&	Server() const;
+    void					ServiceL(const RMessage2& aMessage);
+    };
+
+/*
+ *
+ *	CProfiler class implementation
+ *
+ */
+// --------------------------------------------------------------------------------------------
+CProfiler* CProfiler::NewLC(const TDesC& aSettingsFile)
+    {
+	CProfiler* self = new(ELeave) CProfiler(aSettingsFile);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+CProfiler::CProfiler(const TDesC& aSettingsFile) : 
+    iSettingsFileLocation(aSettingsFile)
+	{
+	// define property for Profiler Engine status, UI may read it for control purposes
+	if ( RProperty::Define(KEngineStatusPropertyCat, 
+	        EProfilerEngineStatus, 
+	        RProperty::EInt, 
+	        KAllowAllPolicy, 
+	        KAllowAllPolicy, 
+	        0) != KErrAlreadyExists )
+	    {
+	    LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
+	    }
+
+	if ( RProperty::Define(KEngineStatusPropertyCat, 
+	        EProfilerErrorStatus, 
+            RProperty::EInt, 
+            KAllowAllPolicy, 
+            KAllowAllPolicy, 
+            0) != KErrAlreadyExists )
+        {
+        LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
+        }
+
+	// attach to own property
+	iEngineStatus.Attach(KEngineStatusPropertyCat, EProfilerEngineStatus);
+	// set status idle
+	iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, RProfiler::EIdle);
+	
+    // attach to own property
+    iUpdateStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus);
+    // set status idle
+    iUpdateStatus.Set(KEngineStatusPropertyCat, EProfilerErrorStatus, EFalse);
+	}
+
+// --------------------------------------------------------------------------------------------
+CProfiler::~CProfiler()
+    {
+	LOGTEXT(_L("CProfiler::~CProfiler - Enter"));
+
+	// delete error checker
+    if(iErrorChecker)
+        {
+        iErrorChecker->Cancel();
+        delete iErrorChecker;
+        iErrorChecker = NULL;
+        }
+	
+	// delete settings array
+	if(iDefaultSamplerAttributesArray)
+	    {
+	    iDefaultSamplerAttributesArray->Reset();
+	    delete iDefaultSamplerAttributesArray;
+	    iDefaultSamplerAttributesArray = NULL;
+	    }
+
+    // delete settings file raw line array
+    if(iSavedLineArray)
+        {
+        iSavedLineArray->Reset();
+        delete iSavedLineArray;
+        iSavedLineArray = NULL;
+        }
+		
+	// delete sampler controller, cleans up the sampler plugin instances
+	if(iSamplerHandler)
+		{
+		delete iSamplerHandler;
+		iSamplerHandler = NULL;
+		}
+	// delete writer controller, cleans up the writer plugin instances
+	if(iWriterHandler)
+		{
+		delete iWriterHandler;
+		iWriterHandler = NULL;
+		}
+
+    // delete user side sampler stream 
+	if(iUserStream)
+		{
+		delete iUserStream;
+		iUserStream = NULL;
+		}
+
+	// close engine status property
+	iEngineStatus.Close();
+	if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerEngineStatus) != KErrNotFound)
+	    {
+	    LOGTEXT(_L("CProfiler::~CProfiler - cannot close status property"));
+	    }
+    // close engine update property
+    iUpdateStatus.Close();
+    if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerErrorStatus) != KErrNotFound)
+        {
+        LOGTEXT(_L("CProfiler::~CProfiler - cannot close update property"));
+        }
+    
+    // close server process
+    if (iServer)
+        {
+        LOGTEXT(_L("CProfiler::~CProfiler - Releasing server"));
+        iServer->Release();        
+        }
+    
+    if( iTimer )
+        {
+        iTimer->Cancel();
+        delete iTimer;
+        iTimer = 0;
+        }
+    
+	LOGTEXT(_L("CProfiler::~CProfiler - Finished"));
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::ConstructL()
+    {
+	LOGTEXT(_L("CProfiler::ConstructL - Enter"));
+	TInt err(0);
+	TLex lex;
+	
+	if ( iSettingsFileLocation.CompareF(KNullDesC) != 0 )
+	    {
+        lex=(iSettingsFileLocation);
+        // parse the first command line argument, the command itself
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            // there is another item in the list
+            TPtrC filename = lex.MarkedToken();
+            LOGSTRING2("filename %S", &filename);
+            lex.SkipSpace();
+            lex.Mark();
+            lex.SkipCharacters();
+            if(lex.TokenLength() != 0)
+                {
+                TPtrC boot = lex.MarkedToken();
+                LOGTEXT(_L("boot mode"));
+                }
+            }
+	    }
+	
+    // create new sampler stream instance
+    iUserStream = CProfilerSampleStream::NewL(KStreamBufferSize);
+    if(!iUserStream)
+        {
+        LOGTEXT(_L("Profiler engine cannot reserve memory"));
+        User::Leave(KErrCancel);   // operation cancelled
+        }
+	
+    // engine status checker
+    iErrorChecker = CProfilerErrorChecker::NewL();
+    iErrorChecker->SetObserver(this);
+
+	// create and initiate plug-in controller instances
+    iSamplerHandler = CSamplerController::NewL(*iUserStream);
+    iWriterHandler = CWriterController::NewL(*iUserStream);
+    
+    iWriterHandler->InitialiseWriterListL();
+    
+    // set engine as an observer to sampler controller to get the notification of plugin load has ended
+    iSamplerHandler->SetObserver(this);
+    
+    // default settings from sampler plugins, maximum 20 sampler plugins
+    iDefaultSamplerAttributesArray = new(ELeave) CArrayFixFlat<TSamplerAttributes>(20); 
+    
+    // set profiler status to initializing
+    iState = RProfiler::EInitializing;
+	iEngineStatus.Set(RProfiler::EInitializing);
+	
+	// set default general settings, will be overdriven if changed in settings file
+	iGeneralAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+	iGeneralAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+	iGeneralAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+	iGeneralAttributes.iTimedSamplingPeriod = KDefaultTimedSamplingPeriod;
+	
+	RThread me;
+	
+	me.SetPriority(EPriorityRealTime);
+
+	err = KErrGeneral;
+	TInt count = 0;
+
+	while(err != KErrNone && count < 30)
+	    {
+		err = User::RenameThread(KProfilerName);
+		if(err != KErrNone)
+		    {
+		    LOGSTRING2("CProfiler: error renaming the thread, err %d", err);
+			User::Leave(err);
+		    }
+		else break;
+	    }
+
+	// set settings file loading preferences
+	iSettingsFileLoaded = EFalse;
+
+	// change status property to idle since initialization successfull
+	iState = RProfiler::EIdle;
+	if( iEngineStatus.Set((TInt)RProfiler::EIdle) != KErrNone )
+	    {
+	    LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
+	    }
+
+    if( iUpdateStatus.Set(EFalse) != KErrNone )
+        {
+        LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
+        }
+
+	// create a server instance for clients to communicate with 
+	iServer = CPServer::NewL(10,*this);
+	
+	// close the handle 
+	me.Close();
+	
+	iTimer = CProfilerTimer::NewL(CActive::EPriorityStandard, *this);
+	
+	LOGTEXT(_L("CProfiler::ConstructL - Exit"));
+	
+    }
+
+CProfilerSampleStream* CProfiler::GetSamplerStream()
+    {
+    return iUserStream;
+    }
+
+void CProfiler::HandleSamplerControllerReadyL()
+    {
+    // load settings
+    // check if settings file already loaded
+    if(!iSettingsFileLoaded)
+        {
+        // load default settings file
+        LoadSettingsL();
+
+        iSettingsFileLoaded = ETrue;
+        }
+    
+    // notify engine's launcher(UI or PIProfilerLauncher) to continue launch
+    RProcess::Rendezvous(KErrNone); 
+    }
+
+void CProfiler::NotifyRequesterForSettingsUpdate()
+    {
+    // set update status P&S property true => update needed on UI side
+    iUpdateStatus.Set(ETrue);
+    }
+
+void CProfiler::HandleProfilerErrorChangeL(TInt aError)
+    {
+    LOGSTRING2("CProfiler::HandleProfilerErrorChangeL() - error received, %d", aError);
+    
+    // check if profiler running
+    if(iState == RProfiler::ERunning)
+        {
+        // stop profiler if error occurred during the trace
+        iEngineStatus.Set(aError);
+        
+        // stop samplers, NOTE! Writer plugins not stopped since 
+        iSamplerHandler->StopSamplerPlugins();
+
+        // stop debug output plugin and write the rest of the trace data to output
+        if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)   
+            {
+            // write the rest of trace data only if debug output selected
+            iWriterHandler->StopSelectedPlugin();
+            }
+        LOGSTRING2("CProfiler::HandleProfilerErrorChangeL - sampling stopped, going to state %d", RProfiler::EIdle);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// Gets a value from settings file for certain attribute.
+// ----------------------------------------------------------------------------
+void CProfiler::DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TDes8& aValue)
+    {
+    LOGTEXT(_L("CProfiler::DoGetValueFromSettingsFile()"));
+    _LIT8(KSettingItemSeparator, "=");
+    
+    // read a line of given array
+    for (TInt i=0; i<aLineArray->MdcaCount(); i++)
+        {
+        // check if this line has a separator
+        TInt sepPos = aLineArray->MdcaPoint(i).Find(KSettingItemSeparator);
+        if (sepPos > 0)
+            {
+            // check that the element matches
+            if (aLineArray->MdcaPoint(i).Left(sepPos).CompareF(aAttribute) == 0)
+                {
+                // get the value
+                aValue.Copy(aLineArray->MdcaPoint(i).Right(aLineArray->MdcaPoint(i).Length()-sepPos-1));
+                break;
+                }
+            }
+        }
+    }
+
+void CProfiler::DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TInt& aValue)
+    {
+    LOGTEXT(_L("CProfiler::DoGetValueFromSettingsFile()"));
+    _LIT8(KSettingItemSeparator, "=");
+    
+    // read a line of given array
+    for (TInt i=0; i<aLineArray->MdcaCount(); i++)
+        {
+        // check if this line has a separator
+        TInt sepPos = aLineArray->MdcaPoint(i).Find(KSettingItemSeparator);
+        if (sepPos > 0)
+            {
+            // check that the element matches
+            if (aLineArray->MdcaPoint(i).Left(sepPos).CompareF(aAttribute) == 0)
+                {
+                // get the value                
+                TLex8 parser(aLineArray->MdcaPoint(i).Right(aLineArray->MdcaPoint(i).Length()-sepPos-1));
+                parser.Val(aValue);
+                break;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::GetSamplerAttributesL(const RMessage2& aMessage)
+    {
+    TInt err(KErrNone);
+    TInt pos(0);
+
+    // get sampler count
+    TInt count(iDefaultSamplerAttributesArray->Count());
+
+    // write each of the default sampler plugin setting attributes over client-server session 
+    for (TInt i(0); i<count; ++i)
+       {
+       TSamplerAttributes attr = iDefaultSamplerAttributesArray->At(i);
+       TPckgC<TSamplerAttributes> attrPckg(attr);
+       
+       // write a TSamplerAttributes container at a time
+       aMessage.WriteL(0, attrPckg, pos);
+       pos += attrPckg.Length();
+       }
+
+    aMessage.Complete(err);
+    return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::SetSamplerAttributesL(const RMessage2& aMessage)
+    {
+    TSamplerAttributes attr;
+    TPckg<TSamplerAttributes> inAttr(attr);
+    
+    TInt err = aMessage.Read(0, inAttr, 0);    
+    
+    // apply the changes directly to a plugin
+    iSamplerHandler->SetSamplerSettingsL(attr.iUid, attr);
+    
+    aMessage.Complete(err);
+    return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::GetGeneralAttributesL(const RMessage2& aMessage)
+    {
+    TPckgBuf<TGeneralAttributes> generalSettings( iGeneralAttributes );
+    
+    // write general attributes over client-server session
+    TInt err = aMessage.Write(0, generalSettings);
+    
+    aMessage.Complete(err);
+    return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::SetGeneralAttributesL(const RMessage2& aMessage)
+    {
+    // read the general settings from message
+    TGeneralAttributes attr;
+    TPckg<TGeneralAttributes> inPckg(attr);
+    TInt err = aMessage.Read(0, inPckg, 0);
+    
+    // copy to the general attributes
+    iGeneralAttributes.iSaveFileDrive.Copy(attr.iSaveFileDrive);
+    iGeneralAttributes.iTraceFilePrefix.Copy(attr.iTraceFilePrefix);
+    iGeneralAttributes.iTraceOutput.Copy(attr.iTraceOutput);
+    iGeneralAttributes.iTimedSamplingPeriod = attr.iTimedSamplingPeriod;
+    
+    aMessage.Complete(err);
+    return err;
+    }
+
+TInt CProfiler::GetSamplerAttributeCountL(const RMessage2& aMessage)
+    {
+    // get the plugin array count and wrap it to TPckgBuf<>
+    TPckgBuf<TInt> attributeCount(iDefaultSamplerAttributesArray->Count());
+    
+    // write general attributes over client-server session
+    TInt err = aMessage.Write(0, attributeCount);
+    
+    aMessage.Complete(err);
+    return err;
+    }
+
+TInt CProfiler::RefreshStatus(const RMessage2& aMessage)
+    {
+    TInt err(KErrNone);
+    
+    // update profiler status for requester
+    iEngineStatus.Set(iState);
+    
+    aMessage.Complete(err);
+    return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::LoadSettingsL(/*const TDesC& configFile*/)
+    {
+	RFs fileServer;
+	RFile file;
+	TInt err(KErrNone);
+    
+	// connect to file server 
+	err = fileServer.Connect();
+	
+	// check if file server can be connected
+	if (err != KErrNone)
+	    {
+		// file server couldn't be connected
+		return KErrGeneral;
+	    }
+
+	// check if settings file location length reasonable
+	if ( iSettingsFileLocation.CompareF(KNullDesC) == 0 )
+	    {
+		// open the file with the default path and name
+		TBuf<256> pathAndName;
+		pathAndName.Append(PathInfo::PhoneMemoryRootPath());
+		pathAndName.Append(KProfilerSettingsFileName);
+		iSettingsFileLocation.Copy(pathAndName);
+		LOGTEXT(_L("CProfiler::LoadSettings - Opening settings file with name (with the default path)"));
+		LOGTEXT(pathAndName);
+	    }
+
+    // open the file with the given path and name
+    err = file.Open(fileServer,iSettingsFileLocation,EFileRead);
+
+	
+	// check if RFile::Open() returned error
+	if (err != KErrNone)
+	    {
+		// file couldn't be opened
+		LOGTEXT(_L("CProfiler::LoadSettings - Failed to open settings, using default"));
+
+		// check if settings already loaded
+		if(iDefaultSamplerAttributesArray->Count() > 0)
+		    {
+		    // reset default settings array
+		    iDefaultSamplerAttributesArray->Reset();
+		    }
+		
+		// load default settings, instead of settings file ones
+		iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+		
+		fileServer.Close();
+		return KErrNone;
+	    }
+	
+	// initialize iSavedLineArray, initial settings file lines 64
+	if(iSavedLineArray)
+	    {
+        iSavedLineArray->Reset();
+	    }
+	else
+	    {
+        iSavedLineArray = new (ELeave) CDesC8ArrayFlat(KSavedLineCount);
+	    }
+	
+	iSavedLinesCount = KSavedLineCount;
+	
+    // get size of the file
+    TInt fileSize(0);
+    err = file.Size(fileSize);
+    // check if an error occurred reading the file size
+    if(err != KErrNone)
+        {
+        return KErrGeneral; // could not find the size
+        }
+        
+    // sanity check for the file size
+    if (fileSize < 3 || fileSize > 20000)
+        {
+        fileSize = KSettingsFileSize;
+        return KErrNotSupported;
+        }
+    
+	// read the contents of the file to buffer. 
+	iSettingsBuffer.Zero();
+	file.Read(iSettingsBuffer, fileSize);
+	file.Close();
+	fileServer.Close();
+	LOGSTRING2("CProfiler::LoadSettings: read %d bytes",iSettingsBuffer.Length());
+
+	// append end mark "[end]"
+    iSettingsBuffer.Append(KEndMark);
+	// force an ending newline
+	iSettingsBuffer.Append('\n');
+
+	// next fill the saved settings array (CDesC8ArrayFlat) for further comparison with changes and default values
+    TBuf8<384> tmpBuf;
+    TInt lineCount(0);
+    TBool commentFound(EFalse);
+    for (TInt i(0); i<iSettingsBuffer.Length(); i++)  // loop all chars
+        {
+        // if new line char found, create a new text line
+        if (iSettingsBuffer[i]=='\r' || iSettingsBuffer[i]=='\n')
+            {
+            // check if collected string has reasonable length
+            if (tmpBuf.Length() > 0)
+                {
+                // remove extra spaces
+                tmpBuf.TrimAll();
+                // check if the size of the array too small
+                if(lineCount >= iSavedLinesCount)
+                    {
+                    iSavedLineArray->ExpandL(20);   // expand by 20 lines
+                    iSavedLinesCount += 20;
+                    }
+                iSavedLineArray->AppendL(tmpBuf);
+                tmpBuf.Copy(KNullDesC8);
+                lineCount++;
+                }
+            commentFound = EFalse;
+            }
+        // check if comment mark ';' is found on the line, skip the rest of the line
+        else if(iSettingsBuffer[i]==';')
+            {
+            commentFound = ETrue;
+            }
+        // otherwise append a char to the temp line buffer if it is a wanted ASCII char
+        else if (iSettingsBuffer[i]>=32 && iSettingsBuffer[i]<=127 && !commentFound)
+            {
+            tmpBuf.Append(iSettingsBuffer[i]);
+            }
+        }
+    
+    // empty tmpBuf
+    tmpBuf.Copy(KNullDesC8);
+    // check settings file version
+    DoGetValueFromSettingsArray(iSavedLineArray, KProfilerVersionTag, tmpBuf); 
+
+    TBuf8<32> version;
+    version.Copy(PROFILER_VERSION_SHORT);
+    
+    // check if settings file version is 
+    if(tmpBuf.CompareF(version) >= 0)
+        {
+        // update general attributes
+        UpdateSavedGeneralAttributes(iSavedLineArray);
+        
+        // update settings to sampler plugins and save the attributes to default array
+        iSamplerHandler->UpdateSavedSamplerAttributesL(iSavedLineArray, iDefaultSamplerAttributesArray);
+        }
+    else
+        {
+        // check if settings already loaded
+        if(iDefaultSamplerAttributesArray)
+            {
+            // reset default settings array
+            iDefaultSamplerAttributesArray->Reset();
+
+			// get the default settings if settings file version too old
+			iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+			}
+        }
+    
+	return err; 
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::UpdateSavedGeneralAttributes(CDesC8ArrayFlat* aSavedAttributes)
+    {
+    // get saved general settings
+    DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceOutput, iGeneralAttributes.iTraceOutput);
+    DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFilePrefix, iGeneralAttributes.iTraceFilePrefix);
+    DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFileSaveDrive, iGeneralAttributes.iSaveFileDrive);
+    DoGetValueFromSettingsArray(aSavedAttributes, KGenericTimedProfilingPeriod, iGeneralAttributes.iTimedSamplingPeriod);
+    }
+
+TBool CProfiler::CheckLocationSanity(RFs& fs, const TDesC8& aLocation)
+    {
+    TBool ret(EFalse);
+    TBool noDiskSpace(EFalse);
+    TBuf<32> drive;
+    
+    CnvUtfConverter::ConvertToUnicodeFromUtf8(drive, aLocation);
+    TDriveUnit driveUnit = TDriveUnit(drive);
+    
+    // check that the root folder is correct
+    if (drive.Length() > 2 && BaflUtils::CheckFolder(fs, drive.Left(3)) == KErrNone)
+        {
+        // test available disk space 
+        TRAP_IGNORE((noDiskSpace = SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, driveUnit)));
+        if(!noDiskSpace)
+            ret = ETrue;
+        }
+    
+    return ret;
+    }
+
+TInt CProfiler::HandleGeneralSettingsChange()
+    {
+    // local literals
+    _LIT8(KBackSlash, "\\");
+    _LIT8(KTraceFileExtension, ".dat");
+    
+    TBuf8<KFileNameBufSize> fileNameBuf;
+    TBuf8<10> number;
+    TInt result(0);
+    TInt index(1);
+    TInt hashLocation(0);
+    TParse parse;
+
+    // check if plugin writer changed
+    if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
+        {
+        iWriterHandler->SetPluginActive( KDebOutWriterPluginUid, EWriterPluginEnabled );
+        }
+    else
+        {
+        RFs fileServer;
+        RFile file;
+        
+        // connect to the file server
+        result = fileServer.Connect();
+        if(result == KErrNone)
+            {
+            // disk writer plugin will be activated
+            iWriterHandler->SetPluginActive( KDiskWriterPluginUid, EWriterPluginEnabled );
+            
+            // fix the trace data file location as well
+            iTotalPrefix.Zero();
+            iTotalPrefix.Append(iGeneralAttributes.iSaveFileDrive);
+            
+            // check that trace file location sane
+            if(!CProfiler::CheckLocationSanity(fileServer, iTotalPrefix))
+                {
+                fileServer.Close();
+                return KErrPathNotFound;
+                }
+            
+            // remove extra spaces
+            iTotalPrefix.TrimAll();
+            
+            // check the directory contains a trailing backlash
+            if(iTotalPrefix.Right(1) != _L8("\\") && 
+                    iTotalPrefix.Right(1) != _L8("/"))
+                {
+                // append backslash to end
+                iTotalPrefix.Append(KBackSlash);
+                }
+            
+            // append trace file name prefix e.g. PIProfiler_#
+            iTotalPrefix.Append(iGeneralAttributes.iTraceFilePrefix);
+    
+            // locate '#' mark for finding the next free trace file name, e.g. E:\data\PIProfiler_4.dat
+            hashLocation = iTotalPrefix.Locate('#');
+            if( hashLocation == KErrNotFound )
+                {
+                // append simply at the end of the trace file prefix, no need to inform user
+                iTotalPrefix.Append('#');
+                // get new hash mark location
+                hashLocation = iTotalPrefix.Locate('#');
+                }
+    
+            // add the file extension
+            iTotalPrefix.Append(KTraceFileExtension);
+
+            // search for files with different indices
+            // until a free filename is found
+            while(result != KErrNotFound)
+                {
+                fileNameBuf.Zero();
+                // start with the original prefix
+                fileNameBuf.Append(iTotalPrefix);
+                // convert the number to a descriptor
+                number.Num(index);
+                // replace the hashmark with the real number
+                fileNameBuf.Replace(hashLocation,1,number);
+                
+                // make a copy to the iFileNameStream descriptor
+                iFileNameStream.Zero();
+                CnvUtfConverter::ConvertToUnicodeFromUtf8(iFileNameStream, fileNameBuf);
+                
+                LOGSTRING2("CProfiler::HandleGeneralSettingsChange() - trying to open files %S ",&iFileNameStream);
+
+                if((result = parse.Set(iFileNameStream, NULL, NULL)) != KErrNone)
+                    {
+                    // break loop if fails, problems in file name => change to log into debug output
+                    break;
+                    }
+                
+                // create directory for trace files if not exists
+                result = fileServer.MkDirAll(parse.FullName());
+
+                // check that file server responded with KErrNone or KErrAlreadyExists
+                if( result != KErrNone && result != KErrAlreadyExists)
+                    {
+                    // if some other result, e.g. memory full => break
+                    break;
+                    }
+
+                // attempt opening the file
+                result = file.Open(fileServer,parse.FullName(),EFileShareReadersOnly);
+                if(result != KErrNotFound)
+                    {
+                    if( result != KErrNotReady && 
+                        result != KErrServerBusy ) 
+                        {
+                        // close the file if it could be opened
+                        LOGSTRING2("Found STREAM file with index %d",index);
+                        index++;
+                        }
+                    else 
+                        {
+                        // in boot measurements the file system might not be ready yet.
+                        LOGSTRING2("Problem in opening STREAM file %d",index);
+                        }
+                    file.Close();
+                    }
+                } // while
+            }
+        else
+            {
+            // return error code
+            return result;
+            }
+        
+        TUint32 id(iWriterHandler->GetActiveWriter()->GetWriterType());
+        
+        // check if a file name is one that does not exist and selected plugin is disk writer
+        if(result == KErrNotFound && id == KDiskWriterPluginUid.iUid)
+            {
+            // write right trace data file name to disk writer plugin
+            iWriterHandler->SetPluginSettings( KDiskWriterPluginUid, iFileNameStream );
+            }
+        else
+            {
+            // return error if could not create trace log file
+            return result;
+            }
+        // close file server
+        fileServer.Close();
+        }   // if output == KOutputToDebugOutput
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::HandleTimerExpiresL(TInt aError)
+    {
+    LOGSTRING2("CProfiler::HandleTimerExpiresL - Error: %d", aError);
+    this->ControlL(RProfiler::EStopSampling);
+    if( CPServer::iClientCount <= 0 )
+        {
+        LOGSTRING("CProfiler::HandleTimerExpiresL - No clients attached, shutting down server...");
+        this->ControlL(RProfiler::EExitProfiler);                
+        }
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::SaveSettingsL()
+    {
+    LOGTEXT(_L("CProfiler::SaveSettings()"));
+    
+    // local literal
+    _LIT(KGeneralHeader, "[general]");
+    _LIT(KVersionHeader, "version");
+    _LIT8(KPIProfilerSettingsHeader, "; PI Profiler Settings File");
+    _LIT8(KGeneralSettingsHeader, "; general settings");
+    _LIT8(KOutputFileDescription,"; \"output_type=file_system\" writes *.dat file to external memory");
+    _LIT8(KOutputDebugDescription,"; \"output_type=debug_output\" writes *.dat file to debug port");
+    _LIT8(KOutputFilePrefixDescription,"; if writing to file, prefix of the *.dat file\r\n; first '#' in the prefix is replaced with an integer");
+    _LIT8(KOutputSaveDriveDescription,"; if writing to file, the location to store the *.dat file");
+    _LIT8(KTimedProfilingPeriod,"; period (in seconds) used when using timed profiling");
+    
+    RFs fs;
+    RFile settingsFile;
+    TInt err(KErrNone);
+    TBuf8<384> line;
+    
+    // connect to file server
+    err = fs.Connect();
+    if( err != KErrNone )
+        {
+        // failed to write settings to settings file
+        return;
+        }
+    
+    // create and set the private path
+    fs.CreatePrivatePath(EDriveC);
+    fs.SetSessionToPrivate(EDriveC);
+  
+    // create the new settings file
+    err = settingsFile.Replace(fs, iSettingsFileLocation, EFileWrite);
+    if(err != KErrNone)
+        return;
+    
+    CleanupClosePushL(settingsFile);  
+
+    // write the header
+    line.Copy(KPIProfilerSettingsHeader);
+    line.Append(KNewLineSeparator);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // write the header
+    line.Copy(KGeneralSettingsHeader);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+
+    // write all generic settings
+    line.Copy(KGeneralHeader);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+
+    // write version info
+    line.Copy(KVersionHeader);
+    line.Append(KEquals);
+    line.Append(PROFILER_VERSION_SHORT);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+
+    // output explanation
+    line.Copy(KOutputFileDescription);
+    line.Append(KNewLineSeparator);
+    line.Append(KOutputDebugDescription);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // write trace output
+    line.Copy(KGenericTraceOutput);
+    line.Append(KEquals);
+    line.Append(iGeneralAttributes.iTraceOutput);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // file prefix explanation
+    line.Copy(KOutputFilePrefixDescription);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+
+    // write trace file prefix
+    line.Copy(KGenericTraceFilePrefix);
+    line.Append(KEquals);
+    line.Append(iGeneralAttributes.iTraceFilePrefix);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // file prefix explanation
+    line.Copy(KOutputSaveDriveDescription);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+
+    // write trace file location
+    line.Copy(KGenericTraceFileSaveDrive);
+    line.Append(KEquals);
+    line.Append(iGeneralAttributes.iSaveFileDrive);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // timed profiling period explanation
+    line.Copy(KTimedProfilingPeriod);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+    
+    // Write timed profiling period value
+    line.Copy(KGenericTimedProfilingPeriod);
+    line.Append(KEquals);
+    TBuf<16> tmpNum;
+    tmpNum.AppendNum(iGeneralAttributes.iTimedSamplingPeriod);
+    line.Append(tmpNum);
+    line.Append(KNewLineSeparator);
+    settingsFile.Write(line);
+        
+    // reset the default attributes array
+    iDefaultSamplerAttributesArray->Reset();
+    
+    // update the latest changes from plugins
+    iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+    
+    // call CSamplerController to write all sampler settings
+    iSamplerHandler->ComposeAttributesToSettingsFileFormat(settingsFile, iDefaultSamplerAttributesArray);
+    
+    CleanupStack::PopAndDestroy(); //settingsFile
+    // close file
+    fs.Close();
+    }
+
+TInt CProfiler::CheckOldProfilerRunning()
+    {
+    TFindProcess procName;
+    procName.Find(_L("BappeaProf.exe*"));
+    TFullName aResult;
+    TInt err(KErrNone);
+    RProcess proc;    
+    
+    // now check if old Profiler is still running on
+    err = procName.Next(aResult);
+    // check if old profiler process found 
+    if(err == KErrNone)
+        {
+        // other process found, i.e. right process to communicate with, in case started from eshell
+        err = proc.Open(procName);
+        if(err == KErrNone)
+            {
+            if(proc.ExitCategory().Length() > 0)
+                {
+                proc.Close();
+                // process already exited => create a new one
+                return KErrNotFound;
+                }
+            proc.Close();
+            }
+        // return error for error handling
+        return KErrAlreadyExists;
+        }
+    return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::HandleError(TInt aErr)
+    {
+    // write error to status property to inform requester
+    TInt err(iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, aErr));
+    if(err != KErrNone)
+        RDebug::Print(_L("CProfiler::HandleError() - error setting status: %d"), err);
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::ControlDataL(TInt aCommand,TAny* value1,TAny* /*value2*/)
+    {
+	LOGSTRING3("CProfiler::ControlData %d, 0x%x",aCommand,value1);
+
+	_LIT(KDebugOutput, "debug_output");
+	_LIT(KFileOutput, "file_system");
+	_LIT8(KOutputToDebugOutput, "debug_output");
+	
+	TDes* desc;
+	TPtrC ptrDesc;
+	
+	switch(aCommand)
+	    {
+		// new controls
+	    case RProfiler::EGetFileName:
+	        {
+            LOGTEXT(_L("Profiler::EGetFileName - start"));
+            LOGSTRING2("Profiler::EGetFileName - total file name is: %S",(TDes*)value1);
+            desc = (TDes*)value1;
+            desc->Zero();
+            desc->Append(iFileNameStream);
+            LOGSTRING2("Profiler::EGetFileName - now total file name is: %S",(TDes*)value1);
+            return KErrNone;
+	        }
+        case RProfiler::EGetActiveWriter:
+            {
+            LOGTEXT(_L("Profiler::EGetActiveWriter - start"));
+            desc = (TDes*)value1;
+            desc->Zero();
+            if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
+                {
+                desc->Append(KDebugOutput);
+                }
+            else
+                {
+                desc->Append(KFileOutput);
+                }
+            return KErrNone;
+            }
+	    }
+
+	return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::ControlL(TInt aCommand)
+    {
+	LOGSTRING2("CProfiler::Control - Controlling ProfilerEngine %d",aCommand);
+	TInt err(KErrNone);
+	
+	switch (aCommand)
+	    {
+		case RProfiler::EStartSampling:
+		case RProfiler::EStartTimedSampling:
+		    {
+		    // check first if old Profiler already running
+		    err = CheckOldProfilerRunning();
+		    if(err == KErrAlreadyExists)
+		        {
+		        // if exists do not start a profiling process since corrupts the collected trace data  
+		        HandleError(err);
+		        err = KErrNone;
+		        return err;
+		        }
+		    
+		    // save settings before launching the profiler
+		    // reason: the profiling may have set to the background => need for get right settings
+		    SaveSettingsL();
+		    
+		    // set the general settings to writer plugins to reflect the latest changes
+		    err = HandleGeneralSettingsChange();
+		    if(err == KErrNone)
+		        {
+                // reset the buffers before new profiling
+                iUserStream->ResetBuffers();
+    
+                // give the CProfilerSampleStream a handle to current writer
+                iUserStream->SetWriter(*iWriterHandler->GetActiveWriter());
+                
+                // set initially debug output writer active
+                err = iWriterHandler->StartSelectedPlugin();
+    
+                // check that writer plugin started
+                if(err != KErrNone)
+                    {
+                    // if not started handle error
+                    HandleError(err);
+                    }
+                else
+                    {
+                    // start activated sampler plug-in, NOTE: plugins check if errors occur in startup for some reason
+                    iSamplerHandler->StartSamplerPluginsL();
+        
+                    // set engine state P&S property to running, e.g. for PIProfiler UI to read
+                    iState = RProfiler::ERunning;
+        
+                    // set the engine into running mode
+                    iEngineStatus.Set(iState);
+                    }
+                }
+		    else
+		        {
+		        // handle error and notify requester
+		        HandleError(err);
+		        }
+		    
+		    if( aCommand == RProfiler::EStartTimedSampling )
+		        {
+                iTimer->After(iGeneralAttributes.iTimedSamplingPeriod);
+                LOGTEXT(_L("CProfiler::Control - Finished processing EStartTimedSampling!"));
+		        }
+		    else
+		        {
+                LOGTEXT(_L("CProfiler::Control - Finished processing EStartSampling!"));
+		        }
+
+			return err;
+		    }
+		case RProfiler::EStopSampling:
+			LOGTEXT(_L("CProfiler::Control - Starting to stop sampling..."));
+			// stop sampler plugins
+			if(iState == RProfiler::ERunning)
+				{
+				iState = RProfiler::EStopping;
+				iEngineStatus.Set(RProfiler::EStopping);
+				
+				iSamplerHandler->StopSamplerPlugins();
+	
+				// finalize the filled buffer writing
+				iUserStream->Finalise();
+				
+				// stop output plugin and write the rest of the trace data to output
+				LOGTEXT(_L("CProfiler::Control - stopping writer"));
+				iWriterHandler->StopSelectedPlugin();
+	
+				// set engine state P&S property idle 
+				iState = RProfiler::EIdle;
+				iEngineStatus.Set(RProfiler::EIdle);
+				
+				LOGSTRING2("CProfiler::Control - sampling stopped, going to state %d", RProfiler::EIdle);
+				}
+			return KErrNone;
+
+		case RProfiler::EExitProfiler:
+		    {
+		    // save settings into settings file when exiting
+		    SaveSettingsL();
+
+            if(iUserStream)
+                {
+                delete iUserStream;
+                iUserStream = NULL;
+                }
+		    
+            // set engine state P&S property idle 
+            iState = RProfiler::EIdle;
+            iEngineStatus.Set(RProfiler::EIdle);
+               
+            LOGTEXT(_L("Stopping Activer Scheduler"));
+            CActiveScheduler::Stop();
+            LOGTEXT(_L("Stopped Activer Scheduler"));
+
+            return KErrNone;
+		    }
+		    
+		case RProfiler::EAttachClient:
+		    {
+		    // Increase client reference count
+		    ++CPServer::iClientCount;
+		    LOGSTRING2("Increased client reference count to: %d", CPServer::iClientCount);
+		    return KErrNone;
+		    }
+		case RProfiler::ERemoveClient:
+		    {
+		    // Decrease client reference count
+		    --CPServer::iClientCount;
+		    LOGSTRING2("Decreasing client reference count to: %d", CPServer::iClientCount);
+		    return KErrNone;
+		    }
+	    }
+
+	LOGTEXT(_L("CProfiler::Control - returning"));
+
+	return err;
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::Finalise()
+    {	
+	LOGTEXT(_L("CProfiler::Finalise - Finished processing EStopSampling!"));
+    }
+
+// --------------------------------------------------------------------------------------------
+RProfiler::TSamplerState CProfiler::State() const
+    {
+	return iState;
+    }
+
+/*
+ *
+ *	Class CPServer definition
+ *
+ */
+// --------------------------------------------------------------------------------------------
+inline const CPServer& CPSession::Server() const
+    {
+	return *static_cast<const CPServer*>(CSession2::Server());
+    }
+
+// --------------------------------------------------------------------------------------------
+void CPSession::ServiceL(const RMessage2& aMessage)
+    {
+	LOGTEXT(_L("CPSession::ServiceL - Starting to process message"));
+	TInt err(KErrNone);
+	
+	if(aMessage.Function() == RProfiler::EGetGeneralAttributes)
+	    {
+	    Server().GetGeneralAttributesL(aMessage);
+	    }
+	else if(aMessage.Function() == RProfiler::ESetGeneralAttributes)
+	    {
+        Server().SetGeneralAttributesL(aMessage);
+	    }
+	else if(aMessage.Function() == RProfiler::EGetSamplerAttributes)
+	    {
+        Server().GetSamplerAttributesL(aMessage);
+	    }
+    else if(aMessage.Function() == RProfiler::EGetSamplerAttributeCount)
+        {
+        Server().GetSamplerAttributeCountL(aMessage);
+        }
+    else if(aMessage.Function() == RProfiler::ESetSamplerAttributes)
+        {
+        Server().SetSamplerAttributesL(aMessage);
+        }
+    else if(aMessage.Function() == RProfiler::ERefreshProfilerStatus)
+        {
+        Server().RefreshStatus(aMessage);
+        }
+	else if(aMessage.Ptr0() == 0 && aMessage.Ptr1() == 0 && aMessage.Ptr2() == 0)
+		{	
+		LOGTEXT(_L("Ptr0 && Ptr1 == 0 && Ptr2 == 0"));
+		aMessage.Complete(Server().ControlL(RProfiler::TCommand(aMessage.Function())));
+		LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+		} 
+	else if(aMessage.Ptr0() != 0 && aMessage.Ptr1() != 0 && aMessage.Ptr2() != 0)
+		{
+		LOGTEXT(_L("Error with message, all pointers contain data!"));
+		}
+		
+	else if (aMessage.Ptr0() != 0)
+		{
+		if(aMessage.Ptr1() == 0)
+			{
+			LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 == 0"));
+			// provided value is a descriptor
+			TBuf<64>* dst = new TBuf<64>;
+			aMessage.ReadL(0,*dst,0);
+	
+			err = Server().ControlDataL(aMessage.Function(),(TAny*)dst);
+			delete dst;
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+			}
+		else
+			{
+			LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 != 0"));
+			// provided value is a descriptor
+			TBuf<64>* dst = new TBuf<64>;
+			aMessage.ReadL(0,*dst,0);
+			
+			TUint32 num1 = (TUint32)aMessage.Ptr1();
+			
+			err = Server().ControlDataL(aMessage.Function(),(TAny*)dst, (TAny*)num1);
+			delete dst;
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+			}
+		}
+	else if (aMessage.Ptr1() != 0)
+		{
+		LOGTEXT(_L("ServiceL: Ptr1 != 0"));
+		// provided value is a TUint32
+		if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
+			{
+			TUint32 num = (TUint32)aMessage.Ptr1();
+			err = Server().ControlDataL(aMessage.Function(),(TAny*)num);
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+			}
+		else
+			{
+			LOGTEXT(_L("ServiceL: Ptr3 != 0xffffffff"));
+			TUint32 num1 = (TUint32)aMessage.Ptr1();
+			TUint32 num2 = (TUint32)aMessage.Ptr3();
+			err = Server().ControlDataL(aMessage.Function(),(TAny*)num1,(TAny*)num2);
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+			}
+		}
+	else if (aMessage.Ptr2() != 0)
+		{
+		// command requests for data, provided 
+		// value should be a descriptor
+		if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
+			{
+			LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 == 0xffffffff"));
+	
+			TBuf<256>* src = new TBuf<256>;
+			src->Zero();
+			err = Server().ControlDataL(aMessage.Function(),(TAny*)src);
+	
+			LOGSTRING2("Got sampler data %S",src);
+			
+			aMessage.WriteL(2, *src, 0);
+	
+			delete src;
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+			}
+		else 
+			{
+			LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 != 0xffffffff"));
+			
+			TUint32 num1 = (TUint32)aMessage.Ptr2();	// containing id
+			TBuf<256>* buffer = new TBuf<256>;		// Text data, e.g. plug-in name or description
+
+			LOGSTRING3("Getting data for sampler: 0x%X, buffer max len %d",num1, aMessage.GetDesMaxLength(3));
+
+			err = Server().ControlDataL(aMessage.Function(), (TAny*)num1, (TAny*)buffer);
+
+			LOGSTRING2("Got sampler data %S",&buffer);
+			
+			// write back to same parameter
+			aMessage.WriteL(3, *buffer, 0);
+			
+			delete buffer;
+			aMessage.Complete(err);
+			LOGTEXT(_L("CPSession::ServiceL - Message completed"));	
+			}
+		}
+	LOGTEXT(_L("CPSession::ServiceL - Message processed"));
+    }
+
+// --------------------------------------------------------------------------------------------
+MProfilerController* CPServer::NewL(TInt aPriority, MProfilerEngine& aEngine)
+    {
+	LOGTEXT(_L("CPServer::NewL - Enter"));
+	CPServer* self = new(ELeave) CPServer(aPriority, aEngine);
+	CleanupStack::PushL(self);
+	self->StartL(KProfilerName);
+	CleanupStack::Pop();
+	LOGTEXT(_L("CPSession::NewL - Exit"));
+	return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+CPServer::CPServer(TInt aPriority, MProfilerEngine& aEngine)
+	: CServer2(aPriority), MProfilerController(aEngine)
+    {
+
+    }
+
+// --------------------------------------------------------------------------------------------
+void CPServer::Release()
+    {
+	delete this;
+    }
+
+// --------------------------------------------------------------------------------------------
+CSession2* CPServer::NewSessionL(const TVersion&,const RMessage2&) const
+    {
+	return new(ELeave) CPSession();
+    }
+
+/*
+ *
+ * Static methods for controlling the profiler
+ * through command line
+ *
+ */
+// --------------------------------------------------------------------------------------------
+static void RunEngineServerL(const TDesC& aSettingsFile)
+    {
+	RDebug::Print(_L("Profiler: RunEngineServerL() - Install active scheduler"));
+	CActiveScheduler* pS = new CActiveScheduler;
+	CActiveScheduler::Install(pS);
+	CProfiler* p = CProfiler::NewLC(aSettingsFile);
+	CActiveScheduler::Start();
+	p->Finalise();
+	CleanupStack::PopAndDestroy(p);
+	delete pS;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt TestSettingsFile(const TDesC& configFile)
+    {
+    RFs fs;
+    LOGSTRING2("TestSettingsFile: entry %S", &configFile);
+    // check if file server can be connected
+    if (fs.Connect() != KErrNone)
+        {
+        LOGTEXT(_L("TestSettingsFile: could not connect file server"));
+        // file server couldn't be connected, return false
+        return KErrNotFound;
+        }
+
+    // check if config file name length is > 0
+    if (configFile.Length() > 0)
+        {
+        LOGTEXT(_L("TestSettingsFile: checking location sanity"));
+        // check sanity of settings file location
+        if(BaflUtils::CheckFolder(fs, configFile) != KErrNone)
+            {
+            LOGTEXT(_L("TestSettingsFile: location sanity check failed"));
+            fs.Close();
+            return KErrGeneral;
+            }
+        }
+    else
+        {
+        // configFile length 0, return false
+        LOGTEXT(_L("TestSettingsFile: config file string null length"));
+        fs.Close();
+        return KErrNotFound;
+        }
+    // return true if tests passed
+    LOGTEXT(_L("TestSettingsFile: exiting..."));
+    fs.Close();
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+GLDEF_C TInt E32Main()
+    {
+    // parse command line arguments 
+    TBuf<256> c;
+    TInt err(KErrNone);
+    
+    // copy the full command line with arguments into a buffer
+    User::CommandLine(c);
+
+    TBuf<256> fileName;
+    fileName.Append(c); // only one settings param should be
+    LOGSTRING3("Filename is %S, response %d 1", &fileName, err);
+    err = TestSettingsFile(fileName);
+    if(err != KErrNone)
+        {
+        LOGSTRING3("Filename is %S, response %d 2", &fileName, err);
+        // settings file does not exist, copy null desc to file name
+        fileName.Copy(KNullDesC);
+        }
+
+    LOGSTRING3("Filename is %S, response %d 3", &fileName, err);
+    
+    // if no command line arguments found just start the profiler process
+    __UHEAP_MARK;
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    TInt ret(KErrNoMemory);
+    if( cleanup )
+        {
+        TRAPD( ret, RunEngineServerL(fileName) );
+        RDebug::Print(_L("Profiler: E32Main() - ret %d"), ret);
+        delete cleanup;
+        } 
+    __UHEAP_MARKEND;
+
+    return ret;
+    } 
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerErrorChecker.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h>
+
+#include <piprofiler/ProfilerTraces.h>
+
+#include "ProfilerErrorChecker.h"
+
+// properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+    {
+    EProfilerEngineStatus = 8,
+    EProfilerErrorStatus
+    };
+
+/*
+ *
+ *  CProfilerErrorChecker class implementation
+ *
+ */
+CProfilerErrorChecker* CProfilerErrorChecker::NewL()
+    {
+    CProfilerErrorChecker* self = new(ELeave) CProfilerErrorChecker;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+CProfilerErrorChecker::CProfilerErrorChecker() :
+    CActive(EPriorityStandard)
+    {
+    }
+
+CProfilerErrorChecker::~CProfilerErrorChecker()
+    {
+    Cancel();
+    iErrorStatus.Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::ConstructL()
+    {
+    
+    LOGTEXT(_L("Trying to attach to profiler engine error status property"));
+    User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+    CActiveScheduler::Add(this);
+
+    // subscribe to P&S status property
+    iErrorStatus.Subscribe(iStatus);
+    SetActive();
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::SetObserver(MProfilerErrorObserver* aObserver)
+    {
+    iObserver = aObserver;
+    }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfilerErrorChecker::RunError(TInt aError)
+    {
+    iErrorStatus.Close();
+    return aError;
+    }
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::RunL()
+    {
+    // resubscribe before processing new value to prevent missing updates
+    iErrorStatus.Subscribe(iStatus);
+    SetActive();
+
+    TInt stat(0);
+    if(iErrorStatus.Get(stat) != KErrNone)
+        {
+        // check if error status != KErrNone
+        if(stat != 0)
+            {
+            iObserver->HandleProfilerErrorChangeL(stat);
+            }
+        
+        // reset error code
+        iErrorStatus.Set(KErrNone);
+        }
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+void CProfilerErrorChecker::DoCancel()
+    {
+    iErrorStatus.Cancel();
+    }
+
+// end of file
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerEshell.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,440 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <f32file.h>
+#include <e32cons.h>
+
+#include "ProfilerEshell.h"
+#include <piprofiler/ProfilerSession.h>
+
+
+
+_LIT(KProfilerEngineExe, "PIProfilerEngine.exe");
+
+/*
+ *
+ * Static methods for controlling the profiler
+ * through command line
+ *
+ */
+// --------------------------------------------------------------------------------------------
+static void PrintUsageInfo(const TDesC& aAdditionalInfo)
+    {
+    _LIT(KConsoleName, "Console");
+    _LIT(KLegalNote, "PIProfiler Version 2.2.0.2 Copyright @ 2009 Nokia\n");
+    _LIT(KUsageNote, "Usage: PIProfiler [start/end/timed] settingsfile [time to run]\n");
+    _LIT(KExample, "Example: PIProfiler timed C:\\data\\piprofilersettings.txt 60\n");
+
+    TRAP_IGNORE(CConsoleBase* console = Console::NewL(KConsoleName,TSize(KConsFullScreen,KConsFullScreen));
+        console->Printf(KLegalNote);
+        console->Printf(KUsageNote);
+        console->Printf(KExample);
+        console->Write(aAdditionalInfo);
+    
+        console->Printf(_L("\n[Press any key]"));
+        console->Getch();
+        delete console;);
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt FindProcess()
+    {
+    TFindProcess procName;
+    procName.Find(_L("PIProfilerEngine.exe*"));
+    TFullName aResult;
+    
+    // find the first appearance, i.e. "myself"...
+    TInt err(procName.Next(aResult));  // the first appearance
+    if(err == KErrNotFound)
+        {
+        // now check if old Profiler is still running on
+        procName.Find(_L("BappeaProf.exe*"));
+        err = procName.Next(aResult);
+        // check if old profiler process found 
+        if(err == KErrNone)
+            {
+            // return error for error handling
+            return KErrAlreadyExists;
+            }
+        // return KErrNotFound and a new profiler engine process can be started
+        return KErrNotFound;
+        }
+    return err;
+    }
+
+/**
+ * Function for starting profiler engine in the background,
+ * call profiler to load settings
+ * and start sampling process
+ * 
+ * @param configFile name and location of settings file
+ * @param aRunTimeInSeconds run time in seconds
+ * @param aBootTime run boot time sampling or not.
+ */
+// --------------------------------------------------------------------------------------------
+static TInt StartProfilerProcess(const TDesC& configFile, TInt aRunTimeInSeconds, TBool aBootTime)
+    {
+    TInt err(KErrNone);
+    RProcess proc;
+    TRequestStatus status = KRequestPending;
+    TBuf<256> conf;
+    conf.Zero();
+    conf.Append(configFile);
+    if(aBootTime)
+        {
+        RDebug::Printf("boot time measurement");
+        conf.Append(_L(" "));
+        conf.Append(_L("boot"));
+        }
+    RDebug::RawPrint(conf);
+    // check if process exists
+    err = FindProcess();
+    LOGSTRING2("PIProfiler: tried to find process, response %d", err); 
+
+    // check if already exists and don't start a new eshell profiling
+    if( err == KErrNotFound )
+        {
+        // try create new process
+        err = proc.Create(KProfilerEngineExe, conf);
+
+        LOGSTRING2("PIProfiler: created process, response %d", err); 
+
+        // check if RProcess::Create() succeeded
+        if( err == KErrNone )
+            {
+            // Trigger rendezvous on the supplied TRequestStatus object
+            proc.Rendezvous(status); 
+
+            // kick off the engine process
+            proc.Resume();
+            
+            // wait for the constructor to complete 
+            User::WaitForRequest(status); 
+            
+            // just lose the handle
+            proc.Close();
+            
+            // start sampling, using settings found in settings file or if not found the default settings
+            err = RProfiler::StartSampling();
+            // check if command succesful
+            if( err != KErrNone )
+                {
+                LOGSTRING2("PI Profiler start: err %d", err);
+                _LIT(KNoteProfilerCannotStart, "PI Profiler: cannot start PI Profiler, check settings!");
+                PrintUsageInfo(KNoteProfilerCannotStart);
+                
+                // check if process still alive
+                if(err != KErrNotFound)
+                    {
+                    // exit the profiler process since process was started
+                    RProfiler::ExitProfiler();
+                    }
+                return err;
+                }
+            
+            if(aRunTimeInSeconds > 0)
+                {
+                RDebug::Print(_L("Profiler running for %d s... "), aRunTimeInSeconds);
+                User::After(aRunTimeInSeconds*1000000);
+                RDebug::Print(_L("************* Profiler process closing *********"));
+        
+                // stop sampling process
+                err = RProfiler::StopSampling();
+                // check if command succesfull
+                if( err != KErrNone )
+                    {
+                    LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+                    return err;
+                    }
+                
+                // exit the profiler process
+                err = RProfiler::ExitProfiler();
+                // check if command succesfull
+                if( err != KErrNone )
+                    {
+                    LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+                    return err;
+                    }
+                }
+            } 
+        else
+            {
+            _LIT(KNoteCannotFindProfiler, "PI Profiler: could not find PIProfilerEngine.exe");
+            PrintUsageInfo(KNoteCannotFindProfiler);
+            }
+        }
+    // check if old Profiler is already running
+    else if( err == KErrAlreadyExists )
+        {
+        _LIT(KNoteAlreadyRunning, "PI Profiler: old Profiler process already running, close it down before launching the new!");
+        PrintUsageInfo(KNoteAlreadyRunning);
+        }
+    // otherwise show error note
+    else
+        {
+        _LIT(KNoteAlreadyRunning, "PI Profiler: already running, not able to launch new one. NOTE: check if UI running!");
+        PrintUsageInfo(KNoteAlreadyRunning);
+        }
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt EndProfilerProcess()
+    {
+    LOGTEXT(_L("EndProfilerProcess() ..."));
+
+    // call profiler to stop sampling
+    TInt err = RProfiler::StopSampling();
+    
+    // check if command succesfull
+    if( err != KErrNone )
+        {
+        LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+        return err;
+        }
+    
+    // exit the profiler process
+    err = RProfiler::ExitProfiler();
+    // check if command succesfull
+    if( err != KErrNone )
+        {
+        LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+        return err;
+        }
+    
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt TestSettingsFile(const TDesC& configFile)
+    {
+    RFs fs;
+    RFile file;
+    TInt err(KErrNone);
+
+    // check if file server can be connected
+    if (fs.Connect() != KErrNone)
+        {
+        // file server couldn't be connected, return false
+        return KErrNotFound;
+        }
+
+    // check if config file name length is > 0
+    if (configFile.Length() > 0)
+        {
+        // open the file with the given path and name
+        err = file.Open(fs,configFile,EFileRead);
+        // check if file open was succesfull 
+        if(err != KErrNone)
+            {
+            // return false if failed
+            fs.Close();
+            return err;
+            }
+        
+        }
+    else
+        {
+        // configFile length 0, return false
+        fs.Close();
+        return KErrNotFound;
+        }
+    // return true if tests passed
+    file.Close();
+    fs.Close();
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt ParseCommandAndExecute()
+    {
+    // commands literals for finding the right keyword 
+    _LIT(KAutomatedTestStart,"start*");
+    _LIT(KAutomatedTestEnd,"end*");
+    _LIT(KAutomatedTestTimed,"timed*");
+    _LIT(KBootMeasurement,"boot*");
+    TBuf<256> c;
+    TInt match(KErrNotFound);
+    TInt bootmatch(KErrNotFound);
+    TBool myBoot=false;
+    // copy the full command line with arguments into a buffer
+    User::CommandLine(c);
+    LOGSTRING2("command: %S", &c);
+
+    // try to match with each of the literals defined above
+    // (commands in atf format)
+    
+    // check if command is "start"
+    match = c.Match(KAutomatedTestStart);
+    if (match != KErrNotFound)
+        {
+        LOGTEXT(_L("Found keyword start"));
+
+        TBuf<256> fileName;
+        fileName.Append(c.Right(c.Length()-6));
+        LOGSTRING2("Filename is %S", &fileName);
+        if(TestSettingsFile(fileName) != KErrNone)
+            {
+            _LIT(KSettingsFileFailed, "False settings file");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+        // execute Profile process 
+        if( StartProfilerProcess(fileName, 0, myBoot) == KErrNone )
+            {
+            return -10;
+            }
+        return -2;
+        }
+
+    // check if command is "end"
+    match = c.Match(KAutomatedTestEnd);
+    if (match != KErrNotFound)
+        {
+        LOGTEXT(_L("Found keyword end"));
+
+        // stop the profiling process
+        EndProfilerProcess();
+        return -10;
+        }
+
+    // check if command is "timed"
+    match = c.Match(KAutomatedTestTimed);
+    // check if command is "boot"
+    bootmatch = c.Match(KBootMeasurement);
+    if ((match!= KErrNotFound) || (bootmatch != KErrNotFound))
+        {
+        // command "timed" or " boot" found, need for finding settings file and run time next
+        if(bootmatch != KErrNotFound)
+            {
+            LOGTEXT(_L("Found keyword boot"));
+            myBoot = TRUE;
+            }
+        if(match != KErrNotFound)
+            {
+            LOGTEXT(_L("Found keyword timed"));
+            }
+        
+        TBuf<256> temp;
+        temp.Append(c);
+        TLex lex(temp);
+        
+        TBuf<256> fileName;
+        TInt seconds;
+
+        // parse the first command line argument, the command itself
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            #ifdef PIPROFILER_PRINTS
+            TPtrC token = lex.MarkedToken();
+            LOGSTRING2("Token 1 %S",&token);
+            #endif
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 1 in parsing command line"));
+            _LIT(KSettingsFileFailed, "Failure: False argument");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+
+        // parse the second command line argument, the settings file name
+        lex.SkipSpace();
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            TPtrC token2 = lex.MarkedToken();
+            LOGSTRING2("Token 2 %S",&token2);
+            fileName.Append(token2);
+            LOGSTRING2("Value of fileName is %S",&fileName);
+//            if(TestSettingsFile(fileName) != KErrNone)
+//                {
+//                _LIT(KSettingsFileFailed, "Failure: False settings file");
+//                PrintUsageInfo(KSettingsFileFailed);
+//                return -2;
+//                }
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 2 in parsing command line"));
+            _LIT(KSettingsFileFailed, "Failure: No settings file specified");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+
+        // parse the third command line argument, the run time in seconds
+        lex.SkipSpace();
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            // third token ok, try to convert into TInt value
+            TPtrC token3 = lex.MarkedToken();
+            LOGSTRING2("Token 3 %S",&token3);
+            TLex num(token3);
+            TInt err = num.Val(seconds);
+            // check if given time value acceptable 
+            if (err != KErrNone)
+                {
+                // value parsing failed, show info note to user
+                _LIT(KSecondsFailed, "Failure: False time value");
+                PrintUsageInfo(KSecondsFailed);
+                return -2;
+                }
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 3 in parsing command line"));
+            _LIT(KSecondsFailed, "Failure: False time value");
+            PrintUsageInfo(KSecondsFailed);
+            return -2;
+            }           
+        
+        LOGSTRING3("Filename is %S, seconds is %d", &fileName, seconds);
+        // execute Profile process 
+        if( StartProfilerProcess(fileName, seconds, myBoot) == KErrNone )
+            {
+            return -10;
+            }
+        return -2;
+        }
+    
+    // check if space character in the middle of command line string 
+    if( c.LocateReverse(' ') != KErrNotFound)
+        {
+        _LIT(KWrongParameters, "Failure: Check command line parameters");
+        PrintUsageInfo(KWrongParameters);
+        return -2;
+        }
+    
+    // return -1 if no command found
+    LOGTEXT(_L("No keyword found"));
+    return -1;
+    }
+
+// --------------------------------------------------------------------------------------------
+GLDEF_C TInt E32Main()
+    {
+    // parse command line arguments
+    ParseCommandAndExecute();
+
+    return KErrNone;
+
+    } 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerTimer.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include "ProfilerTimer.h"
+
+/*
+ *
+ *  CProfilerTimer class implementation
+ *
+ */
+// --------------------------------------------------------------------------------------------
+CProfilerTimer::CProfilerTimer(const TInt aPriority, MProfilerTimerObserver& aObserver)
+: 
+CActive(aPriority),
+iObserver(aObserver)
+    {    
+    } 
+
+// --------------------------------------------------------------------------------------------
+CProfilerTimer::~CProfilerTimer()
+    {
+    Cancel();
+    iTimer.Close();
+    } 
+
+// --------------------------------------------------------------------------------------------
+CProfilerTimer* CProfilerTimer::NewL(const TInt aPriority, MProfilerTimerObserver& aObserver)
+    {
+    CProfilerTimer* self = new (ELeave) CProfilerTimer(aPriority, aObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::ConstructL(void)
+    {
+    CActiveScheduler::Add(this);
+    iTimer.CreateLocal();
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::After(TUint aPeriodInSeconds)
+    {
+    Cancel();
+    TTimeIntervalMicroSeconds32 period = aPeriodInSeconds * 1000000;
+    iTimer.After(iStatus, period);
+    SetActive();
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::DoCancel()
+    {
+    iTimer.Cancel();
+    }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::RunL()
+    {
+    iObserver.HandleTimerExpiresL(iStatus.Int());
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/SamplerController.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,500 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include "SamplerController.h"
+//#include <piprofiler/EngineUIDs.h>
+
+// CONSTANTS
+const TInt KMaxSamplerPluginCount = 20;
+const TInt KMaxExtraSettingsItemCount = 6;
+
+// LITERALS
+_LIT8(KSamplingPeriod, "sampling_period_ms");
+_LIT8(KNewLine8, "\n");
+_LIT8(KEquals8, "=");
+_LIT8(KSettingsText, " settings");
+_LIT(KNewLine, "\n");
+_LIT(KEquals, "=");
+_LIT(KCommentSeparator, " ; ");
+
+CSamplerController* CSamplerController::NewL(CProfilerSampleStream& aStream)
+    {
+    CSamplerController* self = new( ELeave ) CSamplerController(aStream);
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+void CSamplerController::ConstructL()
+	{
+	// initiate sampler plugin list
+	InitialiseSamplerListL();
+	}
+
+
+CSamplerController::CSamplerController(CProfilerSampleStream& aStream) : 
+    iStream(aStream)
+	{
+	}
+
+void CSamplerController::InitialiseSamplerListL()
+    {
+    // create new sampler plugin array
+    iPluginArray = new (ELeave) CArrayPtrFlat<CSamplerPluginInterface>( KMaxSamplerPluginCount );
+    
+    // create plugin loader instance
+    iPluginLoader = CSamplerPluginLoader::NewL();
+    
+    // register sampler controller to get notifications of succesfull plugin load
+    iPluginLoader->SetObserver( this );
+    
+    // load sampler plugins asynchronously
+    iPluginLoader->LoadAsyncL( iPluginArray );
+    
+    LOGTEXT(_L(" RSamplerController::InitialiseUserSideSamplerList - exit"));	
+    }
+
+CSamplerController::~CSamplerController()
+	{
+	LOGTEXT(_L("CSamplerController::~CSamplerController - entry" ));
+	
+    if ( iPluginArray )
+        {
+        // destroy the plugin instances
+        // empty loaded plugins from array
+        for(TInt i(0);i<iPluginArray->Count();i++)
+            {
+            if(iPluginArray->At(i))
+                {
+                delete iPluginArray->At(i);
+                iPluginArray->At(i) = NULL;
+                }
+            }
+        iPluginArray->Reset();
+        delete iPluginArray;
+        iPluginArray = NULL;
+        }
+	
+	if ( iPluginLoader )
+	    {
+	    iPluginLoader->AbortAsyncLoad();
+	    delete iPluginLoader;
+	    iPluginLoader = NULL;
+	    }
+    
+	LOGTEXT(_L("CSamplerController::~CSamplerController - exit" ));
+	}
+
+void CSamplerController::SetObserver(MSamplerControllerObserver* aObserver)
+    {
+    iObserver = aObserver;
+    }
+    
+TInt CSamplerController::UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    TInt err(KErrNone);
+    TInt count(iPluginArray->Count());
+    // all plugins get their own settings among whole lump of setting strings
+    CSamplerPluginInterface* plugin = NULL;
+    
+    // loop through the plugin array
+    for(TInt i(0);i<count;i++)
+        {
+        // get each plugin at a time
+        plugin = iPluginArray->At(i);
+        
+        // call each plugin to sort out its own settings 
+        err = plugin->ConvertRawSettingsToAttributes(aSavedLineArray);
+        
+        // get plugin specific attributes, array may contain attributes of several sub samplers
+        plugin->GetAttributesL(aAttributes); 
+        }
+    
+    return err;
+    }
+
+TInt CSamplerController::SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes)
+    {
+    // parse right plugin based on UID
+    CSamplerPluginInterface* plugin = GetPlugin(TUid::Uid(aUid));
+    
+    // set the sampler attributes of a sampler plugin
+    plugin->SetAttributesL(aAttributes);
+    
+    return KErrNone;
+    }
+
+void CSamplerController::GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    CSamplerPluginInterface* plugin = NULL;
+    
+    TInt count(iPluginArray->Count());
+    
+    // get first all the attributes from all the sampler plugins listed in iPluginArray
+    for(TInt i(0);i<count;i++)
+        {
+        // get the plugin first
+        plugin = iPluginArray->At(i);
+        
+        // get plugin specific attributes, array may contain attributes of several sub samplers
+        plugin->GetAttributesL(aAttributes); 
+        }
+    }
+
+void CSamplerController::ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    // write immediately to settings file
+    ComposeSettingsText(aFile, aAttributes);
+    }
+
+void CSamplerController::ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray)
+    {
+    // temporary buffer for a setting line
+    TBuf<384> settingLine;
+    TBuf8<384> settingLine8;
+    TInt itemCount(0);
+    TBuf<266> tBuf;
+    
+    TSamplerAttributes attr;
+    
+    for(TInt i(0);i<aAttrArray->Count();i++)
+        {
+        // get the attribute container 
+        attr = aAttrArray->At(i);
+        
+        // add the name and description of the sampler in brackets first
+        settingLine8.Copy(KBracketOpen);
+        settingLine8.Append(attr.iShortName);
+        settingLine8.Append(KBracketClose);
+        settingLine8.Append(KCommentSeparator());
+        settingLine8.Append(attr.iName);
+        settingLine8.Append(KSettingsText);
+        settingLine8.Append(KNewLine8);
+        aFile.Write(settingLine8);
+        
+        // enabled
+        settingLine8.Copy(KEnabled);
+        settingLine8.Append(KEquals8);
+        settingLine8.Append(Bool2Str(attr.iEnabled));
+        settingLine8.Append(KNewLine8);
+        aFile.Write(settingLine8);
+        
+        // sampling rate (if set)
+        if( attr.iSampleRate != -1 )
+            {
+            settingLine8.Copy(KSamplingPeriod);
+            settingLine8.Append(KEquals8);
+            settingLine8.Append(Int2Str(attr.iSampleRate));
+            settingLine8.Append(KNewLine8);
+            aFile.Write(settingLine8);
+            }
+        
+        itemCount = attr.iItemCount;
+        
+        // check if item count set is sane, max extra settings item count 6
+        if(itemCount > KMaxExtraSettingsItemCount)
+            {
+            // probably forgot to set the item count value in plugin => safe to set it 0
+            itemCount = 0;
+            }
+        
+        // setting items
+        for (TInt j(0);j<itemCount;j++)
+            {
+            switch(j)
+                {
+                case 0: // settingItem1
+                    {
+                    settingLine.Copy(attr.iSettingItem1.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem1.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem1.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                case 1: // settingItem2
+                    {
+                    settingLine.Copy(attr.iSettingItem2.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem2.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem2.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                case 2: // settingItem3
+                    {
+                    settingLine.Copy(attr.iSettingItem3.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem3.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem3.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                case 3: // settingItem4
+                    {
+                    settingLine.Copy(attr.iSettingItem4.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem4.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem4.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                case 4: // settingItem5
+                    {
+                    settingLine.Copy(attr.iSettingItem5.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem5.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem5.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                case 5: // settingItem6
+                    {
+                    settingLine.Copy(attr.iSettingItem6.iSettingText);
+                    settingLine.Append(KEquals());
+                    settingLine.Append(attr.iSettingItem6.iValue);
+                    settingLine.Append(KCommentSeparator());
+                    settingLine.Append(attr.iSettingItem6.iUIText);
+                    settingLine.Append(KNewLine());
+                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+                    aFile.Write(settingLine8);
+                    break;
+                    }
+                }
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TBool value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Bool(const TDesC8& aBuf, TBool& aValue)
+    {
+    if (aBuf.CompareF(KFalse) == 0)
+        aValue = EFalse;
+    else
+        aValue = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Int(const TDesC8& aBuf, TInt& aValue)
+    {
+    TLex8 conv;
+    conv.Assign(aBuf);
+    
+    if (conv.Val(aValue) != KErrNone)
+        aValue = 0;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Int(const TDesC8& aBuf, TUint32& aValue)
+    {
+    TInt temp(0);
+    
+    TLex8 conv;
+    conv.Assign(aBuf);
+    
+    if (conv.Val(temp) != KErrNone)
+        aValue = 0;
+    else
+        aValue = (TUint32)temp;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given boolean into a descriptor.
+// ----------------------------------------------------------------------------
+//
+inline TBuf8<16> CSamplerController::Bool2Str(const TBool& aValue)
+    {
+    TBuf8<16> buf;
+    
+    if (aValue)
+        buf.Copy(KTrue);
+    else
+        buf.Copy(KFalse);
+    
+    return buf;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given integer into a descriptor.
+// ----------------------------------------------------------------------------
+//
+inline TBuf8<16> CSamplerController::Int2Str(const TInt& aValue)
+    {
+    TBuf8<16> buf;
+    buf.AppendNum(aValue);
+   
+    return buf;
+    }
+
+
+void CSamplerController::HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus )
+    {
+    
+    // process status value
+    switch(aStatus)
+        {
+        case 0:
+            LOGSTRING2("RSamplerController - one plugin loaded, status: %d", aStatus);
+            break;
+        case 1:
+            LOGSTRING2("RSamplerController - a plugin load failed: %d", aStatus);
+            break;
+        case 2:
+            LOGSTRING2("RSamplerController - plugin loading aborted: %d", aStatus);
+            break;
+        case 3:
+            LOGSTRING2("RSamplerController - all plugins loaded: %d", aStatus);
+            TRAPD(err, iPluginLoader->SortPluginsL(iPluginArray));
+            if(err != KErrNone)
+                {
+                LOGTEXT(_L("Sampler controller unable to sort plugins"));
+                }
+            
+            // call engine to finalize the startup
+            TRAPD(result, iObserver->HandleSamplerControllerReadyL(););
+            if(result != KErrNone)
+                {
+                LOGTEXT(_L("Failed to notify engine"));
+                }
+            break;
+        case 4:
+            LOGSTRING2("RSamplerController - error in loading plugins: %d", aStatus);
+            break;
+        default:
+            break;
+        }
+    }
+
+
+CSamplerPluginInterface* CSamplerController::GetPlugin(TUid aUid)
+	{
+	LOGTEXT(_L("RSamplerController::GetPlugin - entry"));
+	// check that plugin array contains samplers
+	if( iPluginArray && iPluginArray->Count() > 0 )
+	  {
+    	for(TInt i=0;i<iPluginArray->Count();i++)
+    		{
+	    	CSamplerPluginInterface* plugin = iPluginArray->At(i);
+	    	TUid uid = plugin->Id(-1);	// get parent uid first
+	    	if(uid == aUid)
+	    		{
+	    		LOGTEXT(_L("CSamplerController::GetPlugin() - main plug-in found!"));
+    			return plugin;
+				} 
+
+            if(plugin->SubId(aUid) != KErrNotFound)
+                {
+                LOGTEXT(_L("CSamplerController::GetPlugin() - subsampler found!"));
+                return plugin;
+                }
+    		}
+		}	
+	LOGTEXT(_L("CSamplerController::GetPlugin() - No plug-in found for UID"));
+
+	return (CSamplerPluginInterface*)0;
+	}
+
+// start user mode samplers
+void CSamplerController::StartSamplerPluginsL()
+    {
+    CSamplerPluginInterface* plugin = NULL;
+
+	if( iPluginArray )
+		{
+		TInt count(iPluginArray->Count());
+	
+		for(TInt i(0);i<count;i++)
+			{
+			plugin = iPluginArray->At(i);
+			// check if some error received when starting profiling
+			TRAPD(err, plugin->ResetAndActivateL(iStream));
+			LOGSTRING2(" RSamplerController::StartSamplerPlugin - plugin activated (0x%X)", plugin->Id(-1));  
+			if( err != KErrNone)
+				{
+				LOGSTRING2(" RSamplerController::StartSamplerPlugin - error %d", i);  
+				// handle received error, need to update UI!
+				iObserver->HandleError(err);
+				}
+            }
+	    }
+    }
+
+// stop user mode samplers
+TInt CSamplerController::StopSamplerPlugins()
+	{
+	TInt count(0);
+
+	if( iPluginArray && iPluginArray->Count() > 0 )
+		{
+		TInt i(0);
+		CSamplerPluginInterface* plugin = NULL;
+		// stop kernel mode samplers
+    	for(;i<iPluginArray->Count();i++)
+    		{
+			plugin = iPluginArray->At(i); 
+			TUint32 id = plugin->Id(-1).iUid;
+            LOGSTRING2(" CSamplerController::StopSamplerPlugins - traceId = %d",
+                        id);
+            // stop only started samplers
+            if(plugin->Enabled())
+                {
+                // stop selected plugin
+                plugin->StopSampling();
+                // check if user mode sampler, special flush needed to direct data to stream
+                if(plugin->GetSamplerType() == PROFILER_USER_MODE_SAMPLER)
+                    {
+                    LOGTEXT(_L(" CSamplerController::StopSamplerPlugins - flushing user mode sampler stream"));
+                    plugin->Flush();
+                    }
+                }
+            count++;
+    		}
+		}
+	return count; 	
+	}
+
+// end of file
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/SamplerPluginLoader.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,539 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include    "SamplerPluginLoader.h"
+//#include	<piprofiler/EngineUIDs.h>
+#include    <utf.h> // CnvUtfConverter
+#include  	<basched.h>
+
+// CONSTANTS
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NewL
+//
+// EPOC two-phased constructor
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader* CSamplerPluginLoader::NewL()
+    {
+    CSamplerPluginLoader* self = new( ELeave ) CSamplerPluginLoader;
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CSamplerPluginLoader
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader::CSamplerPluginLoader() : CActive( EPriorityStandard )
+    {
+    LOGSTRING( "CSamplerPluginLoader()::CSamplerPluginLoader()" );
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ConstructL
+//
+// EPOC default constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::ConstructL( )
+    {
+    LOGSTRING( "CSamplerPluginLoader()::ConstructL()" );
+
+    // get list of implementations
+    CSamplerPluginInterface::ListAllImplementationsL( iImplInfoArray );
+
+    CActiveScheduler::Add( this );
+    }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::~CSamplerPluginLoader
+//
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader::~CSamplerPluginLoader()
+    {
+    LOGSTRING( "CSamplerPluginLoader()::~CSamplerPluginLoader()" );
+
+    AbortAsyncLoad();
+
+    Cancel();
+    
+    // reset ECOM implementation info array
+    iImplInfoArray.ResetAndDestroy();   // This is needed
+    iImplInfoArray.Close();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadAsync
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadAsyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray )
+    {
+    iPluginArray = aPluginArray;
+
+    // Reset iterator
+    iImplInfoArrayIterator = 0;
+
+    LOGSTRING2( "CSamplerPluginLoader()::Implementation info count: %d",
+        iImplInfoArray.Count() );
+
+    NotifyProgress();
+
+    //Begin CActive asynchronous loop.
+    CompleteOwnRequest();
+    }
+    
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadSyncL
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadSyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray)
+    {
+    // cancel first active object from loading samplers dynamically
+    Cancel();
+    CSamplerPluginInterface* plugin = NULL;
+    
+    iPluginArray = aPluginArray;
+
+    // Get a list of all implementations, even though we only want one specific
+    // one. There appears to be no way to otherwise extract a specific implementation
+    // info object :(
+    // Search for the implementation that matches aImplementationUid
+    const TInt impCount = iImplInfoArray.Count();
+    for( TInt i=0; i<impCount; i++ )
+        {
+        const CImplementationInformation* info = iImplInfoArray[ i ];
+            {
+            TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); );
+            if( ret == KErrNone )
+                {
+                // Plugin ownership is transfered to iPluginArray
+                InsertPluginInOrderL( plugin, iPluginArray );
+                }
+            else
+                {
+                // Error note is displayed even if plugin is not loaded
+                LOGSTRING2("CSamplerPluginLoader::LoadSyncL() - plugin load failed, error %d", ret);
+                }
+            break;
+            }
+        }
+
+    if  ( plugin == NULL )
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::AbortAsyncLoad
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::AbortAsyncLoad()
+    {
+    LOGSTRING( "CSamplerPluginLoader()::AbortAsyncLoad()" );
+    Cancel();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::RunL
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::RunL()
+    {
+    iRunLDebugCount++;
+    LoadNextPluginL();
+
+    // Check if there are still more plugins to be loaded:
+    if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
+        {
+        NotifyProgress();
+        // Continue CActive asynchronous loop.
+        CompleteOwnRequest();
+        }
+    else
+        {
+        // All plugins loaded:
+        LOGSTRING( "CSamplerPluginLoader()::Loading plugins finished." );
+        NotifyFinished();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CScGenreItemConstructionConductor::CompleteOwnRequest
+//
+// Issue request complete notification.
+// ---------------------------------------------------------------------------
+void CSamplerPluginLoader::CompleteOwnRequest()
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::RunError
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::RunError( TInt aError )
+    {
+    // This method is called when a plugin loading fails.
+    // Always "fake" the return value so that ActiveSchedule
+    // keeps running and later plugins are continued to be loaded.
+    // Check if still plugins to be loaded:
+    LOGTEXT(_L("CSamplerPluginLoader::RunError() - error in loading plugin"));
+    if( iImplInfoArrayIterator < iImplInfoArray.Count() )
+        {
+        NotifyProgress();
+
+        //Continue CActive asynchronous loop.
+        CompleteOwnRequest();
+        }
+    else // All plugins loaded:
+        {
+        NotifyFinished();
+        }
+
+    if ( aError == KLeaveExit )
+        {
+        return KLeaveExit;
+        }
+
+    return KErrNone;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::DoCancel
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::DoCancel()
+    {
+
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NotifyProgress
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::NotifyProgress()
+    {
+    if( iObserver )
+        {
+        iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerSuccess);
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NotifyFinished
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::NotifyFinished()
+    {
+    if( iObserver )
+        {
+        iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerFinished );
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::SetObserver
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::SetObserver(MSamplerPluginLoadObserver* aObserver)
+    {
+    LOGSTRING2("CSamplerPluginLoader()::Observer set:0x%X", aObserver);
+    iObserver = aObserver;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ParseToUid
+// Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
+    {
+    // Remove "0x" from the descriptor if it exists
+    _LIT8(KHexPrefix, "0x");
+
+    TPtrC8 pSource( aSource );
+    const TInt prefixPosition = pSource.Find( KHexPrefix );
+    if  ( prefixPosition != KErrNotFound )
+        {
+        pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
+        }
+
+    // Parse to integer
+    TLex8 lex( pSource );
+    TUint integer = 0;
+
+    // Parse using TRadix::EHex as radix:
+    const TInt err = lex.Val( integer, EHex );
+    aTarget.iUid = integer;
+
+    if( err != KErrNone )
+        {
+        // If parsing parent UID failed, do not load plugin:
+        LOGSTRING2(
+            "CSamplerPluginLoader()::Parsing parent UID failed. Error code:%d",
+            err );
+        }
+    return err;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ParseOrderNumber
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
+    {
+    // Parse plugin's order number from opaque_data:
+    TLex8 lex( aSource );
+    const TInt orderErr = lex.Val( aOrderNumber );
+    return orderErr;
+    }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadNextPluginL
+// Iterate through iImplInfoArray. Load the plugin if it is eligible for
+// loading. Loaded plugin is added to iPluginArray. Each time a plugin is
+// loaded, iObserver is notified.
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadNextPluginL()
+    {
+    // Iterate through iImplInfoArray. This loop continues between function
+    // calls. Therefore member variable iImplInfoArrayIterator is used as a
+    // counter. Loop will break when match is found and continues on next RunL.
+    for( ; iImplInfoArrayIterator < iImplInfoArray.Count();  )
+        {
+        const CImplementationInformation* info =
+            iImplInfoArray[ iImplInfoArrayIterator ];
+
+        iImplInfoArrayIterator++;
+
+//        PrintInfoDebug( *info, iImplInfoArrayIterator, iImplInfoArray.Count() );
+        LOGSTRING3("CSamplerPluginLoader() - iImplInfoArrayIterator %d, iImplInfoArray.Count() %d", 
+                iImplInfoArrayIterator, 
+                iImplInfoArray.Count() );
+        
+        // If this plugin is OK -> load it:
+        LOGSTRING2( "CSamplerPluginLoader() %S eligible for parent",
+                &info->DisplayName());
+        CSamplerPluginInterface* plugin = NULL;
+        TInt error(KErrNone);
+        // Create plugin. Trap leave for debugging purposes.
+        TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
+
+        if( error == KErrNone )
+            {
+            // Plugin ownership is transfered to iPluginArray
+            InsertPluginInOrderL( plugin, iPluginArray );
+            }
+        else
+            {
+            // Error note is displayed even if plugin is not loaded
+            LOGSTRING2("CSamplerPluginLoader::LoadNextPluginL() - plugin load failed, error %d", error);
+            }
+        // Wait for next round
+        break;
+        }
+    }
+ 
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CreatePluginInstanceL
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+CSamplerPluginInterface& CSamplerPluginLoader::CreatePluginInstanceL(
+    const CImplementationInformation& aImpInfo )
+    {
+    // Now we can load the plugin
+    const TUid implUid = aImpInfo.ImplementationUid();
+
+    CSamplerPluginInterface* plugin = CSamplerPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() );
+    CleanupStack::PushL ( plugin );
+
+    // Parse plugin's order number from opaque_data:
+    TInt orderNumber(0);
+    const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
+
+    if  ( orderErr == KErrNone && orderNumber >= 0 )
+        {
+        	plugin->iOrder = orderNumber;
+        }
+    CleanupStack::Pop( plugin ); // CSamplerController is now responsible for this memory.
+
+    return *plugin;
+    }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::SortPluginsL
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::SortPluginsL(
+        CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
+    {
+    RPointerArray<CSamplerPluginInterface> plugins;
+    TLinearOrder<CSamplerPluginInterface> order( CSamplerPluginLoader::Compare );
+
+    // Insertion will also order
+    for( TInt i = 0; i < aPlugins->Count(); i++ )
+        {
+        plugins.InsertInOrderL( (*aPlugins)[i], order );
+        }
+
+    // Replace original array content with sorted items
+    aPlugins->Reset();
+    for( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        aPlugins->AppendL( plugins[i] );
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::Compare
+//
+// Compare two plugins.
+// Precedence:
+// [1. plugin provider category]
+// 2. plugin order number
+// 3. plugin caption
+// Plugin provider gategory is currently disabled (not supported yet).
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::Compare( const CSamplerPluginInterface& aFirst,
+                               const CSamplerPluginInterface& aSecond )
+    {
+    // compare indexes and sort
+    return CompareIndex( aFirst, aSecond );
+    }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::InsertPluginInOrderL
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::InsertPluginInOrderL(
+    CSamplerPluginInterface* aPlugin,
+    CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
+    {
+    CSamplerPluginInterface* comparedPlugin;
+    TInt comparison = 0;
+    TBool inserted = EFalse;
+
+    for( TInt i = 0; i < aPlugins->Count(); i++ )
+        {
+        comparedPlugin = (*aPlugins)[i];
+        // Optimization: do not call time consuming Compare() multiple times!
+        comparison = Compare( *aPlugin, *comparedPlugin );
+        if( comparison < 0 )
+            {
+            aPlugins->InsertL( i, aPlugin );
+            inserted = ETrue;
+            break;
+            }
+        else if( comparison == 0 )
+            {
+            aPlugins->InsertL( i+1, aPlugin );
+            inserted = ETrue;
+            break;
+            }
+        }
+    // Plugin was not before any other plugin - make sure it's appended
+    if( !inserted )
+        {
+        aPlugins->AppendL( aPlugin );
+        }
+
+    #ifdef _GS_PLUGINLOADER_SORTING_TRACES
+        PrintOrderTraces( aPlugins );
+    #endif // _GS_PLUGINLOADER_SORTING_TRACES
+
+    }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CompareIndex
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::CompareIndex( const CSamplerPluginInterface& aFirst,
+                                    const CSamplerPluginInterface& aSecond )
+    {
+    TInt comparison = KSamplerComparisonEqual;
+    // The plugin having index is before the one not having one
+
+    if( aFirst.iOrder  == KSamplerPluginNotIndexed &&
+        aSecond.iOrder == KSamplerPluginNotIndexed )
+        {
+        // Neither have index -> equal
+        comparison = KSamplerComparisonEqual;
+        }
+    else if( aFirst.iOrder == KSamplerPluginNotIndexed )
+        {
+        // The plugin having index is before the one not having one
+        comparison = KSamplerComparisonAfter;
+        }
+    else if( aSecond.iOrder == KSamplerPluginNotIndexed )
+        {
+        // The plugin having index is before the one not having one
+        comparison = KSamplerComparisonBefore;
+        }
+    else if( aFirst.iOrder < aSecond.iOrder )
+        {
+        // Compare actual index values
+        comparison = KSamplerComparisonBefore;
+        }
+    else if( aFirst.iOrder > aSecond.iOrder )
+        {
+        // Compare actual index values
+        comparison = KSamplerComparisonAfter;
+        }
+    return comparison;
+    }
+
+//  End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/WriterController.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include "WriterController.h"
+
+const TInt KMaxWriterPluginCount = 10;
+
+
+CWriterController* CWriterController::NewL(CProfilerSampleStream& aStream)
+    {
+    CWriterController* self = new( ELeave ) CWriterController(aStream);
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CWriterController::CWriterController(CProfilerSampleStream& aStream) : 
+    iStream(aStream)
+    {
+    }
+
+void CWriterController::ConstructL()
+	{
+	// initiate writer plugin list
+
+	}
+
+
+void CWriterController::InitialiseWriterListL()
+    {
+    // create new writer plugin array
+    iPluginArray = new(ELeave) CArrayPtrFlat<CWriterPluginInterface>( KMaxWriterPluginCount );
+    
+    // create new writer plugin loader
+    iPluginLoader = CWriterPluginLoader::NewL();
+    iPluginLoader->SetObserver( this );
+    iPluginLoader->LoadAsyncL( iPluginArray );
+
+    LOGTEXT(_L(" RWriterController::InitialiseWriterList - exit"));	
+    }
+
+CWriterController::~CWriterController()
+    {
+    LOGTEXT(_L("RWriterController::~RWriterController" ));
+    if ( iPluginArray )
+        {
+        // destroy the plugin instances
+        // empty loaded plugins from array
+        for(TInt i(0);i<iPluginArray->Count();i++)
+            {
+            if(iPluginArray->At(i))
+                {
+                delete iPluginArray->At(i);
+                iPluginArray->At(i) = NULL;
+                }
+            }
+        iPluginArray->Reset();
+        delete iPluginArray;
+        iPluginArray = NULL;
+        }
+    
+    if ( iPluginLoader )
+        {
+        iPluginLoader->AbortAsyncLoad();
+        delete iPluginLoader;
+        iPluginLoader = NULL;
+        }
+
+    }
+
+
+void CWriterController::InitialisePluginStream()
+	{
+	LOGTEXT(_L("RWriterController::InitialisePluginStream - entry"));
+	if( iPluginArray )
+		{
+		TInt pluginCount(iPluginArray->Count());
+	
+		LOGSTRING2("RWriterController::InitialisePluginStream - plugin count %d, searching through", pluginCount);
+	  	for(TInt i=0;i<pluginCount;i++)
+	  	    {
+  			LOGSTRING2("RWriterController::InitialisePluginStream - getting plugin n:o: %d...", i);
+	    	CWriterPluginInterface* plugin = iPluginArray->At(i);
+	  		LOGSTRING2("RWriterController::InitialisePluginStream - writer found, 0x%x, initializing stream...", plugin->Id());
+    		plugin->SetStream(iStream);
+	  		LOGTEXT(_L("RSamplerController::InitialisePluginStream - succeeded!"));
+	  	    }
+	  	}
+	LOGTEXT(_L("RSamplerController::InitialisePluginStream - exit"));
+
+	}
+
+CArrayPtrFlat<CWriterPluginInterface>* CWriterController::GetPluginList()
+    {
+	return iPluginArray;
+    }
+
+void CWriterController::HandlePluginLoaded( KWriterPluginLoaderStatus aStatus )
+    {
+    
+    switch(aStatus)
+        {
+        case 0:
+            LOGSTRING2("RWriterController - one plugin loaded, status: %d", aStatus);
+            break;
+        case 1:
+            LOGSTRING2("RWriterController - a plugin load failed: %d", aStatus);
+            break;
+        case 2:
+            LOGSTRING2("RWriterController - plugin loading aborted: %d", aStatus);
+            break;
+        case 3:
+            LOGSTRING2("RWriterController - all plugins loaded: %d", aStatus);
+            // set stream after all loaded writer plugins
+            InitialisePluginStream();
+            break;
+        case 4:
+            LOGSTRING2("RWriterController - error in loading plugins: %d", aStatus);
+            break;
+        default:
+            break;
+        }
+    }
+
+
+
+TUid CWriterController::GetPluginUID(TInt traceId)
+    {
+	LOGSTRING2(" RWriterController::GetPluginUID - checking UID for traceId = %d",traceId);	
+	// this part has to be changed for each new writer
+
+    if( iPluginArray && iPluginArray->Count() > 0 )
+        {
+        for(TInt i=0;i<iPluginArray->Count();i++)
+            {
+            CWriterPluginInterface* plugin = iPluginArray->At(i); 
+            if(plugin->Id().iUid == traceId)
+                {
+                LOGSTRING2(" RWriterController::GetPluginUID - got: 0x%X",plugin->Id());	
+                return plugin->Id();
+                }
+            }
+        }	
+	return KWriterNoneSelected;
+
+    }
+
+CWriterPluginInterface* CWriterController::GetActiveWriter()
+    {
+    CWriterPluginInterface* plugin = NULL;
+
+	if( iPluginArray )
+		{
+		TInt count(iPluginArray->Count());
+		
+		for(TInt i=0;i<count;i++)
+			{
+			plugin = iPluginArray->At(i); 
+			if(plugin->GetEnabled())
+				{
+				return plugin;
+				}
+			}
+		}
+
+    return (CWriterPluginInterface*)0;
+    }
+
+TUint32 CWriterController::GetWriterType(TUint32 writerId)
+    {
+    TUid id;
+    
+    id = this->GetPluginUID(writerId);
+    
+    if(id != KWriterNoneSelected)
+        return GetPlugin(id)->GetWriterType();
+    else
+        return 0;
+    }
+
+CWriterPluginInterface* CWriterController::GetPlugin(TUid aUid)
+    {
+    if( iPluginArray && iPluginArray->Count() > 0 )
+        {
+        for(TInt i=0;i<iPluginArray->Count();i++)
+            {
+            CWriterPluginInterface* plugin = iPluginArray->At(i); 
+            // check if searched uid found
+            if(plugin->Id().iUid == aUid.iUid)
+                {
+                // return pointer to found plugin
+                return plugin;
+                }
+            }
+        }
+    // return null plugin
+	return (CWriterPluginInterface*)0;
+    }
+
+TInt CWriterController::StartSelectedPlugin()
+	{
+	LOGTEXT(_L("RWriterController::StartSelectedPlugin - entry"));
+	
+    CWriterPluginInterface* plugin = GetActiveWriter();
+    
+    if(plugin)
+        {
+        return plugin->Start();
+		}
+    
+	LOGTEXT(_L("RWriterController::StartSelectedPlugin - exit"));
+	return KErrNotFound;
+	}
+
+void CWriterController::StopSelectedPlugin()
+	{
+	LOGTEXT(_L("RWriterController::StopSelectedPlugin - entry"));
+    
+    CWriterPluginInterface* plugin = GetActiveWriter();
+    
+	if(plugin)
+		{
+		plugin->Stop();
+		}
+	LOGTEXT(_L("RWriterController::StopSelectedPlugin - exit"));
+	}
+
+/** Set selected plugin active **/
+void CWriterController::SetPluginActive(TUid uid, const TWriterPluginValueKeys aKey)
+    {
+	CWriterPluginInterface* plugin = NULL;
+	_LIT(KDummy, "");
+	TBuf<1> buf;
+	buf.Append(KDummy);
+
+	for(TInt i(0);i<iPluginArray->Count();i++)
+	    {
+	    plugin = iPluginArray->At(i);
+	    if(plugin->Id().iUid == uid.iUid)
+	        {
+	        plugin->SetValue(aKey, buf);
+	        }
+	    else
+	        {
+	        plugin->SetValue(EWriterPluginDisabled, buf);
+	        }
+	    }
+    }
+
+TInt CWriterController::SetPluginSettings(TUid aUid, TDes& aDes)
+    {
+	LOGSTRING2(" CWriterController::SetPluginSettings, traceId = 0x%X", aUid.iUid);	
+	GetPlugin(aUid)->SetValue(EWriterPluginSettings, aDes);
+	return KErrNone;
+    }
+
+/** Get settings for a specific plugin **/
+void CWriterController::GetPluginSettings(TUid uid, TDes& aVal)
+    {
+	GetPlugin(uid)->GetValue(EWriterPluginSettings, aVal);
+    }
+
+
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/WriterPluginLoader.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,565 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include    "WriterPluginLoader.h"
+//#include	<piprofiler/EngineUIDs.h>
+#include    <utf.h> // CnvUtfConverter
+#include  	<basched.h>
+
+// constants
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NewL
+//
+// EPOC two-phased constructor
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader* CWriterPluginLoader::NewL()
+    {
+    CWriterPluginLoader* self = new( ELeave ) CWriterPluginLoader;
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CWriterPluginLoader
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader::CWriterPluginLoader() : CActive( EPriorityStandard )
+    {
+    LOGTEXT(_L("CWriterPluginLoader()::CWriterPluginLoader()" ));
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ConstructL
+//
+// EPOC default constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::ConstructL( )
+    {
+    LOGTEXT(_L("CWriterPluginLoader()::ConstructL()" ));
+    
+    // get list of implementations
+    CWriterPluginInterface::ListAllImplementationsL( iImplInfoArray );
+    
+    CActiveScheduler::Add( this );
+    }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::~CWriterPluginLoader
+//
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader::~CWriterPluginLoader()
+    {
+    LOGTEXT(_L("CWriterPluginLoader()::~CWriterPluginLoader()") );
+
+    AbortAsyncLoad();
+
+    Cancel();
+
+    // reset ECOM implementation info array
+    iImplInfoArray.ResetAndDestroy(); // This is needed
+    iImplInfoArray.Close();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadAsync
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::LoadAsyncL( CArrayPtrFlat<CWriterPluginInterface>* aPluginArray )
+    {
+    iPluginArray = aPluginArray;
+    
+    // Reset iterator:
+    iImplInfoArrayIterator = 0;
+
+    LOGSTRING2( "CWriterPluginLoader()::Implementation info count: %d",
+        iImplInfoArray.Count() );
+
+    NotifyProgress();
+
+    //Begin CActive asynchronous loop.
+    CompleteOwnRequest();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadSyncL
+//
+//
+// ----------------------------------------------------------------------------
+//
+CWriterPluginInterface& CWriterPluginLoader::LoadSyncL( TUid aImplementationUid )
+    {
+    Cancel();
+    CWriterPluginInterface* plugin = NULL;
+
+    // Get a list of all implementations, even though we only want one specific
+    // one. There appears to be no way to otherwise extract a specific implementation
+    // info object :(
+    // Search for the implementation that matches aImplementationUid
+    const TInt impCount = iImplInfoArray.Count();
+    for( TInt i=0; i<impCount; i++ )
+        {
+        const CImplementationInformation* info = iImplInfoArray[ i ];
+        if  ( info->ImplementationUid() == aImplementationUid )
+            {
+            TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); );
+            if( ret == KErrNone )
+                {
+                // Plugin ownership is transfered to iPluginArray
+                InsertPluginInOrderL( plugin, iPluginArray );
+                }
+            else
+                {
+                // Error note is displayed even if plugin is not loaded
+                LOGSTRING2("CWriterPluginLoader::LoadSyncL() - plugin load failed, error %d", ret);
+                }
+            break;
+            }
+        }
+
+    if  ( plugin == NULL )
+        {
+        User::Leave( KErrNotFound );
+        }
+    return *plugin;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::AbortAsyncLoad
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::AbortAsyncLoad()
+    {
+    LOGTEXT(_L("CWriterPluginLoader()::AbortAsyncLoad()" ));
+    Cancel();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::RunL
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::RunL()
+    {
+    iRunLDebugCount++;
+    LoadNextPluginL();
+
+    // Check if there are still more plugins to be loaded:
+    if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
+        {
+        NotifyProgress();
+        // Continue CActive asynchronous loop.
+        CompleteOwnRequest();
+        }
+    else
+        {
+        // All plugins loaded:
+        LOGTEXT(_L("CWriterPluginLoader()::Loading plugins finished." ));
+        NotifyFinished();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CScGenreItemConstructionConductor::CompleteOwnRequest
+//
+// Issue request complete notification.
+// ---------------------------------------------------------------------------
+void CWriterPluginLoader::CompleteOwnRequest()
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::RunError
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::RunError( TInt aError )
+    {
+    // This method is called when a plugin loading fails.
+    // Always "fake" the return value so that ActiveSchedule
+    // keeps running and later plugins are continued to be loaded.
+    // Check if still plugins to be loaded:
+    if( iImplInfoArrayIterator < iImplInfoArray.Count() )
+        {
+        NotifyProgress();
+
+        //Continue CActive asynchronous loop.
+        CompleteOwnRequest();
+        }
+    else // All plugins loaded:
+        {
+        NotifyFinished();
+        }
+
+    if ( aError == KLeaveExit )
+        {
+        return KLeaveExit;
+        }
+
+    return KErrNone;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::DoCancel
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::DoCancel()
+    {
+
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NotifyProgress
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::NotifyProgress()
+    {
+    if( iObserver )
+        {
+        iObserver->HandlePluginLoaded( MWriterPluginLoadObserver::EWriterSuccess);
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NotifyFinished
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::NotifyFinished()
+    {
+    if( iObserver )
+        {
+        iObserver->HandlePluginLoaded( MWriterPluginLoadObserver::EWriterFinished );
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::SetObserver
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::SetObserver(MWriterPluginLoadObserver* aObserver)
+    {
+    LOGSTRING2("CWriterPluginLoader()::Observer set:0x%X", aObserver);
+    iObserver = aObserver;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ParseToUid
+// Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
+    {
+    // Remove "0x" from the descriptor if it exists
+    _LIT8(KHexPrefix, "0x");
+
+    TPtrC8 pSource( aSource );
+    const TInt prefixPosition = pSource.Find( KHexPrefix );
+    if  ( prefixPosition != KErrNotFound )
+        {
+        pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
+        }
+
+    // Parse to integer
+    TLex8 lex( pSource );
+    TUint integer = 0;
+
+    // Parse using TRadix::EHex as radix:
+    const TInt err = lex.Val( integer, EHex );
+    aTarget.iUid = integer;
+
+    if( err != KErrNone )
+        {
+        // If parsing parent UID failed, do not load plugin:
+        LOGSTRING2(
+            "CWriterPluginLoader()::Parsing parent UID failed. Error code:%d",
+            err );
+        }
+    return err;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ParseOrderNumber
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
+    {
+    // Parse plugin's order number from opaque_data:
+    TLex8 lex( aSource );
+    const TInt orderErr = lex.Val( aOrderNumber );
+    return orderErr;
+    }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadNextPluginL
+// Iterate through iImplInfoArray. Load the plugin if it is eligible for
+// loading. Loaded plugin is added to iPluginArray. Each time a plugin is
+// loaded, iObserver is notified.
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::LoadNextPluginL()
+    {
+    // Iterate through iImplInfoArray. This loop continues between function
+    // calls. Therefore member variable iImplInfoArrayIterator is used as a
+    // counter. Loop will break when match is found and continues on next RunL.
+    for( ; iImplInfoArrayIterator < iImplInfoArray.Count();  )
+        {
+        const CImplementationInformation* info =
+            iImplInfoArray[ iImplInfoArrayIterator ];
+
+        iImplInfoArrayIterator++;
+
+        // If this plugin is OK -> load it:
+        LOGSTRING2( "CWriterPluginLoader() %S eligible for parent",
+                &info->DisplayName() );
+        CWriterPluginInterface* plugin = NULL;
+        TInt error(KErrNone);
+        // Create plugin. Trap leave for debugging purposes.
+        TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
+        if( error == KErrNone )
+            {
+            // Plugin ownership is transfered to iPluginArray
+            InsertPluginInOrderL( plugin, iPluginArray );
+            }
+        else
+            {
+            LOGSTRING2("CWriterPluginLoader::LoadNextPluginL() - plugin load failed, error %d", error);
+            }
+        // Wait for next round
+        break;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CreatePluginInstanceL
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+CWriterPluginInterface& CWriterPluginLoader::CreatePluginInstanceL(
+    const CImplementationInformation& aImpInfo )
+    {
+    // Now we can load the plugin
+    const TUid implUid = aImpInfo.ImplementationUid();
+
+    CWriterPluginInterface* plugin = CWriterPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() );
+    CleanupStack::PushL ( plugin );
+   
+    TInt orderNumber(0);
+    const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
+    
+    if  ( orderErr == KErrNone && orderNumber >= 0 )
+        {
+        plugin->iOrder = orderNumber;
+        }
+
+    CleanupStack::Pop( plugin ); // CWriterController is now responsible for this memory.
+
+    return *plugin;
+    }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::SortPluginsL
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::SortPluginsL(
+        CArrayPtrFlat<CWriterPluginInterface>* aPlugins )
+    {
+    RPointerArray<CWriterPluginInterface> plugins;
+    TLinearOrder<CWriterPluginInterface> order( CWriterPluginLoader::Compare );
+
+    // Insertion will also order
+    for( TInt i = 0; i < aPlugins->Count(); i++ )
+        {
+        plugins.InsertInOrderL( (*aPlugins)[i], order );
+        }
+
+    // Replace original array content with sorted items
+    aPlugins->Reset();
+    for( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        aPlugins->AppendL( plugins[i] );
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::Compare
+//
+// Compare two plugins.
+// Precedence:
+// [1. plugin provider category]
+// 2. plugin order number
+// 3. plugin caption
+// Plugin provider gategory is currently disabled (not supported yet).
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::Compare( const CWriterPluginInterface& aFirst,
+                               const CWriterPluginInterface& aSecond )
+    {
+    return CompareIndex( aFirst, aSecond );
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::InsertPluginInOrderL
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::InsertPluginInOrderL(
+    CWriterPluginInterface* aPlugin,
+    CArrayPtrFlat<CWriterPluginInterface>* aPlugins )
+    {
+    CWriterPluginInterface* comparedPlugin;
+    TInt comparison = 0;
+    TBool inserted = EFalse;
+
+    for( TInt i = 0; i < aPlugins->Count(); i++ )
+        {
+        comparedPlugin = (*aPlugins)[i];
+        // Optimization: do not call time consuming Compare() multiple times!
+        comparison = Compare( *aPlugin, *comparedPlugin );
+        if( comparison < 0 )
+            {
+            aPlugins->InsertL( i, aPlugin );
+            inserted = ETrue;
+            break;
+            }
+        else if( comparison == 0 )
+            {
+            aPlugins->InsertL( i+1, aPlugin );
+            inserted = ETrue;
+            break;
+            }
+        }
+    // Plugin was not before any other plugin - make sure it's appended
+    if( !inserted )
+        {
+        aPlugins->AppendL( aPlugin );
+        }
+
+    #ifdef _GS_PLUGINLOADER_SORTING_TRACES
+        PrintOrderTraces( aPlugins );
+    #endif // _GS_PLUGINLOADER_SORTING_TRACES
+
+    }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CompareIndex
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+TInt CWriterPluginLoader::CompareIndex( const CWriterPluginInterface& aFirst,
+                                    const CWriterPluginInterface& aSecond )
+    {
+    TInt comparison = KWriterComparisonEqual;
+    // The plugin having index is before the one not having one
+
+    if( aFirst.iOrder  == KWriterPluginNotIndexed &&
+        aSecond.iOrder == KWriterPluginNotIndexed )
+        {
+        // Neither have index -> equal
+        comparison = KWriterComparisonEqual;
+        }
+    else if( aFirst.iOrder == KWriterPluginNotIndexed )
+        {
+        // The plugin having index is before the one not having one
+        comparison = KWriterComparisonAfter;
+        }
+    else if( aSecond.iOrder == KWriterPluginNotIndexed )
+        {
+        // The plugin having index is before the one not having one
+        comparison = KWriterComparisonBefore;
+        }
+    else if( aFirst.iOrder < aSecond.iOrder )
+        {
+        // Compare actual index values
+        comparison = KWriterComparisonBefore;
+        }
+    else if( aFirst.iOrder > aSecond.iOrder )
+        {
+        // Compare actual index values
+        comparison = KWriterComparisonAfter;
+        }
+    return comparison;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::GetDocument
+//
+//
+// ----------------------------------------------------------------------------
+//
+/*
+CWriterBaseDocument* CWriterPluginLoader::GetDocument()
+    {
+    CWriterBaseDocument* document = static_cast<CWriterBaseDocument*>( iAppUi->Document() );
+    return document;
+    }
+*/
+
+//  End of File
Binary file piprofiler/group/ReleaseNotes_PIProfiler.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+//PRJ_PLATFORMS
+//DEFAULT ARMV5SMP
+
+#include <platform_paths.hrh>
+
+#include "../piprofiler_plat/group/bld.inf"
+#include "../engine/group/bld.inf"
+#include "../plugins/GeneralsPlugin/group/bld.inf"
+#include "../plugins/BUPplugin/group/bld.inf"
+#include "../plugins/DebugOutputWriterPlugin/group/bld.inf"
+#include "../plugins/DiskWriterPlugin/group/bld.inf"
+
+
+PRJ_EXPORTS
+../rom/piprofiler.iby CORE_IBY_EXPORT_PATH(tools,piprofiler.iby)
+../rom/piprofiler_ldd.iby CORE_IBY_EXPORT_PATH(tools/rom,piprofiler_ldd.iby)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  File that exports the files belonging to 
+:                PIProfilerAPI
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+PRJ_EXPORTS
+../inc/ProfilerTraces.h                   OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerTraces.h)
+../inc/ProfilerVersion.h                  OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerVersion.h)
+../inc/ProfilerConfig.h                   OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerConfig.h)
+../inc/ProfilerAttributes.h               OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerAttributes.h)
+../inc/ProfilerGenericClassesUsr.h        OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesUsr.h)
+../inc/ProfilerGenericClassesUsr.inl      OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesUsr.inl)
+../inc/ProfilerGenericClassesKrn.h        OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesKrn.h)
+../inc/ProfilerGenericClassesKrn.inl      OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesKrn.inl)
+../inc/ProfilerGenericClassesCommon.h     OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesCommon.h)
+../inc/ProfilerEngineAPI.h 				  OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineAPI.h)
+../inc/EngineUIDs.h                       OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/EngineUIDs.h)
+../inc/PluginDriver.h                     OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginDriver.h)
+../inc/PluginDriver.inl                   OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginDriver.inl)
+../inc/PluginSampler.h                    OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginSampler.h)
+../inc/ProfilerSession.h                  OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerSession.h)
+../inc/SamplerPluginInterface.h           OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/SamplerPluginInterface.h)
+../inc/SamplerPluginInterface.inl         OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/SamplerPluginInterface.inl)
+../inc/WriterPluginInterface.h            OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/WriterPluginInterface.h)
+../inc/WriterPluginInterface.inl          OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/WriterPluginInterface.inl)
+../inc/ProfilerEngineStatusChecker.h      OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineStatusChecker.h)
+../inc/ProfilerEngineStatusChecker.inl    OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineStatusChecker.inl)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/EngineUIDs.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef ENGINEUIDS_H
+#define ENGINEUIDS_H
+
+#include <e32cmn.h>
+
+// No item is selected in the container's listbox
+const TUid KSamplerNoneSelected = { 0x00000001 };
+const TUid KWriterNoneSelected = { 0x00000002 };
+
+#endif // ENGINEUIDS_H
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginDriver.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+const TInt KMinRate = 10;
+const TInt KMaxRate = 1000;
+
+enum TState{ERunning, EStopping, EStopped};
+
+const TUid KGppPropertyCat={0x20201F70};
+enum TGppPropertyKeys
+	{
+	EGppPropertySyncSampleNumber
+	};
+
+
+/*
+ *
+ *
+ *	Class DPluginDriver definition, inherited by sampler implementations except GPP
+ *
+ *
+ */
+
+class DPluginDriver : public DLogicalChannel
+{
+
+public:
+	DPluginDriver();
+	~DPluginDriver();
+
+public:	
+	TInt					ProcessStreamReadCancel();
+
+	TInt					StopSampling();
+
+private:
+	TInt					ProcessPrintStreamRequest(TDesC8* aDes/*,TRequestStatus* aStatus*/);
+	
+	void 					FastPrintf(TDesC8* aDes);
+ 
+public:
+	DThread*				iClient;
+
+	// property and value; 
+	// GPP sampler start time, needed to set other samplers in sync
+	RPropertyRef 			iSampleStartTimeProp;
+	TInt					iSampleStartTime;
+	TUint32 				iSyncOffset;		// offset from the start
+	
+	
+	TUint32					sampleRunning;
+	const TUint*			iInterruptStack;
+	TState					iState;
+	TInt					doingDfc;
+
+	// request status objects for requests
+	TRequestStatus*			iEndRequestStatus;
+	TRequestStatus*			iStreamReadCancelStatus;
+
+	// sample stream object used in stream mode
+	DProfilerSampleStream		iSampleStream;
+
+	// just for testing
+	TUint32*				stackTop;
+
+};
+
+#include <piprofiler/PluginDriver.inl>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginDriver.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+//
+// LDD for thread time profiling
+//
+
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+
+
+#include <kern_priv.h>
+#include <sproperty.h>
+
+#include <piprofiler/PluginSampler.h>
+
+
+/*
+ *
+ *
+ *	Class DPluginDriver implementation
+ *
+ *
+ */
+inline DPluginDriver::DPluginDriver() //: iSubsRequest(&HandleSubsComplete, this)
+	{
+    //iClientProcess = &Kern::CurrentProcess();
+	}
+inline DPluginDriver::~DPluginDriver()
+	{
+	
+	}
+
+/*
+ *	Methods for controlling stream read option
+ */
+ 
+inline TInt DPluginDriver::ProcessStreamReadCancel()
+{
+	return KErrNone;
+}
+
+/*
+ *	Mark traces active or inactive, this can be done
+ *	only if sampling is not running
+ */
+
+inline TInt DPluginDriver::StopSampling()
+{
+	if(this->iState == ERunning)
+	{
+		this->iState = EStopping;
+		return KErrNone;
+	}
+	else
+	{
+		return KErrGeneral;
+	}
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginSampler.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,247 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PLUGINSAMPLER_H__
+#define __PLUGINSAMPLER_H__
+
+/*
+ * The user-interface to the sampling device driver sued by the profiling engine
+ */
+//	#include <piprofiler/ProfilerConfig.h>
+//	#include <piprofiler/ProfilerVersion.h>	// versions removed from ProfilerConfig.h
+
+#ifndef __KERNEL_MODE__
+#include <utf.h>
+#endif
+
+/*
+ *	Forward declarations
+ */
+class TBapBuf;
+
+/**
+ * A minimal capabilities class for the Sampling device.
+ * It just returns the version number.
+ */
+class TCapsSamplerV01
+	{
+public:
+	TVersion	iVersion;
+	};
+
+
+const TInt KMinDelay = 1;
+const TInt KMaxDelay = 10000;
+
+/**
+ * The user device driver class for controlling the plugin sampler.
+ */
+
+class RPluginSampler :  public RBusLogicalChannel
+{	
+	friend class DPluginDriver;
+	public:
+		enum TControl
+		{
+			EOutputSettingsForTrace,
+			EMarkTraceActive,
+			EMarkTraceInactive,
+			ESample,
+			EStartSampling,
+			EGetSampleTime,
+			EGetSamplerVersion,
+			EStopAndWaitForEnd,
+			ESetSamplingPeriod,
+			EAdditionalTraceSettings,
+			EAdditionalTraceSettings2,
+			EAdditionalTraceSettings3,
+			EAdditionalTraceSettings4,
+			//EPrintTraces,
+			ECancelStreamRead,
+			ERequestFillThisStreamBuffer,
+			ERequestPrintStreamBuffer,
+			ETest
+		};
+
+	public:
+		#ifndef __KERNEL_MODE__
+		
+		inline ~RPluginSampler();
+			
+		/**
+		 * 
+		 * Methods for controlling the sampler device
+		 * 
+		 **/
+		/** Open a channel to the sampling device **/
+		virtual TInt Open() = 0;
+
+		/** Set sampling period for sampler */
+		inline void SetSamplingPeriod(TInt samplerId, TInt settings);
+		
+		/** Set additional trace settings **/
+		inline void AdditionalSettingsForTrace(TInt samplerId,TInt settings);
+		inline void AdditionalSettingsForTrace2(TInt samplerId,TInt settings);
+		inline void AdditionalSettingsForTrace3(TInt samplerId,TInt settings);
+		inline void AdditionalSettingsForTrace4(TInt samplerId,TInt settings);
+		
+		/** Mark trace active **/
+		inline void MarkTraceActive(TUint32 id);
+
+		/** Mark trace inactive **/
+		inline void MarkTraceInactive(TUint32 id);
+
+		/** Sample command to kernel LDD**/
+		inline void Sample();
+		
+		/** Start tracing **/
+		inline void StartSampling();
+
+		/** Stop tracing **/
+		inline void StopSampling();
+
+		/** Get current sampling time **/
+		inline TUint32 GetSampleTime();
+
+		/** Get sampler version as descriptor **/
+		virtual void GetSamplerVersion(TDes*);
+
+		/** Get next filled buffer in stream mode **/
+		void GetNextbuffer( );
+
+		/** Request stream read **/
+		void FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus);
+
+		/** Request print buffer**/
+		void PrintStreamBuffer(TDesC16* aBuffer);
+		
+		/** Run test case **/
+		inline void Test(TUint32 testCase);
+
+		#endif	// !__KERNEL_MODE__	
+};
+
+
+#ifndef __KERNEL_MODE__
+inline RPluginSampler::~RPluginSampler()
+{
+}
+
+inline void RPluginSampler::AdditionalSettingsForTrace(TInt samplerId,TInt settings)
+	{
+	DoControl(EAdditionalTraceSettings,
+			reinterpret_cast<TAny*>(samplerId),
+			reinterpret_cast<TAny*>(settings));
+	}
+
+inline void RPluginSampler::AdditionalSettingsForTrace2(TInt samplerId,TInt settings)
+	{
+	DoControl(EAdditionalTraceSettings2,
+			reinterpret_cast<TAny*>(samplerId),
+			reinterpret_cast<TAny*>(settings));
+	}
+
+inline void RPluginSampler::AdditionalSettingsForTrace3(TInt samplerId,TInt settings)
+	{
+	DoControl(EAdditionalTraceSettings3,
+			reinterpret_cast<TAny*>(samplerId),
+			reinterpret_cast<TAny*>(settings));
+	}
+
+inline void RPluginSampler::AdditionalSettingsForTrace4(TInt samplerId,TInt settings)
+	{
+	DoControl(EAdditionalTraceSettings4,
+			reinterpret_cast<TAny*>(samplerId),
+			reinterpret_cast<TAny*>(settings));
+	}
+
+inline void RPluginSampler::SetSamplingPeriod(TInt samplerId, TInt settings)
+	{
+	DoControl(ESetSamplingPeriod, 
+			reinterpret_cast<TAny*>(samplerId),
+			reinterpret_cast<TAny*>(settings));
+	}
+
+
+inline void RPluginSampler::MarkTraceActive(TUint32 id)
+{
+		DoControl(EMarkTraceActive, reinterpret_cast<TAny*>(id));
+}
+
+inline void RPluginSampler::MarkTraceInactive(TUint32 id)
+{
+		DoControl(EMarkTraceInactive, reinterpret_cast<TAny*>(id));
+}
+
+inline void RPluginSampler::Sample()
+	{
+	DoControl(ESample);
+	}
+
+inline void RPluginSampler::StartSampling()
+{
+	// at first, start the kernel side samplers
+	DoControl(EStartSampling);
+}
+
+inline void RPluginSampler::StopSampling()
+{
+	// stop the device driver and the kernel mode samplers
+	TRequestStatus status;
+	status = KRequestPending;
+	DoRequest(EStopAndWaitForEnd,status);
+	User::WaitForRequest(status);
+}
+
+inline TUint32 RPluginSampler::GetSampleTime()
+{
+	TUint32* sampleTime = new TUint32;
+
+	DoControl(EGetSampleTime,reinterpret_cast<TAny*>(sampleTime));
+	TUint32 value = *sampleTime;
+	delete sampleTime;
+
+	return value;
+}
+
+inline void RPluginSampler::GetSamplerVersion(TDes* aDes)
+{
+	TBuf8<16> buf;
+	DoControl(EGetSamplerVersion,(TAny*)&buf);
+	CnvUtfConverter::ConvertToUnicodeFromUtf8(*aDes,buf);
+}
+
+inline void RPluginSampler::PrintStreamBuffer(TDesC16* aDes) 
+{
+	DoControl(ERequestPrintStreamBuffer,reinterpret_cast<TAny*>(aDes));
+}
+
+inline void RPluginSampler::FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus)
+{
+	aStatus = KRequestPending;
+	DoRequest(ERequestFillThisStreamBuffer,aStatus,(TAny*)aBuffer);
+
+}
+
+inline void RPluginSampler::Test(TUint32 testCase)
+{
+	DoControl(ETest,reinterpret_cast<TAny*>(testCase));
+}
+
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerAttributes.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_ATTRIBUTES_H
+#define PROFILER_ATTRIBUTES_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include <s32mem.h>
+
+// LITERALS
+_LIT8(KDefaultTraceFilePrefix, "PIProfiler_#");
+_LIT8(KDefaultTraceOutput, "file_system");
+_LIT8(KDefaultTraceFileSaveDrive, "C:\\data\\");
+
+_LIT8(KEnabled, "enabled");
+_LIT8(KBracketOpen, "[");
+_LIT8(KBracketClose, "]");
+_LIT8(KSettingItemSeparator, "=");
+
+// CONSTANTS
+const TUint KPrefixMaxLength = 64;
+const TUint KShortNameMaxLength = 3;
+const TUint KNameMaxLength = 63;
+const TUint KDescriptionMaxLength = 255;
+const TInt KDefaultTimedSamplingPeriod = 60; // Sampling time in seconds 
+/*
+ * 
+ * TGeneralAttributes class definition, internal settings format
+ *  
+ */
+class TGeneralAttributes
+    {
+public:
+    TBuf8<KPrefixMaxLength> iTraceOutput;
+    TBuf8<KPrefixMaxLength> iTraceFilePrefix;
+    TBuf8<KPrefixMaxLength> iSaveFileDrive;
+    TInt                    iTimedSamplingPeriod;
+    };
+
+
+
+/*
+ * 
+ * TSettingItem class definition, internal settings format
+ *  
+ */
+class TSettingItem
+    {
+public:
+    enum 
+    {
+        ESettingItemTypeInt = 0,
+        ESettingItemTypeBool,
+        ESettingItemTypeHex,
+        ESettingItemTypeText
+    };
+    
+public:
+    TBuf<64>   iSettingText;
+    TUint32    iType;
+    TBuf<128>  iValue;
+    TBuf<256>  iSettingDescription;
+    TBuf<64>   iUIText;
+    };
+/*
+ * 
+ * TSamplerAttributes class definition, internal settings format
+ *  
+ */
+class TSamplerAttributes
+    {
+public:
+    // default constructor
+    TSamplerAttributes();
+    // constructor
+    TSamplerAttributes(TInt32 aUid,
+    const TDesC8& aShortName,
+    const TDesC8& aName,
+    const TDesC8& aDescription,
+    TInt aSampleRate,
+    TBool aEnabled,
+    TBool aHidden,
+    TInt aItemCount);
+public:
+    TInt32      iUid;
+    TBuf8<8>    iShortName;     // name of the plugin, short name
+    TBuf8<64>   iName;          // name of the plugin, long name
+    TBuf8<256>  iDescription;   // sampler description, info about HW/SW dependencies etc.
+    TInt        iSampleRate;    // sample rate of the plugin
+    TBool       iEnabled;       // enabled for profiling
+    TBool       iIsHidden;      // hidden, i.e. no start/stop controls
+    TInt        iItemCount;     // plugin specific setting item count
+    
+    // plugin specific settings, plugin implementation dependent
+    TSettingItem    iSettingItem1;
+    TSettingItem    iSettingItem2;
+    TSettingItem    iSettingItem3;
+    TSettingItem    iSettingItem4;
+    TSettingItem    iSettingItem5;
+    TSettingItem    iSettingItem6;
+    };
+
+inline TSamplerAttributes::TSamplerAttributes()
+    {}
+
+inline TSamplerAttributes::TSamplerAttributes(TInt32 aUid,
+            const TDesC8& aShortName,
+            const TDesC8& aName,
+            const TDesC8& aDescription,
+            TInt aSampleRate,
+            TBool aEnabled,
+            TBool aHidden,
+            TInt aItemCount)
+    {
+    iUid = aUid;
+    // check if given short name too long
+    aShortName.Length() > KShortNameMaxLength ? 
+        iShortName.Copy(aShortName.Left(KShortNameMaxLength)) : 
+        iShortName.Copy(aShortName);
+    // check if given name too long
+    aName.Length() > KNameMaxLength ? 
+        iName.Copy(aName.Left(KNameMaxLength)) : 
+        iName.Copy(aName);
+    // check if description too long
+    aDescription.Length() > KDescriptionMaxLength ? 
+        iDescription.Copy(aDescription.Left(KDescriptionMaxLength)) : 
+        iDescription.Copy(aDescription);
+    iSampleRate = aSampleRate;
+    iEnabled = aEnabled;
+    iIsHidden = aHidden;
+    iItemCount = aItemCount;
+    }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerConfig.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PI_PROFILER_CONFIG_H
+#define PI_PROFILER_CONFIG_H
+
+// NCP release process will move the PIProfiler flags as Carbon feature flags
+// where the product responsibles can choose the right settings for PI Profiler
+// compilation.
+
+	/*** NOTE!!! 
+	* 	Uncomment the following definition if compiling the Profiler by your own
+	***/
+	#define PROFILER_SISX
+
+	/*
+	 *
+	 *	Filename and path for the settings file
+	 *  this file is written on application exit and
+	 *	it contains the settings of the profiler application
+	 *
+	 */	
+	 
+//	#define PROFILER_SETTINGS_DRIVE		_L("C:\\")
+//	#define PROFILER_SETTINGS_MAXLENGTH	32
+//	#define PROFILER_SETTINGS_FILENAME	_L("ProfilerSettings.txt")
+	const TInt KProfilerSettingsMaxLength = 32;
+	_LIT(KProfilerSettingsFileName, "PIProfilerSettings.txt");
+
+	// a fix for going through the different drives for settings file
+	#define PROFILER_SETTINGS_DRIVE_COUNT				3
+	#define	PROFILER_SETTINGS_DRIVE_ARRAY 			TBuf<4> settingsDrives[PROFILER_SETTINGS_DRIVE_COUNT];
+	#define PROFILER_DEFINE_SETTINGS_DRIVE(name,number)	settingsDrives[number].Append(_L(name));										
+
+	// change these to reflect the drive names and numbers
+	// the last number must be PROFILER_SETTINGS_DRIVE_COUNT-1
+	#define PROFILER_SETTINGS_DRIVES		PROFILER_DEFINE_SETTINGS_DRIVE("C:\\",0) \
+		PROFILER_DEFINE_SETTINGS_DRIVE("E:\\",1) \
+		PROFILER_DEFINE_SETTINGS_DRIVE("Z:\\",2)			
+		
+	/*
+	 *
+	 *	Locations of PI Profiler binaries
+	 *
+	 */
+
+	#define PROFILERENGINE_EXE_PATH_PRIMARY		_L("C:\\sys\\bin\\PIProfilerEngine.exe")
+	#define PROFILERENGINE_EXE_PATH_SECONDARY	_L("Z:\\sys\\bin\\PIProfilerEngine.exe")
+
+	/*
+	 *
+	 *	PI Profiler tool composition definitions
+	 *
+	 */	
+
+	// sampler codes and names
+	#define		PROFILER_USER_MODE_SAMPLER		123
+	#define		PROFILER_KERNEL_MODE_SAMPLER		321
+	#define		PROFILER_DUMMY_SAMPLER			213
+
+	// old definitions
+	#define 	PROFILER_GENERALS_SAMPLER_ID		100
+	#define 	PROFILER_INTERNALS_SAMPLER_ID		101
+	#define		PROFILER_GPP_SAMPLER_ID			1
+	#define		PROFILER_GFC_SAMPLER_ID			2
+	#define		PROFILER_ITT_SAMPLER_ID			3
+	#define		PROFILER_MEM_SAMPLER_ID			4
+	#define		PROFILER_PRI_SAMPLER_ID			5
+	#define		PROFILER_IRQ_SAMPLER_ID			6
+	#define		PROFILER_BUP_SAMPLER_ID			7
+	#define		PROFILER_SWI_SAMPLER_ID			8
+	#define		PROFILER_TIP_SAMPLER_ID			9
+	#define		PROFILER_PEC_SAMPLER_ID			10
+	#define		PROFILER_PWR_SAMPLER_ID			11
+	#define		PROFILER_IPC_SAMPLER_ID			12
+	#define 	PROFILER_ISA_SAMPLER_ID			13
+    #define     PROFILER_GPU_SAMPLER_ID         14
+
+	// sampler IDs for external, e.g. 3rd party sampler plug-ins
+	#define		PROFILER_EXT1_SAMPLER_ID			15
+	#define		PROFILER_EXT2_SAMPLER_ID			16
+	#define		PROFILER_EXT3_SAMPLER_ID			17
+	#define		PROFILER_EXT4_SAMPLER_ID			18
+	#define		PROFILER_EXT5_SAMPLER_ID			19
+	
+    #define     PROFILER_GPP_SAMPLER_NAME _L("GPP")
+    #define     PROFILER_GFC_SAMPLER_NAME _L("GFC")
+    #define     PROFILER_ITT_SAMPLER_NAME _L("ITT")
+    #define     PROFILER_MEM_SAMPLER_NAME _L("MEM")
+    #define     PROFILER_PRI_SAMPLER_NAME _L("PRI")
+    #define     PROFILER_GPU_SAMPLER_NAME _L("GPU")
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineAPI.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,88 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILERCONTROLLER_H
+#define PROFILERCONTROLLER_H
+
+#include <e32std.h>
+#include <s32stor.h>
+
+class CProfilerSettings;
+
+class CProfilerEngineAPI : public CBase
+{
+public:
+    enum TProfilerEngineTraceMode 
+        { 
+        EProfilerEngineDebugOutputMode, 
+        EProfilerEngineFileSystemMode 
+        };
+    
+	~CProfilerEngineAPI();
+
+	IMPORT_C static CProfilerEngineAPI* NewL();
+	void ConstructL();
+
+	IMPORT_C void SaveSettings();
+	IMPORT_C void LoadSettings();
+
+	// controlling all sampler plugins
+	IMPORT_C TInt StartProfiling();
+	IMPORT_C TBool StopProfiling();
+	IMPORT_C TInt LaunchProfiler();
+
+	// controlling separate plugins
+	IMPORT_C TInt StartSampler(TUint32 aUid);
+	IMPORT_C TInt StopSampler(TUint32 aUid);
+	IMPORT_C TInt EnableSampler(TUint32 aUid);
+	IMPORT_C TInt DisableSampler(TUint32 aUid);
+	IMPORT_C TInt EnableWriter(TUint32 aUid);
+	IMPORT_C TInt DisableWriter(TUint32 aUid);
+
+	// for meeting the HTI requirements
+	IMPORT_C TInt SetSettings(TUint aSamplerId, TDes& aSettings);
+    IMPORT_C TInt SetTraceMode(TProfilerEngineTraceMode aMode, TDes& aTraceDataStruct);
+    IMPORT_C TInt GetSamplerInfo(TUint aSamplerId, TDes& aCompleteSamplerInfo);
+	
+	// old implementations
+	IMPORT_C TBool GetSamplerVersion(TDes& version);
+
+	IMPORT_C void LeaveProfilerBG(TBool aVal);
+	
+	
+public:
+	TBool DriveIsValidL(const TDesC& drive);
+	IMPORT_C CProfilerSettings* Settings() const;
+
+private:
+
+	CProfilerEngineAPI();
+
+	TInt				FindProcessL();
+private:
+	CProfilerSettings* 	iSettings;
+	
+	RProcess* 			iProfilerProcess;
+
+	TBool 				iProfilerLaunched;
+	
+	TBool 				iLeaveProfilerBG;
+
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   
+*
+*/
+
+#ifndef PROFILER_STATUS_CHECKER_H
+#define PROFILER_STATUS_CHECKER_H
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h>    // RProperty
+
+// CONSTANTS
+const TUid KEngineStatusPropertyCat = { 0x2001E5AD };
+enum TEnginePropertyKeys
+    {
+    EProfilerEngineStatus = 8
+    };
+
+// CLASS DECLARATIONS
+class MProfilerStatusObserver
+    {
+    public: // Enums
+        enum KProfilerStatus
+            {
+            EIdle = 0,
+            EInitializing,
+            ERunning,
+            EStopping,
+            ERestarting
+            };
+
+    public: // New
+        virtual void HandleProfilerStatusChange(
+                KProfilerStatus aStatus ) = 0;
+        virtual void HandleProfilerErrorL(
+                TInt aError ) = 0;
+    };
+
+
+class CProfilerEngineStatusChecker : public CActive
+    {
+public:
+    inline static CProfilerEngineStatusChecker* CProfilerEngineStatusChecker::NewL();
+    inline ~CProfilerEngineStatusChecker();
+    inline void SetObserver(MProfilerStatusObserver* aObserver);
+    inline TInt GetInitialState();
+private:
+    inline CProfilerEngineStatusChecker();
+    inline void ConstructL();
+    inline void RunL();
+    inline void DoCancel();
+private:
+    TInt                        iPrevStat;
+    MProfilerStatusObserver*    iObserver;
+    RProperty                   iEngineStatus;
+    };
+
+#include <piprofiler/ProfilerEngineStatusChecker.inl>
+
+
+#endif // PROFILER_STATUS_CHECKER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   
+*
+*/
+
+// ------------------------------------------------------------------------------
+//
+// class CProfilerEngineStatusChecker
+//
+// ------------------------------------------------------------------------------
+//
+inline CProfilerEngineStatusChecker* CProfilerEngineStatusChecker::NewL()
+    {
+    CProfilerEngineStatusChecker* self = new(ELeave) CProfilerEngineStatusChecker();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// --------------------------------------------------------------------------------------------
+inline CProfilerEngineStatusChecker::CProfilerEngineStatusChecker() :
+    CActive(EPriorityStandard)
+    {
+    }
+
+inline CProfilerEngineStatusChecker::~CProfilerEngineStatusChecker()
+    {
+    Cancel();
+    iEngineStatus.Close();
+    }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::ConstructL()
+    {
+    User::LeaveIfError(iEngineStatus.Attach(KEngineStatusPropertyCat, EProfilerEngineStatus));
+    CActiveScheduler::Add(this);
+    
+    // check engine status, if not available set to idle
+    if(iEngineStatus.Get(iPrevStat) != KErrNone)
+        {
+        iPrevStat = MProfilerStatusObserver::EIdle;
+        }
+
+    // subscribe to P&S status property
+    iEngineStatus.Subscribe(iStatus);
+    SetActive();
+    }
+
+inline TInt CProfilerEngineStatusChecker::GetInitialState()
+    {
+    // check engine status, if not available set to idle
+    TInt err(iEngineStatus.Get(KEngineStatusPropertyCat, EProfilerEngineStatus, iPrevStat));
+    if(err != KErrNone)
+        {
+        iPrevStat = MProfilerStatusObserver::EIdle;
+        }
+    return iPrevStat;
+    }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::RunL()
+    {
+    // resubscribe before processing new value to prevent missing updates
+    iEngineStatus.Subscribe(iStatus);
+    SetActive();
+
+    TInt stat(0);
+    if(iEngineStatus.Get(KEngineStatusPropertyCat, EProfilerEngineStatus, stat) == KErrNone)
+        {
+        // check if status one of error codes (< 0)
+        if(stat < KErrNone)
+            {
+            // some error occurred on engine side => set UI idle and show an error note
+            iObserver->HandleProfilerErrorL(stat);
+            }
+        else
+            {
+            if(iPrevStat != stat)
+                {
+                switch(stat)
+                    {
+                    case 0:
+                        iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EIdle);
+                        break;
+                    case 1:
+                        iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EInitializing);
+                        break;
+                    case 2:
+                        iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::ERunning);
+                        break;
+                    case 3:
+                        iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EStopping);
+                        break;
+                    default:
+                        iObserver->HandleProfilerErrorL(stat);
+                        break;
+                    }
+                iPrevStat = stat;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------------------------
+ 
+inline void CProfilerEngineStatusChecker::DoCancel()
+    {
+    iEngineStatus.Cancel();
+    }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::SetObserver(MProfilerStatusObserver* aObserver)
+    {
+    iObserver = aObserver;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesCommon.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESCOMMON_H
+#define PROFILERGENERICCLASSESCOMMON_H
+
+	#include <e32cmn.h>
+
+/*
+ *	
+ *	Class TProfilerSampleBufStruct definition
+ *
+ */
+
+
+class TProfilerSampleBufStruct
+{
+public:
+	TUint32 iSampleRemainder;
+	TUint8	iDataStart;
+};
+
+/*
+ *  
+ *  Class TBapBuf definition
+ *
+ */
+
+class TBapBuf
+{
+public:
+	TPtr8*		iDes;
+	TPtr8*		iBufDes;
+	TInt		iBufferSize;
+	TInt		iDataSize;
+	TUint8*		iBuffer;
+	TBapBuf*	iNext;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,422 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESKRN_H
+#define PROFILERGENERICCLASSESKRN_H
+
+	#include <piprofiler/ProfilerGenericClassesCommon.h>
+	#include <piprofiler/ProfilerTraces.h>
+
+	#include <e32cmn.h>
+
+	#define PROFILER_KERNEL_MODE
+
+#ifdef PROFILER_KERNEL_MODE
+class DProfilerSampleBuffer;
+
+class DProfilerSampleStream
+    {
+public:
+		DProfilerSampleStream();
+		~DProfilerSampleStream();
+
+		void InsertCurrentClient(DThread* aClient);
+		void AddSampleBuffer(TBapBuf* aBuffer,TRequestStatus* aStatus);
+		void ReleaseIfPending();
+
+		void AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId);
+		TInt EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId);
+
+		void PerformCopy(TUint8 aSamplerId,TUint8* aSrc,TPtr8* dst,TInt aOffset,TInt aAmount);
+
+private:
+		TBapBuf*			iCurrentBuffer;
+		TRequestStatus*		iPendingRequest;
+		DThread*			iClient;
+		TInt				iAddingSamples;
+    };
+
+class DProfilerSampleBuffer : public DBase
+    {
+		friend class DProfilerSampleStream;
+public:
+
+			enum ProfilerBufferStatus 
+			    {
+				BufferOk,
+				BufferCopyAsap,
+				BufferBeingCopied,
+				BufferFull,
+				BufferDataEnd
+			    };
+
+			DProfilerSampleBuffer(TUint8* aBuffer, TUint8* aDblBuffer, TUint32 aSize);
+			~DProfilerSampleBuffer();	
+			TInt	AddSample(TUint8* aSample, TUint32 aLength);
+			TUint32 GetBufferStatus();
+			void	ClearBuffer();
+			void	EndSampling();
+			void	DataCopied();
+
+			TUint32 iBufferStatus;
+private:
+			TUint32 iBytesWritten;
+			TUint32 iDblBytesWritten;
+			TUint32 iDblBytesRead;
+
+			TUint32 iBufferDataSize;
+			TUint32 iBufferRealSize;
+
+			TProfilerSampleBufStruct* iDblBufStruct;
+			TProfilerSampleBufStruct* iBufStruct;
+    };
+
+#endif
+
+
+ 
+/*
+ *	
+ *	Abstract class CProfilerSamplerBase definition
+ *	
+ */
+
+#ifdef PROFILER_KERNEL_MODE
+class DProfilerSamplerBase : public DBase
+    {
+public:
+	DProfilerSamplerBase();
+			virtual					~DProfilerSamplerBase();
+
+			virtual	TInt			Initialise() = 0;
+			virtual	void			Sample() = 0;
+			virtual TBool			PostSampleNeeded() = 0;
+			virtual TInt			PostSample() = 0;
+			virtual TInt			EndSampling() = 0;
+
+			virtual TInt			Reset(DProfilerSampleStream* aStream = 0, TUint32 aSyncOffset = 0) = 0;
+
+			virtual void			SetEnabledFlag(TBool aFlag) = 0;
+			virtual TBool			GetEnabledFlag() = 0;
+			virtual void			SetOutputCombination(TInt aSettings) = 0;
+			virtual void 			SetSamplingPeriod(TInt aSettings) = 0;
+			virtual void			SetAdditionalSettings(TInt aSettings) = 0;
+			virtual void			SetAdditionalSettings2(TInt aSettings) = 0;
+			virtual void			SetAdditionalSettings3(TInt aSettings) = 0;
+			virtual void			SetAdditionalSettings4(TInt aSettings) = 0;
+
+			TInt					iSamplerId;
+			TInt					iOutputCombination;
+			TBool					iEnabled;
+    };
+
+/*
+ *	
+ *	Template abstract class CProfilerGenericSampler definition
+ *	
+ */
+
+// size parameter given defines the explicit buffer size in bytes for this sampler
+template <int BufferSize> 
+class DProfilerGenericSampler : public DProfilerSamplerBase
+    {
+public:
+			DProfilerGenericSampler(TInt aSamplerId);
+			virtual					~DProfilerGenericSampler();
+
+			TInt					Initialise();
+			virtual	void			Sample() = 0;
+			TBool					PostSampleNeeded();
+			TInt					PostSample();
+			TInt					EndSampling();
+			virtual TInt			Reset(DProfilerSampleStream* aStream = 0, TUint32 aSyncOffset = 0);
+
+
+			void					SetEnabledFlag(TBool aFlag);
+			TBool					GetEnabledFlag();
+			void					SetOutputCombination(TInt aComb);
+			void 					SetSamplingPeriod(TInt aSettings);
+			void					SetAdditionalSettings(TInt aSettings);
+			void					SetAdditionalSettings2(TInt aSettings);
+			void					SetAdditionalSettings3(TInt aSettings);
+			void					SetAdditionalSettings4(TInt aSettings);
+
+			DProfilerSampleBuffer*	iSampleBuffer;
+			DProfilerSampleStream*	iStream;
+
+			// for right alignment
+			TUint8					iBuffer[BufferSize+4];
+			TUint8					iDblBuffer[BufferSize+4];
+			
+			TInt					iSamplingPeriod;
+			TInt					iAdditionalSettings;
+			TInt					iAdditionalSettings2;
+			TInt					iAdditionalSettings3;
+			TInt					iAdditionalSettings4;
+    };
+
+/*
+ *	
+ *	Template abstract class CProfilerGenericSampler implementation
+ *
+ */
+
+template <int BufferSize>
+DProfilerGenericSampler<BufferSize>::DProfilerGenericSampler(TInt aSamplerId)
+    {
+	iSamplerId = aSamplerId;
+	iEnabled = false;
+	iSampleBuffer = 0;
+	iAdditionalSettings = 0;
+	iAdditionalSettings2 = 0;
+    iAdditionalSettings3 = 0;
+    iAdditionalSettings4 = 0;
+	iStream = 0;
+	Initialise();
+    }
+
+template <int BufferSize> 
+DProfilerGenericSampler<BufferSize>::~DProfilerGenericSampler()
+    {
+	LOGSTRING2("CProfilerGenericSampler<%d>::CProfilerGenericSampler",BufferSize);	
+	
+	if(iSampleBuffer != 0)
+		delete iSampleBuffer;
+
+    }
+ 
+template <int BufferSize> 
+TInt DProfilerGenericSampler<BufferSize>::Initialise()
+    {
+	LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - chunk option",BufferSize);
+
+	// stream is not used in chunk mode
+	iStream = 0;
+
+	// create the sample buffer object with the buffers
+	if(iSampleBuffer == 0)
+	    {
+	    iSampleBuffer = new DProfilerSampleBuffer(iBuffer,iDblBuffer,BufferSize);
+        }
+	else
+	   {
+		LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - ERROR 1",BufferSize);
+        }
+
+	return KErrNone;
+    }
+
+
+
+template <int BufferSize> 
+TInt DProfilerGenericSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+    {
+	LOGSTRING4("CProfilerGenericSampler<%d>::Reset %d, sync offset %d",BufferSize,aStream,aSyncOffset);
+	// reset the sample buffer and resolve the chunk again
+
+	// CURRENT VERSION SUPPORTS ONLY STREAM MODE!
+	LOGSTRING2("CProfilerGenericSampler<%d>::Reset - stream option",BufferSize);
+
+	// initialise the sampler with the stream option
+	iStream = aStream;
+
+	// clear the sample buffer
+	if(iSampleBuffer != 0)
+	    {
+	    iSampleBuffer->ClearBuffer();
+        }
+	else
+	    {
+		LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - ERROR no buffer",BufferSize);
+        }
+
+	return KErrNone;
+
+    }
+
+template <int BufferSize> 
+TBool DProfilerGenericSampler<BufferSize>::PostSampleNeeded()
+    {
+	LOGSTRING4("CProfilerGenericSampler<%d>::PostSampleNeeded - ID %d, state %d",iSamplerId,BufferSize,iSampleBuffer->GetBufferStatus());
+
+	TUint32 status = iSampleBuffer->iBufferStatus;
+
+	if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull)
+	    {
+		return true;
+        }
+	
+	return false;
+    }
+
+
+template <int BufferSize> 
+TInt DProfilerGenericSampler<BufferSize>::PostSample()
+    {
+	LOGSTRING4("CProfilerGenericSampler<%d>::PostSample - ID %d, state %d",iSamplerId,BufferSize,iSampleBuffer->GetBufferStatus());
+
+	TUint32 status = iSampleBuffer->iBufferStatus;
+
+	if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull)
+	    {
+        // write data to the stream
+	    iStream->AddSamples(*iSampleBuffer,iSamplerId);
+		}
+	
+	return KErrNone;
+    }
+
+template <int BufferSize>
+TInt DProfilerGenericSampler<BufferSize>::EndSampling()
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::EndSampling, ID %d",BufferSize,iSamplerId);
+
+    // only if write to stream option is selected
+    if(iStream->EndSampling(*iSampleBuffer,iSamplerId) == 0)
+        {
+        return KErrNone;
+        }
+    else 
+        {
+        // there is still data to copy
+        return KErrNotReady;
+        }
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetEnabledFlag(TBool aFlag)
+    {
+	LOGSTRING2("CProfilerGenericSampler<%d>::SetEnabledFlag",BufferSize);
+	iEnabled = aFlag;
+    }
+
+template <int BufferSize>
+TBool DProfilerGenericSampler<BufferSize>::GetEnabledFlag()
+    {
+	LOGSTRING2("CProfilerGenericSampler<%d>::GetEnabledFlag",BufferSize);
+	return iEnabled;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetOutputCombination(TInt aComb)
+    {
+	LOGSTRING2("CProfilerGenericSampler<%d>::SetOutputCombination",BufferSize);
+	iOutputCombination = aComb;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings(TInt aSettings)
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings to 0x%x",BufferSize,aSettings);
+	iAdditionalSettings = aSettings;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings2(TInt aSettings)
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings2 to 0x%x",BufferSize,aSettings);
+	iAdditionalSettings2 = aSettings;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings3(TInt aSettings)
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings3 to 0x%x",BufferSize,aSettings);
+	iAdditionalSettings3 = aSettings;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings4(TInt aSettings)
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings4 to 0x%x",BufferSize,aSettings);
+	iAdditionalSettings4 = aSettings;
+    }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetSamplingPeriod(TInt aSettings)
+    {
+	LOGSTRING3("CProfilerGenericSampler<%d>::SetSamplingPeriod to 0x%x",BufferSize,aSettings);
+	iSamplingPeriod = aSettings;
+    }
+
+/*
+ *	
+ *	Just a test class that is derived from CProfilerGenericSampler
+ *	
+ */
+
+template <int BufferSize>
+class DProfilerExampleSampler : public DProfilerGenericSampler<BufferSize>
+    {
+public:
+	TUint32 iSampleNumber;
+
+	DProfilerExampleSampler(TInt aSamplerId);
+	~DProfilerExampleSampler();
+
+	void Sample();
+	void Sample(TInt aCount, TInt aLastPc);
+    };
+
+
+/*
+ *	
+ *	Just a test class that is derived from CProfilerGenericSampler
+ *	
+ */
+
+template <int BufferSize>
+DProfilerExampleSampler<BufferSize>::DProfilerExampleSampler(TInt aSamplerId) :
+	DProfilerGenericSampler<BufferSize>(aSamplerId) 
+    {
+    iSampleNumber = 0;
+	LOGSTRING2("CProfilerExampleSampler<%d>::CProfilerExampleSampler",BufferSize);	
+    }
+
+template <int BufferSize>
+void DProfilerExampleSampler<BufferSize>::Sample()
+    {
+	LOGSTRING2("CProfilerExampleSampler<%d>::Sample",BufferSize);
+	TBuf8<20>* testiBuf = new TBuf8<20>;
+
+	testiBuf->AppendNum((TInt)iSampleNumber);
+	iSampleNumber++;
+
+	this->iSampleBuffer->AddSample((TUint8*)testiBuf->Ptr(),testiBuf->Length());
+	delete testiBuf;
+	return;
+    }
+
+template <int BufferSize>
+void DProfilerExampleSampler<BufferSize>::Sample(TInt aCount, TInt aLastPc)
+    {
+	return;
+    }
+
+template <int BufferSize>
+DProfilerExampleSampler<BufferSize>::~DProfilerExampleSampler()
+    {
+	LOGSTRING2("CProfilerExampleSampler<%d>::~CProfilerExampleSampler",BufferSize);		
+    }
+
+#include <piprofiler/ProfilerGenericClassesKrn.inl>
+
+#endif
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,530 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+
+/*
+ *	
+ *	Class CProfilerSamplerBase implementation
+ *
+ */
+
+inline DProfilerSamplerBase::DProfilerSamplerBase()
+    {
+	
+    }
+
+inline DProfilerSamplerBase::~DProfilerSamplerBase()
+    {
+	
+    }
+
+/*
+ *	
+ *	Class CProfilerSampleBuffer implementation
+ *
+ */
+
+inline DProfilerSampleBuffer::DProfilerSampleBuffer(TUint8* aBuffer, 
+											TUint8* aDblBuffer, 
+											TUint32 aBufferSize )
+    {
+	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer AtFirst: b:0x%x db:0x%x",aBuffer,aDblBuffer);
+
+	// make sure the alignment is right
+	if((((TUint32)aBuffer) %4) != 0)
+	    aBuffer += (4-(((TUint32)aBuffer)%4));
+	if((((TUint32)aDblBuffer) %4) != 0)
+	    aDblBuffer += (4-(((TUint32)aDblBuffer)%4));
+
+	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer b:0x%x db:0x%x",aBuffer,aDblBuffer);
+
+	iBufStruct = (TProfilerSampleBufStruct*)aBuffer;
+	iDblBufStruct = (TProfilerSampleBufStruct*)aDblBuffer;
+
+	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer bufStruct rem:0x%x dbuStruct rem:0x%x",
+						&iBufStruct->iSampleRemainder,&iDblBufStruct->iSampleRemainder);
+
+	iBufferDataSize = aBufferSize-4;
+	iBufferRealSize = aBufferSize;
+
+	ClearBuffer();
+    }
+
+inline DProfilerSampleBuffer::~DProfilerSampleBuffer()
+    {
+	
+    }
+
+inline TInt DProfilerSampleBuffer::AddSample(TUint8* aSample, TUint32 aLength)
+    {
+	TUint32 bytesTotal;
+
+	// check whether the buffer status is
+	switch (iBufferStatus)
+	    {
+		case DProfilerSampleBuffer::BufferOk:
+			// add the data normally to the buffer
+			bytesTotal = iBytesWritten+aLength;
+
+			if(bytesTotal < iBufferDataSize)
+			    {
+				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+				iBytesWritten+=aLength;
+				return 0;
+			    }
+			else
+			    {
+
+				// the sample does not fit to the buffer
+				// first copy as much data as we can fit to the first buffer
+				TUint32 fitsToBuffer = iBufferDataSize-iBytesWritten;
+				TUint32 remaining = aLength-fitsToBuffer;
+
+				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,fitsToBuffer);
+				iBytesWritten = iBufferDataSize;
+
+				// ->switch to the double buffer
+				iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
+				
+				TProfilerSampleBufStruct* tmpPtr = iBufStruct;
+				iBufStruct = iDblBufStruct;
+				iDblBufStruct = tmpPtr;
+				
+				iDblBytesWritten = iBytesWritten;
+
+				// and this is the remainder of a sample
+				// that will be copied to the new buffer
+				// just in a while
+				iBufStruct->iSampleRemainder = remaining;
+				
+				// now that the buffers have been switched
+				// add the rest of the sample to the buffer
+				aSample+=fitsToBuffer;
+
+				// there should be room - in case the single sample
+				// is smaller than the whole buffer! so we don't
+				// bother to check
+
+				memcpy((&(iBufStruct->iDataStart)),aSample,remaining);
+				iBytesWritten = remaining;
+				return 0;
+			    }
+
+		case DProfilerSampleBuffer::BufferCopyAsap:
+
+			// no difference to the BufferOk case
+			// unless the double buffer gets filled
+			// before the data has been copied
+			// add the data normally to the buffer
+			bytesTotal = iBytesWritten+aLength;
+
+			if(bytesTotal < iBufferDataSize)
+			    {
+				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+				iBytesWritten+=aLength;
+				return 0;
+			    }
+			else
+			    {
+				// the double buffer is now also full - there is no
+				// place to put the data -> we have to waste it!
+				// this is an indication of a too small buffer size
+				iBufferStatus = DProfilerSampleBuffer::BufferFull;
+				LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full1!!");
+				return -1;
+			    }
+
+		case DProfilerSampleBuffer::BufferBeingCopied:
+
+			// no difference to the BufferCopyAsap case
+			bytesTotal = iBytesWritten+aLength;
+
+			if(bytesTotal < iBufferDataSize)
+			    {
+				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+				iBytesWritten+=aLength;
+				return 0;
+			    }
+			else
+			    {
+				// the double buffer is now also full - there is no
+				// place to put the data -> we have to waste it!
+				// this is an indication of a too small buffer size
+                LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full2!!");
+				
+				// don't change the state to CProfilerSampleBuffer::BufferFull, since it is
+				// already being copied
+				return -1;
+			    }
+
+		case DProfilerSampleBuffer::BufferFull:
+			// the buffer is still full, there is noting we can do
+			// about it -> return
+		    LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full3!!");
+			return -1;
+
+		default:
+		    LOGSTRING("DProfilerSampleBuffer::AddSample - wrong switch!!");
+			return -1;
+	    }
+    }
+
+inline void DProfilerSampleBuffer::EndSampling()
+    {
+    LOGSTRING("DProfilerSampleBuffer::EndSampling");
+	// this will switch to the dbl buffer even though
+	// the buffer is not full, so that data can be copied
+
+	// during this operation, no other buffer
+	// operations are allowed
+
+	// ensure that the normal buffer is in use and that the
+	// buffer is in normal state ( this procedure is performed only once )
+	if(iBufferStatus == DProfilerSampleBuffer::BufferOk)
+	    {
+		// ->switch to the double buffer
+        LOGSTRING("DProfilerSampleBuffer::EndSampling - switching to double buffer");
+		iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
+		
+		TProfilerSampleBufStruct* tmpPtr = iBufStruct;
+		iBufStruct = iDblBufStruct;
+		iDblBufStruct = tmpPtr;
+				
+		iDblBytesWritten = iBytesWritten;
+		
+		// there is no new sample so the remainder is
+		// zero, (this shouldn't be used anyway)
+		iBufStruct->iSampleRemainder = 0;
+	    }
+    }
+
+inline TUint32 DProfilerSampleBuffer::GetBufferStatus()
+    {
+	return iBufferStatus;
+    }
+
+inline void DProfilerSampleBuffer::ClearBuffer()
+    {
+	LOGSTRING2("CProfilerSampleBuffer::ClearBuffer - %d",iBufferDataSize);
+
+	// the buffers are of same size
+	TUint8* ptr1 = (TUint8*)&(iBufStruct->iDataStart);
+	TUint8* ptr2 = (TUint8*)&(iDblBufStruct->iDataStart);
+
+	for(TUint32 i=0;i<iBufferDataSize;i++)
+	    {
+		ptr1[i] = 0;
+		ptr2[i] = 0;
+	    }
+
+
+	iBufStruct->iSampleRemainder = 0;
+	iDblBufStruct->iSampleRemainder = 0;
+
+	// written the dblBufStruct
+	iBytesWritten = 0;
+	iDblBytesWritten = 0;
+	iDblBytesRead = 0;
+
+	iBufferStatus = DProfilerSampleBuffer::BufferOk;
+    }
+
+inline void DProfilerSampleBuffer::DataCopied()
+    {
+	iDblBytesRead = 0;
+	iDblBytesWritten = 0;
+	iBufferStatus = DProfilerSampleBuffer::BufferOk;
+    }
+
+/*
+ *
+ *	Class DProfilerSampleStream implementation
+ *
+ */
+
+inline DProfilerSampleStream::DProfilerSampleStream()
+    {
+	LOGSTRING("DProfilerSampleStream::DProfilerSampleStream");
+
+	iCurrentBuffer = 0;
+	iPendingRequest = 0;
+	iAddingSamples = 0;
+	iClient = 0;
+    }
+
+inline DProfilerSampleStream::~DProfilerSampleStream()
+    {
+	LOGSTRING("DProfilerSampleStream::~DProfilerSampleStream");	
+    }
+
+inline void DProfilerSampleStream::InsertCurrentClient(DThread* aClient)
+    {
+	iClient = aClient;
+	LOGSTRING2("DProfilerSampleStream::InsertCurrentClient - iClient is 0x%x",iClient);
+    }
+
+
+inline void DProfilerSampleStream::AddSampleBuffer(TBapBuf* aBuffer,TRequestStatus* aStatus)
+    {
+	if(iCurrentBuffer != 0 || iPendingRequest != 0)
+	    {
+		LOGSTRING("DProfilerSampleStream::AddSampleBuffer - ERROR 1");
+		return;
+	    }
+
+	LOGSTRING3("DProfilerSampleStream::AddSampleBuffer - OK 0x%x,0x%x",aBuffer,aStatus);
+	iCurrentBuffer = aBuffer;
+	iPendingRequest = aStatus;
+	
+	LOGSTRING2("DProfilerSampleStream::AddSampleBuffer - Current Client is 0x%x",iClient);	
+    }
+
+
+inline void DProfilerSampleStream::ReleaseIfPending()
+    {
+    LOGSTRING("DProfilerSampleStream::ReleaseIfPending - entry");
+
+	if(iCurrentBuffer != 0 && iPendingRequest != 0 && iClient != 0)
+	    {
+		LOGSTRING("DProfilerSampleStream::ReleaseIfPending - release buffer");
+
+		LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
+		Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
+		
+		iPendingRequest = 0;
+		iCurrentBuffer = 0;
+	    }
+
+	LOGSTRING("DProfilerSampleStream::ReleaseIfPending - exit");
+    }
+
+inline void DProfilerSampleStream::AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId)
+    {
+	LOGSTRING3("DProfilerSampleStream::AddSamples - entry ID: %d, currentbuffer: 0x%x", aSamplerId,iCurrentBuffer);
+	if(iCurrentBuffer != 0)
+	    {
+		// the following will perform simple mutual exclusion
+		iAddingSamples++;
+		if(iAddingSamples > 1) 
+		    {
+			// there is someone else adding samples to the buffer
+            LOGSTRING("DProfilerSampleStream::AddSamples - mutex in use");
+			iAddingSamples--;
+			return;
+		    }
+
+		LOGSTRING("DProfilerSampleStream::AddSamples - reading TBapBuf");
+		
+		// use a copy of the client TBapBuf structure during processing
+		TBapBuf realBuf;
+		TPtr8 ptr((TUint8*)&realBuf,(TInt)sizeof(TBapBuf));
+	
+		Kern::ThreadRawRead(iClient,(TAny*)(iCurrentBuffer),(TAny*)&realBuf,sizeof(TBapBuf));
+
+		ptr.SetLength(sizeof(TBapBuf));
+
+		LOGSTRING4("DProfilerSampleStream::AddSamples - read %d bytes from 0x%x of thread 0x%x",ptr.Size(),iCurrentBuffer,iClient);
+
+		LOGSTRING5("DProfilerSampleStream::AddSamples - current buffer 0x%x -> b:0x%x s:%d d:%d",
+			&realBuf,
+			realBuf.iBuffer,
+			realBuf.iBufferSize,
+			realBuf.iDataSize);
+
+		// get the address of the source buffer data
+		TUint8* src = (TUint8*)&(aBuffer.iDblBufStruct->iDataStart);
+		src += aBuffer.iDblBytesRead;
+
+		// the amount of data to copy is the 4 header bytes +
+		// the remaining data in the buffer
+		TInt amount = aBuffer.iDblBytesWritten-aBuffer.iDblBytesRead;
+
+		TUint8* dst = realBuf.iBuffer;
+
+		LOGSTRING4("DProfilerSampleStream::AddSamples - s:0x%x d:0x%x a:%d",src,dst,amount);
+
+		if(realBuf.iDataSize == 0)
+		    {
+			LOGSTRING("DProfilerSampleStream::AddSamples - case 1");
+
+			// the buffer is empty
+			if(realBuf.iBufferSize >= (amount+4))
+			    {
+				LOGSTRING("DProfilerSampleStream::AddSamples - case 1.1");
+
+				// the source buffer is smaller or of equal size than the amount of output data
+				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
+				realBuf.iDataSize += amount+4;
+				// the rest of the source buffer was copied at once, so signal the buffer
+				aBuffer.DataCopied();
+			    }
+			else
+			    {
+				LOGSTRING("DProfilerSampleStream::AddSamples - case 1.2");
+
+				// only a part of the source buffer will fit to the client side buffer
+				amount = realBuf.iBufferSize-4;
+				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
+				realBuf.iDataSize += amount+4;
+				// add the amount of bytes read to the source buffer
+				aBuffer.iDblBytesRead+=amount;
+			    }
+		    }
+		else
+		    {
+			LOGSTRING("DProfilerSampleStream::AddSamples - case 2");
+
+			// there is data in the client buffer
+			dst += realBuf.iDataSize;
+			TInt remainingSpace = realBuf.iBufferSize-realBuf.iDataSize;
+
+			if( remainingSpace >= (amount+4) )
+			    {
+				LOGSTRING("DProfilerSampleStream::AddSamples - case 2.1");
+
+				// the source buffer is smaller or of equal size than the amount of output data
+				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
+				realBuf.iDataSize += (amount+4);
+				// the rest of the source buffer was copied at once, so signal the buffer
+				aBuffer.DataCopied();
+			    }
+			else
+			    {
+				LOGSTRING("DProfilerSampleStream::AddSamples - case 2.2");
+
+				// only a part of the source buffer will fit to the client side buffer
+				if(remainingSpace >= 12)
+				    {
+					LOGSTRING("DProfilerSampleStream::AddSamples - case 2.3");
+
+					amount = remainingSpace-4;
+					// there are at least 8 bytes left for data, write it
+					PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
+					realBuf.iDataSize += (amount+4);
+					// add the amount of bytes read to the source buffer
+					aBuffer.iDblBytesRead+=amount;				
+				    }
+			    }
+		    }
+	
+		// copy the data in the modified TBapBuf structure back to the client
+		LOGSTRING("DProfilerSampleStream::AddSamples - writing TBapBuf");
+
+		Kern::ThreadDesWrite(iClient,(TAny*)(realBuf.iDes),ptr,0,KChunkShiftBy0,iClient);
+
+		// if the client side buffer is full or nearly full, signal the client
+		LOGSTRING("DProfilerSampleStream::AddSamples - data copied");
+
+		if(realBuf.iBufferSize-realBuf.iDataSize < 12)
+		    {
+			LOGSTRING("DProfilerSampleStream::AddSamples - release buffer");
+			
+			LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
+
+			Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
+
+			iPendingRequest = 0;
+			iCurrentBuffer = 0;
+			//iClient = 0;
+		    }
+
+		// free the lock
+		iAddingSamples--;
+	    }
+	LOGSTRING("DProfilerSampleStream::AddSamples - exit");
+    }
+
+
+
+inline TInt DProfilerSampleStream::EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId)
+    {
+    LOGSTRING2("DProfilerSampleStream::EndSampling, sampler ID: %d",aSamplerId);
+
+	// switch the buffer to double buffer
+	// even though it would not be full yet
+	// the switch is done only once / end sampling procedure
+	// (Only with BufferOk status)
+	aBuffer.EndSampling();
+	
+	LOGSTRING2("DProfilerSampleStream::EndSampling, iClient: 0x%x",iClient);
+	
+	if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferDataEnd)
+	    {
+		// add these final samples to the client buffer
+		AddSamples(aBuffer,aSamplerId);
+		
+		// if all data was copied to the buffer, the buffer status is now BufferOk
+
+		if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferOk)
+		    {
+            LOGSTRING("DProfilerSampleStream::EndSampling - more data to copy");
+			// there is still more data to copy, the pending request should have been
+			// completed in AddSamples(), because the client buffer got filled 
+			return 1;
+		    }
+		else
+		    {
+			// buffer status was changed to BufferOk in AddSamples() - 
+			// this means all data from it could be copied
+			// now we have to change the status of the buffer to BufferDataEnd, so
+			// we know that the particular buffer has no more data to copy
+            LOGSTRING("DProfilerSampleStream::EndSampling - switch to BufferDataEnd");
+			aBuffer.iBufferStatus = DProfilerSampleBuffer::BufferDataEnd;
+		    }
+	    }
+
+	// the buffer was completely emptied to the client buffer, or there was no
+	// data to copy to the client side
+	LOGSTRING("DProfilerSampleStream::EndSampling - no more data to copy");
+
+	return 0;
+    }
+
+inline void DProfilerSampleStream::PerformCopy(TUint8 aSamplerId,TUint8* aSrc,TPtr8* aDst,TInt aOffset,TInt aAmount)
+    {
+	LOGSTRING2("DProfilerSampleStream::PerformCopy for sampler ID: %d",aSamplerId);	
+	LOGSTRING5("DProfilerSampleStream::PerformCopy - 0x%x -> 0x%x - %d - offset: %d",aSrc, aDst, aAmount, aOffset);	
+	TUint32 header;
+	header = aAmount & 0x00ffffff;
+	header += (aSamplerId << 24);
+	TPtr8 ptr((TUint8*)&header,4);
+	ptr.SetLength(4);
+
+	LOGSTRING2("DProfilerSampleStream::PerformCopy - start header copy HDR = 0x%x",header);	
+
+	// write the header
+	Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
+
+	LOGSTRING2("DProfilerSampleStream::PerformCopy - copied header %d bytes",ptr.Size());	
+	aOffset+=4;
+
+	LOGSTRING("DProfilerSampleStream::PerformCopy - start copy");	
+	// write the data
+	ptr.Set(aSrc,aAmount,aAmount);
+	ptr.SetLength(aAmount);
+	
+	Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
+
+
+	LOGSTRING2("DProfilerSampleStream::PerformCopy - copied data %d bytes",ptr.Size());	
+
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESUSR_H
+#define PROFILERGENERICCLASSESUSR_H
+
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerGenericClassesCommon.h>
+#include <piprofiler/PluginSampler.h>
+#include <piprofiler/WriterPluginInterface.h>
+
+#include <e32cmn.h>
+#include <e32std.h>
+#include <f32file.h>
+
+
+/*
+ *	
+ *	Class MProfilerBufferHandlerObserver definition
+ *	
+ */
+class MProfilerBufferHandlerObserver
+	{
+public:
+	virtual TBapBuf* GetNextFreeBuffer() = 0;
+	virtual void AddToFilledBuffers(TBapBuf* aFilledBuffer) = 0;
+	};
+
+/*
+ *	
+ *	Class CProfilerBufferHandler definition
+ *	
+ */
+// forward declarations
+class CProfilerSampleStream;
+
+class CProfilerBufferHandler : public CActive
+	{
+public:
+	static CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler);
+	CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler);
+	~CProfilerBufferHandler();
+	
+	void 		ConstructL();
+	
+	// for plugins to start receiving trace data
+	void		StartReceivingData();
+private:
+	void		RunL();
+	TInt        RunError(TInt aError);
+	void		DoCancel();
+	void        HandleEndOfStream();
+public:
+	TInt					iFinished;
+private:
+	RPluginSampler&			iSampler;
+	TBapBuf*				iBufferInProcess;
+	TBool					iEndOfStreamDetected;
+	
+	CProfilerSampleStream&     iObserver;
+	};
+
+/*
+ *	
+ *	Class CProfilerSampleStream definition
+ *	
+ */
+class CWriterPluginInterface;
+
+class CProfilerSampleStream : public CBase, MProfilerBufferHandlerObserver
+{
+public:
+	static CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize);
+	~CProfilerSampleStream();
+
+	void 		ConstructL();
+
+	void 		Finalise();
+	void 		EmptyBuffers();
+	inline void		AddToFreeBuffers(TBapBuf* freeBuffer);
+	void        SetWriter(CWriterPluginInterface& aWriter);
+	
+	// from MProfilerBufferHandlerObserver
+	TBapBuf* 	GetNextFreeBuffer();
+	void        AddToFilledBuffers(TBapBuf* aFilledBuffer);
+	inline TBapBuf*    GetNextFilledBuffer();
+	void        ResetBuffers();
+	void        InitialiseBuffers();
+	inline void        NotifyWriter();
+private:
+	CProfilerSampleStream(TInt aBufSize);
+	
+	
+public:
+    TInt					iFinished;
+    CWriterPluginInterface* iWriter;
+private:
+    TInt					iBufferSize;
+    TBapBuf*				iFreeBuffers;
+    TBapBuf*                iFilledBuffers;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.inl>
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,498 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <f32file.h>
+#include <e32svr.h>
+
+#include <piprofiler/ProfilerTraces.h>
+
+// constants
+const TInt KInitialFreeBufferAmount = 4;
+
+/*
+ *
+ *	Class CProfilerBufferHandler implementation
+ *
+ */
+inline CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+	{
+	LOGTEXT(_L("CProfilerBufferHandler::NewL - entry"));
+	CProfilerBufferHandler* self = new(ELeave) CProfilerBufferHandler(aStream, aSampler);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;   
+	}
+
+inline CProfilerBufferHandler::CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+    : CActive(EPriorityStandard),
+    iSampler(aSampler),
+    iObserver(aStream)
+    {
+    }
+
+inline CProfilerBufferHandler::~CProfilerBufferHandler()
+	{
+	LOGTEXT(_L("CProfilerBufferHandler::~CProfilerBufferHandler() - entry"));
+	}
+
+inline void CProfilerBufferHandler::ConstructL()
+	{
+	LOGTEXT(_L("CProfilerBufferHandler::ConstructL - entry"));
+	iBufferInProcess = 0;
+	iEndOfStreamDetected = false;
+
+	iFinished = 0;
+	// add the buffer handler to the active scheduler
+	CActiveScheduler::Add(this);
+	}
+
+inline void CProfilerBufferHandler::StartReceivingData()
+	{
+	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - entry"));
+
+	iEndOfStreamDetected = false;
+	// this method initiates receiving data from the sampler
+	iBufferInProcess = iObserver.GetNextFreeBuffer();
+
+	LOGSTRING5("CProfilerBufferHandler::StartReceivingData - 0x%x -> b:0x%x s:%d d:%d",
+					iBufferInProcess,
+					iBufferInProcess->iBuffer,
+					iBufferInProcess->iBufferSize,
+					iBufferInProcess->iDataSize);
+
+	iSampler.FillThisStreamBuffer(iBufferInProcess,iStatus);
+
+	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - SetActive"));
+	SetActive();
+
+	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - exit"));
+	}
+
+inline TInt CProfilerBufferHandler::RunError(TInt aError)
+    {
+    // handle the error case by stopping the trace
+    HandleEndOfStream();
+    return aError;
+    }
+
+inline void CProfilerBufferHandler::HandleEndOfStream()
+    {
+    LOGTEXT(_L("CProfilerBufferHandler::RunError - entry"));
+    // Cancel has been called, the stream should be about to end now,
+    // we will wait for the rest of the buffers to be filled synchronously
+    // the end of the stream will be indicated through an empty buffer
+    // at first, complete the ongoing request
+    if(iStatus == KRequestPending && iBufferInProcess != 0)
+        {
+        LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1"));
+
+        // wait for the buffer to be filled synchronously
+        User::WaitForRequest(iStatus);
+        
+        // add the received buffer to the list of filled buffers
+        iObserver.AddToFilledBuffers(iBufferInProcess);
+        // continue writing to output
+        iObserver.NotifyWriter();
+        
+        if(iBufferInProcess->iDataSize == 0)
+            {
+            // a buffer with size 0 was received
+            LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1.1"));
+            iEndOfStreamDetected = true;
+            }
+
+        // there will be no more asynchronous requests
+        iBufferInProcess = 0;
+        }
+    else if (iBufferInProcess != 0)
+        {
+        LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2"));
+
+        // add the buffer into filled, i.e. ready-to-write buffers
+        iObserver.AddToFilledBuffers(iBufferInProcess);
+        iObserver.NotifyWriter();
+        
+        if(iBufferInProcess->iDataSize == 0)
+            {
+            // a buffer with size 0 was received
+            LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2.1"));
+            iEndOfStreamDetected = true;
+            }       
+        // there will be no more asynchronous requests
+        iBufferInProcess = 0;   
+        }
+
+    // then, continue until end of stream has been reached
+    while(iEndOfStreamDetected == false)
+        {
+        // the end of stream has not yet been detected, so get more
+        // buffers from the sampler, until we get an empty one
+
+        if(iStatus == KRequestPending)
+            {
+            LOGTEXT(_L("CProfilerBufferHandler::DoCancel - ERROR 1"));
+            }
+
+        LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3"));
+
+        TBapBuf* nextFree = iObserver.GetNextFreeBuffer();  
+        iSampler.FillThisStreamBuffer(nextFree,iStatus);
+        // wait for the buffer to be filled synchronously
+        User::WaitForRequest(iStatus);
+        
+        // call the writer plugin to write data to output
+        iObserver.AddToFilledBuffers(nextFree);
+        iObserver.NotifyWriter();
+        
+        // check if end-of-data message (i.e. data size is 0 sized) received
+        if(nextFree->iDataSize == 0)
+            {
+            LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3.1"));
+            // a buffer with size 0 was received
+            iEndOfStreamDetected = true;
+            nextFree = 0;
+            }
+        }   
+    }
+
+inline void CProfilerBufferHandler::RunL()
+	{
+	LOGTEXT(_L("CProfilerBufferHandler::RunL - entry"));
+
+	// is called by the active scheduler
+	// when a buffer has been received
+
+	// buffer with dataSize 0 is returned when the sampling ends
+	if(iBufferInProcess->iDataSize != 0)
+	    {
+	    LOGTEXT(_L("CProfilerBufferHandler::RunL - buffer received"));
+
+		TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
+		
+		LOGSTRING5("CProfilerBufferHandler::RunL - 0x%x -> b:0x%x s:%d d:%d",
+					nextFree,
+					nextFree->iBuffer,
+					nextFree->iBufferSize,
+					nextFree->iDataSize);
+
+		iSampler.FillThisStreamBuffer(nextFree,iStatus);
+
+		LOGTEXT(_L("CProfilerBufferHandler::RunL - issued new sample command"));
+
+		// add the received buffer to the list of filled buffers
+		iObserver.AddToFilledBuffers(iBufferInProcess);
+		iObserver.NotifyWriter();
+
+        // the empty buffer is now the one being processed
+        iBufferInProcess = nextFree;
+        
+        LOGTEXT(_L("CProfilerBufferHandler::RunL - SetActive"));
+        SetActive();        
+		}
+	else
+		{
+		LOGTEXT(_L("CProfilerBufferHandler::RunL - end of stream detected"));
+		iEndOfStreamDetected = true;
+		
+		// add the empty buffer to the writer so that it will also get the information
+		// about the finished stream
+		iObserver.AddToFilledBuffers(iBufferInProcess);
+		iObserver.NotifyWriter();
+
+		iBufferInProcess = 0;
+		Cancel();
+
+		}
+	LOGTEXT(_L("CProfilerBufferHandler::RunL - exit"));
+	}
+
+inline void CProfilerBufferHandler::DoCancel()
+    {
+    LOGTEXT(_L("CProfilerBufferHandler::DoCancel - entry"));
+    HandleEndOfStream();
+    LOGTEXT(_L("CProfilerBufferHandler::DoCancel - exit"));
+    }
+
+
+/*
+ *
+ *	Class CProfilerSampleStream implementation
+ *
+ *  - used by Plugin
+ **/
+
+inline CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize)
+	{
+	LOGTEXT(_L("CProfilerSampleStream::NewL - entry"));
+	CProfilerSampleStream* self = new(ELeave) CProfilerSampleStream(aBufSize);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;   
+	}
+
+inline CProfilerSampleStream::CProfilerSampleStream(TInt aBufSize) : 
+    iBufferSize(aBufSize)
+	{
+	LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - entry"));
+	
+	iFilledBuffers = 0;
+    iFreeBuffers = 0;
+    iFinished = 0;
+    
+	LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - exit"));	
+	}
+
+inline CProfilerSampleStream::~CProfilerSampleStream()
+	{
+	LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - entry"));
+
+	// empty all buffers
+	EmptyBuffers();
+	    
+	LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - exit"));
+	}
+
+inline void CProfilerSampleStream::ConstructL()
+	{
+
+	}
+
+inline void CProfilerSampleStream::SetWriter(CWriterPluginInterface& aWriter)
+    {
+    // set writer plugin
+    iWriter = &aWriter;
+    }
+
+inline void CProfilerSampleStream::Finalise()
+	{
+	LOGTEXT(_L("CProfilerSampleStream::Finalise - entry"));
+	}
+
+inline void CProfilerSampleStream::ResetBuffers()
+    {
+
+    // empty buffers
+    EmptyBuffers();
+
+    // re-initialise buffers
+    InitialiseBuffers();
+    }
+
+inline void CProfilerSampleStream::InitialiseBuffers()
+    {
+    // re-initialize member variables
+    iFilledBuffers = 0;
+    iFreeBuffers = 0;
+    iFinished = 0;
+    
+    // create three(orig. two) new TBapBuf objects and add them to the
+    // list of free buffers
+    for(TInt i(0);i<KInitialFreeBufferAmount;i++)
+        {
+        // alloc new buffer
+        TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+        newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+
+        // initialize the new buffer
+        newBuf->iBufferSize = iBufferSize;
+        newBuf->iDataSize = 0;
+        newBuf->iNext = 0;
+        newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+        newBuf->iDes->SetLength(sizeof(TBapBuf));
+        newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+        newBuf->iBufDes->SetLength(iBufferSize);
+        AddToFreeBuffers(newBuf);
+        }
+    }
+
+inline void CProfilerSampleStream::EmptyBuffers()
+    {
+	LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - entry"));
+
+	// delete all free buffers
+	while(iFreeBuffers != 0)
+	    {
+		LOGSTRING2("CProfilerSampleStream::EmptyBuffers - deleting 0x%x",iFreeBuffers);
+
+		// store the next buffer in the list
+		TBapBuf* nextFree = iFreeBuffers->iNext;
+		// delete the first one in the list
+		delete iFreeBuffers->iBufDes;
+		delete iFreeBuffers->iDes;
+		delete iFreeBuffers->iBuffer;
+		delete iFreeBuffers;
+		// set the list start to the next buffer
+		iFreeBuffers = nextFree;
+	    }
+	iFreeBuffers = 0;
+	LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - exit"));
+    }
+
+inline TBapBuf* CProfilerSampleStream::GetNextFreeBuffer()
+    {
+    LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - entry"));
+
+	// get a new buffer from the free buffers list
+	TBapBuf* nextFree = iFreeBuffers;
+	
+	// check if we got a buffer or not
+	if(nextFree == 0)
+	    {
+		// if there are no free buffers,
+		// create a new one
+		LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - creating new buffer"));
+		TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+		if(newBuf != 0)
+		    {
+			newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+			if(newBuf->iBuffer != 0)
+			    {
+				newBuf->iBufferSize = iBufferSize;
+				newBuf->iDataSize = 0;
+				newBuf->iNext = 0;
+				newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+				newBuf->iDes->SetLength(sizeof(TBapBuf));
+				newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+				newBuf->iBufDes->SetLength(iBufferSize);
+				nextFree = newBuf;
+			    }
+			else
+			    {
+				LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (1)!!"));
+				return 0;
+			    }
+		    }
+		else
+		    {
+			LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (2)!!"));
+			delete newBuf;
+			return 0;
+		    }		
+	    }
+	else
+	    {
+		// set the list to point to next free buffer
+		iFreeBuffers = nextFree->iNext;
+	    }
+
+	LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - exit"));
+	return nextFree;
+    }
+
+inline void CProfilerSampleStream::AddToFilledBuffers(TBapBuf* aFilledBuffer)
+    {
+    LOGSTRING2("CProfilerSampleStream::AddToFilledBuffers - entry, size %d", aFilledBuffer->iDataSize);
+
+    // add this buffer to the list of filled buffers
+    if(iFilledBuffers == 0)
+        {
+        // the list is empty, so add the the beginning of the list
+        // there is no next buffer in the list at the moment
+        aFilledBuffer->iNext = 0;
+        iFilledBuffers = aFilledBuffer;
+        }
+    else
+        {
+        // there are buffers in the list, add this buffer to the beginning of the list
+        aFilledBuffer->iNext = iFilledBuffers;
+        iFilledBuffers = aFilledBuffer;
+        }
+    LOGTEXT(_L("CProfilerSampleStream::AddToFilledBuffers - exit"));
+    }
+
+TBapBuf* CProfilerSampleStream::GetNextFilledBuffer()
+    {
+    LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - entry"));
+
+    if(iFilledBuffers == 0)
+        {
+        // there are no filled buffers in the list
+        LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - no filled bufs"));
+        return 0;
+        }
+    else
+        {   
+        // get a buffer from the end of the list
+        TBapBuf* buf = iFilledBuffers;
+        TBapBuf* prev = 0;
+
+        if(buf->iNext == 0)
+            {
+            // this was the last (and only) buffer
+            iFilledBuffers = 0;
+            LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - last filled"));
+            return buf;
+            }
+        else
+            {
+            LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - searching last filled"));
+            while(buf->iNext != 0)
+                {
+                // there are two or more buffers in the list
+                // proceed until the end of the list is found
+                prev = buf;
+                buf = buf->iNext;
+                }
+            // now buf->next is 0, return buf and set the next
+            // element of prev to NULL
+            prev->iNext = 0;
+            LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - found last"));
+            return buf;
+            }
+        }
+    }
+
+inline void CProfilerSampleStream::AddToFreeBuffers(TBapBuf* aFreeBuffer)
+    {
+	LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - entry"));
+
+	// set data size of the buffer to 0
+	aFreeBuffer->iDataSize = 0;
+
+	// add this buffer to the list of free buffers
+	if(iFreeBuffers == 0)
+	    {
+		// this is the first buffer, so set the next to point to NULL
+	    aFreeBuffer->iNext = 0;
+	    }
+	else
+	    {
+		// otherwise set to point to the beginning of the list
+	    aFreeBuffer->iNext = iFreeBuffers;
+	    }
+
+	// set this buffer to be the first one in the list
+	iFreeBuffers = aFreeBuffer;
+
+	LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - exit"));
+    }
+
+void CProfilerSampleStream::NotifyWriter()
+    {
+    // notify writer plugin to write data from filled buffer list
+    LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - entry"));
+    iWriter->WriteData();
+    LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - exit"));
+    }
+
+// end of file
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerSession.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,417 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PROFILER_SESSION_H__
+#define __PROFILER_SESSION_H__
+
+#include <e32base.h>
+#include <e32svr.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+#include <piprofiler/ProfilerAttributes.h>
+
+_LIT(KProfilerName,"PIProfilerEngine");
+
+/**
+ * The RProfiler class provides a functional interface to the sampling profiler.
+ *
+ * The engine must already be running for this interface to work, this can be
+ * achieved by executing PIProfilerEngine.exe. The control methods are all static, and 
+ * require no other context.
+ */
+NONSHARABLE_CLASS( RProfiler ) : public RSessionBase
+	{
+public:
+	enum TCommand {	
+		// profiler controls
+		EStartSampling = 1,
+		EStartTimedSampling,
+		EStopSampling,
+//		ELoadSettings,
+		EExitProfiler,
+		EFinalise,
+		EAttachClient,
+		ERemoveClient,
+
+		// general attributes
+		EGetGeneralAttributes,
+		EGetSamplerAttributes,
+		EGetSamplerAttributeCount,
+		ESetGeneralAttributes,
+		ESetSamplerAttributes,
+		
+		// generic settings
+		ESetTraceFilePrefix, 
+		ESetTraceFileDrive,
+		EGetSamplerVersion,
+		EGetFileName,
+		EGetActiveWriter,
+		ERefreshProfilerStatus
+		};
+	
+	enum TSamplerState {
+		EIdle = 0, 
+		EInitializing, 
+		ERunning, 
+		EStopping, 
+		EStopped
+		};
+	
+	enum TProfilingMode
+	    {
+	    EProfilingModeNormal = 0,
+	    EProfilingModeTimed
+	    };
+public:
+	
+	
+	/*
+	 * 
+	 *  Methods for commanding Profiler Engine
+	 *   
+	 */
+	
+	// get general settings
+	static inline TInt GetGeneralAttributes(TGeneralAttributes& aAttributes);
+	
+	// get samplers; names, settings, states, descriptions etc. in one array containing all sampler attributes
+	static inline TInt GetSamplerAttributes(CArrayFixFlat<TSamplerAttributes>& aAttributeArray);
+	
+	// save settings back to engine and plugins
+	static inline TInt SetGeneralAttributes(TGeneralAttributes aAttributes);
+
+	// save settings back to engine and plugins
+    static inline TInt SetSamplerAttributes(TSamplerAttributes aAttributes);
+    
+    // refresh profiler engine status
+    static inline TInt RefreshProfilerStatus();	
+	
+    /** Start sampling */
+	static inline TInt StartSampling(TProfilingMode aProfilingMode = EProfilingModeNormal);
+	/** Stop sampling */
+	static inline TInt StopSampling();
+    /** Load settings */
+//    static inline TInt LoadSettings(TDesC& aSettingsFile);
+	/** Exit profiler */
+	static inline TInt ExitProfiler();
+
+	/** Get file name */
+	static inline TInt GetFileName(TDes&);
+    /** Get active writer */
+    static inline TInt GetActiveWriter(TDes&);
+	/** Perform a test case */
+	static inline TInt Test(TUint32 testCase);
+	/** Issue a control request to the engine without data*/
+	static inline TInt ControlState(TCommand aRequest);
+	/** Issue a control request to the engine with descriptor data to write there*/
+	static inline TInt ControlWrite(TCommand aRequest,TDesC& data);
+	/** Issue a control request to the engine with numeric and descriptor data to write there*/
+	static inline TInt ControlWrite(TCommand aRequest,TInt numData, TDesC& data);
+	/** Issue a control request to read descriptor data from the engine*/
+	static inline TInt ControlRead(TCommand aRequest,TDes& data);
+	/** Actually sends the message to profiler engine*/	
+	static inline TInt PerformControl(	TCommand aRequest,
+										TDesC* fromDescriptor = NULL,
+										TUint32 numData1 = 0,
+										TDes* toDescriptor = NULL,
+										TUint32 numData2 = 0xffffffff);
+	
+	static inline TInt AttachClient();
+	static inline TInt RemoveClient();
+
+private:
+	inline RProfiler();
+	};
+
+inline RProfiler::RProfiler()
+	{}
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlState(TCommand aRequest)
+    { return PerformControl(aRequest); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlWrite(TCommand aRequest,TDesC& data)
+    { return PerformControl(aRequest,&data,0); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlWrite(TCommand aRequest,TInt numData, TDesC& data)
+    { return PerformControl(aRequest,&data,numData); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlRead(TCommand aRequest,TDes& data)
+    { return PerformControl(aRequest,0,0,&data); }
+
+inline TInt RProfiler::PerformControl(TCommand aRequest,TDesC* fromDescriptor,TUint32 numData1,TDes* toDescriptor,TUint32 numData2)
+	{
+	LOGTEXT(_L("Creating a session to profiler"));
+	RProfiler p;
+	TUint count(0);
+	TInt r(KErrNone);
+
+	// in boot measurement mode, count until 30s
+	#ifdef PROFILER_BOOT_MEASUREMENT
+	while(count < 60)
+	#else
+	while(count < 6)
+	#endif
+		{
+		r = p.CreateSession(KProfilerName, TVersion(), 0);
+		if (r == KErrNone)
+			{
+			LOGSTRING2("Succeeded, sending a message %d", aRequest);
+			LOGSTRING5(" - parameters 0x%x 0x%x 0x%x 0x%x",fromDescriptor,numData1,toDescriptor,numData2);
+			TInt err = KErrNone;
+
+			TIpcArgs a;
+			a.Set(0,fromDescriptor);
+			a.Set(1,numData1);
+			a.Set(2,toDescriptor);
+			a.Set(3,numData2);
+			err = p.SendReceive(aRequest,a);
+
+			p.RSessionBase::Close();
+			
+			if(err != KErrNone)
+				{
+				LOGSTRING2("Profiler responded with an error - code %d !!",err);		
+				return err;
+				}
+			else
+				{ 
+				LOGTEXT(_L("OK, message sent, closing"));
+				return KErrNone;
+				}
+			}
+
+		LOGSTRING2("Error in opening session to profiler - code %d !!",r);
+		//#ifdef PROFILER_BOOT_MEASUREMENT
+		// there was an error contacting the Profiler
+		// indicates that the server is most probably not up
+		// however, since it should be(unless some resource is not yet ready)
+		// we can just wait
+		User::After(500000); // wait 1/2 s
+		count++;
+		//#else
+		// exit immediately on error
+		//return r;
+		//#endif
+		}
+	return r;
+	}
+
+// the new UI access methods
+inline TInt RProfiler::GetGeneralAttributes(TGeneralAttributes& aAttributes)
+    {
+#ifdef _TEST_
+    _LIT(KDefaultTraceOutput,"debug_output");
+    _LIT(KDefaultTraceFilePrefix,"PIProfiler_#");
+    _LIT(KDefaultTraceFileSaveDrive,"E:\\");
+    aAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+    aAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+    aAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+#else
+    LOGTEXT(_L("Creating a session to profiler"));
+    RProfiler p;
+    TInt r(KErrNone);
+    r = p.CreateSession(KProfilerName, TVersion(), 0);
+    if (r == KErrNone)
+        {
+        LOGSTRING2("Succeeded, sending a message %d", EGetGeneralAttributes);
+
+        TPckg<TGeneralAttributes> attrPckg(aAttributes);
+        TIpcArgs a(&attrPckg);
+        r = p.SendReceive(RProfiler::EGetGeneralAttributes,a);
+        
+        p.RSessionBase::Close();
+        
+        if(r != KErrNone)
+            {
+            LOGSTRING2("Profiler responded with an error - code %d !!",r);        
+            return r;
+            }
+        else
+            { 
+            LOGTEXT(_L("OK, message sent, closing"));
+            return KErrNone;
+            }
+        }
+#endif
+    return r;   // return error code  
+    }
+inline TInt RProfiler::GetSamplerAttributes(CArrayFixFlat<TSamplerAttributes>& aAttributes)
+    {
+#ifdef _TEST_
+    _LIT(KDefaultTraceOutput,"debug_output");
+    _LIT(KDefaultTraceFilePrefix,"PIProfiler_#");
+    _LIT(KDefaultTraceFileSaveDrive,"E:\\");
+    aAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+    aAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+    aAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+#else
+    // do receive stream of TSamplerAttributes
+    LOGTEXT(_L("Creating a session to profiler"));
+    RProfiler p;
+    TInt r(KErrNone);
+    r = p.CreateSession(KProfilerName, TVersion(), 0);
+    if (r == KErrNone)
+        {
+        TInt attrCount(0);
+        TPckg<TInt> pckg(attrCount);
+        TIpcArgs args(&pckg);
+        
+        r = p.SendReceive(RProfiler::EGetSamplerAttributeCount, args);
+        
+        HBufC8* buffer = HBufC8::NewL(attrCount*sizeof(TSamplerAttributes));
+        TPtr8 ptr(buffer->Des());
+        TIpcArgs args2(&ptr);
+        r = p.SendReceive(RProfiler::EGetSamplerAttributes, args2);
+        
+        TInt len(ptr.Length());
+        TInt pos(0);
+        while (pos != len)
+           {
+           TPckgBuf<TSamplerAttributes> attrPckg;
+           attrPckg.Copy(ptr.Mid(pos, attrPckg.Length()));
+           pos += attrPckg.Length();
+    
+           aAttributes.AppendL(attrPckg());
+           }
+        
+        p.RSessionBase::Close();
+        
+        if(r != KErrNone)
+            {
+            LOGSTRING2("Profiler responded with an error - code %d !!",r);        
+            return r;
+            }
+        else
+            { 
+            LOGTEXT(_L("OK, message sent, closing"));
+            return KErrNone;
+            }
+        }
+#endif
+    return KErrNone; 
+    }
+
+inline TInt RProfiler::SetGeneralAttributes(TGeneralAttributes aAttributes)
+    {
+    // do receive stream of TSamplerAttributes
+    LOGTEXT(_L("Creating a session to profiler"));
+    RProfiler p;
+    TInt r(KErrNone);
+    r = p.CreateSession(KProfilerName, TVersion(), 0);
+    if (r == KErrNone)
+        {
+
+        TPckg<TGeneralAttributes> attrPckg(aAttributes);
+        TIpcArgs a(&attrPckg);
+        r = p.SendReceive(RProfiler::ESetGeneralAttributes,a);
+        
+        p.RSessionBase::Close();
+        
+        if(r != KErrNone)
+            {
+            LOGSTRING2("Profiler responded with an error - code %d !!",r);        
+            return r;
+            }
+        else
+            { 
+            LOGTEXT(_L("OK, message sent, closing"));
+            return KErrNone;
+            }
+        }
+    return r; 
+    }
+
+// save settings back to engine and plugins
+inline TInt RProfiler::SetSamplerAttributes(TSamplerAttributes aAttributes)
+    {
+    // do receive stream of TSamplerAttributes
+    LOGTEXT(_L("Creating a session to profiler"));
+    RProfiler p;
+    TInt r(KErrNone);
+    r = p.CreateSession(KProfilerName, TVersion(), 0);
+    if (r == KErrNone)
+        {
+
+        TPckg<TSamplerAttributes> attrPckg(aAttributes);
+        
+        TIpcArgs a;
+        a.Set(0,&attrPckg);
+
+        r = p.SendReceive(RProfiler::ESetSamplerAttributes,a);
+        
+        p.RSessionBase::Close();
+        
+        if(r != KErrNone)
+            {
+            LOGSTRING2("Profiler responded with an error - code %d !!",r);        
+            return r;
+            }
+        else
+            { 
+            LOGTEXT(_L("OK, message sent, closing"));
+            return KErrNone;
+            }
+        }
+    return r; 
+    }
+
+inline TInt RProfiler::RefreshProfilerStatus()
+    {return ControlState(RProfiler::ERefreshProfilerStatus); }
+
+inline TInt RProfiler::StartSampling(RProfiler::TProfilingMode aProfilingMode)
+	{
+    RProfiler::TCommand command = RProfiler::EStartSampling;
+    if( aProfilingMode == RProfiler::EProfilingModeTimed )
+        {
+        command = RProfiler::EStartTimedSampling;
+        }    
+    return ControlState(command);
+	}
+
+inline TInt RProfiler::StopSampling()
+	{return ControlState(RProfiler::EStopSampling);}
+
+inline TInt RProfiler::ExitProfiler()
+	{return ControlState(RProfiler::EExitProfiler);}
+
+inline TInt RProfiler::AttachClient()
+    {return ControlState(RProfiler::EAttachClient);}
+
+inline TInt RProfiler::RemoveClient()
+    {return ControlState(RProfiler::ERemoveClient);}
+
+inline TInt RProfiler::GetFileName(TDes& fileName)
+	{return ControlRead(EGetFileName,fileName);}
+
+inline TInt RProfiler::GetActiveWriter(TDes& writerDes)
+    {return ControlRead(EGetActiveWriter,writerDes);}
+
+#endif // __PROFILER_SESSION_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerTraces.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PROFILER_TRACES_H__
+#define __PROFILER_TRACES_H__
+
+#include <e32def.h>
+
+
+// ---------------------------------------------------------------------------
+// You change these logging method values below! Recompile the application to take changes effect.
+
+    // logging methods
+    // 0 = No logging
+    // 1 = Flogger
+    // 2 = RDebug
+    // 3 = Flogger and RDebug
+
+#undef _DEBUG
+
+    #ifndef _DEBUG
+        
+        // Logging method for UREL builds:
+        #define PROFILER_LOGGING_METHOD  0
+
+    #else
+
+        // Logging method for UDEB builds:
+        #define PROFILER_LOGGING_METHOD  2
+
+    #endif    
+    
+    #ifndef _KERNEL_DEBUG
+        
+        // Logging method for UREL builds:
+        #define KERNEL_LOGGING_METHOD  0
+
+    #else
+
+        // Logging method for UDEB builds:
+        #define KERNEL_LOGGING_METHOD  1
+
+    #endif    
+
+
+
+#ifndef __KERNEL_MODE__
+
+// ---------------------------------------------------------------------------
+// Do not make any changes to lines below...
+
+    #if PROFILER_LOGGING_METHOD == 1 || PROFILER_LOGGING_METHOD == 3
+
+        #include <flogger.h>
+        _LIT(KLogFolder,"PIProfiler");
+        _LIT(KLogFile,"PIProfiler_Trace.txt");
+
+    #endif
+
+    #if PROFILER_LOGGING_METHOD == 2 || PROFILER_LOGGING_METHOD == 3
+
+        #include <e32debug.h>
+
+    #endif
+
+
+    #if PROFILER_LOGGING_METHOD == 0
+    
+        #define LOGTEXT(AAA)
+        #define LOGSTRING(AAA)
+        #define LOGSTRING2(AAA,BBB)
+        #define LOGSTRING3(AAA,BBB,CCC)
+        #define LOGSTRING4(AAA,BBB,CCC,DDD)
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE)
+    
+    
+    #elif PROFILER_LOGGING_METHOD == 1
+    
+        #define LOGTEXT(AAA)                RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend, AAA)
+        #define LOGSTRING(AAA)              do { _LIT(tempLogDes,AAA); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend,tempLogDes()); } while (0)
+        #define LOGSTRING2(AAA,BBB)         do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB); } while (0)
+        #define LOGSTRING3(AAA,BBB,CCC)     do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC); } while (0)
+        #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD); } while (0)
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD,EEE); } while (0)
+   
+    #elif PROFILER_LOGGING_METHOD == 2
+    
+        #define LOGTEXT(AAA)                RDebug::Print(AAA);
+        #define LOGSTRING(AAA)              do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes); } while (0)
+        #define LOGSTRING2(AAA,BBB)         do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB); } while (0)
+        #define LOGSTRING3(AAA,BBB,CCC)     do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC); } while (0)
+        #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD); } while (0)
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD, EEE); } while (0)
+    
+    #elif PROFILER_LOGGING_METHOD == 3
+    
+        #define LOGTEXT(AAA)                RDebug::Print(AAA); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend, AAA)
+        #define LOGSTRING(AAA)              do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend,tempLogDes()); } while (0)
+        #define LOGSTRING2(AAA,BBB)         do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB); } while (0)
+        #define LOGSTRING3(AAA,BBB,CCC)     do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC); } while (0)
+        #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD); } while (0)
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD, EEE); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD,EEE); } while (0)
+
+    #endif
+
+#else __KERNEL_MODE__
+
+	#if KERNEL_LOGGING_METHOD == 0
+	
+		#define LOGTEXT(AAA)
+		#define LOGSTRING(AAA)
+		#define LOGSTRING2(AAA,BBB)
+		#define LOGSTRING3(AAA,BBB,CCC)
+		#define LOGSTRING4(AAA,BBB,CCC,DDD)
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE)
+
+	#else
+	
+		#define LOGTEXT(AAA)               		Kern::Printf(AAA)
+		#define LOGSTRING(AAA)             		Kern::Printf(AAA);
+		#define LOGSTRING2(AAA,BBB)        		Kern::Printf(AAA, BBB);
+		#define LOGSTRING3(AAA,BBB,CCC)     	Kern::Printf(AAA, BBB, CCC);
+		#define LOGSTRING4(AAA,BBB,CCC,DDD) 	Kern::Printf(AAA, BBB, CCC, DDD);
+		#define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) Kern::Printf(AAA, BBB, CCC, DDD, EEE);
+
+	#endif
+#endif
+// ---------------------------------------------------------------------------
+
+#endif // __PROFILER_TRACES_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerVersion.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_TOOL_VERSION_H
+#define PROFILER_TOOL_VERSION_H
+
+	/*
+	 *
+	 *	PI Profiler tool composition definitions
+	 *
+	 */	
+
+	#define PROFILER_VERSION		"PI Profiler v2.1.0"
+	#define PROFILER_VERSION_SHORT	_L("2.00.0")
+	#define PROFILER_SAMPLER_VERSION	_L("2.00.0")
+	#define PROFILER_RELEASE_DATE			_L("23rd February 2009. ")
+	
+	#define PROFILER_GPP_SAMPLER_VERSION   _L("2.00")    // SMPfied v2.00
+	#define PROFILER_GFC_SAMPLER_VERSION   _L8("1.10")
+	#define PROFILER_ITT_SAMPLER_VERSION   _L8("1.22")
+	#define PROFILER_MEM_SAMPLER_VERSION	_L8("2.02")
+	#define PROFILER_PRI_SAMPLER_VERSION	_L8("1.56")
+	#define PROFILER_BUP_SAMPLER_VERSION	_L8("1.20")
+	#define PROFILER_IRQ_SAMPLER_VERSION	_L8("1.20")
+	#define PROFILER_TIP_SAMPLER_VERSION	_L8("1.10")
+	#define PROFILER_PEC_SAMPLER_VERSION  _L8("1.24")
+	#define PROFILER_PWR_SAMPLER_VERSION	_L8("1.57")
+	#define PROFILER_SCR_SAMPLER_VERSION	_L8("1.57")
+	#define PROFILER_IPC_SAMPLER_VERSION	_L8("1.59")
+    #define PROFILER_GPU_SAMPLER_VERSION    _L8("1.00")
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/SamplerPluginInterface.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,257 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __SAMPLER_PLUGIN_INTERFACE__
+#define __SAMPLER_PLUGIN_INTERFACE__
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <badesca.h>
+#include <piprofiler/ProfilerAttributes.h>	// internal settings format presentations 
+
+
+// Constant for indexing (iOrder):
+const TInt KSamplerPluginNotIndexed      = -1;
+
+/**
+ * Constant:    KSamplerPluginInterfaceUid
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *              It is used to identify this specific custom interface.
+ *              Implementations of this interface will use this ID, when they
+ *              publish the implementation. Clients use this UID to search for
+ *              implementations for this interface (the
+ *              EcomInterfaceDefinition.inl does this).
+ */
+const TUid KSamplerPluginInterfaceUid = {0x2001E5BC};
+
+/**
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *
+ */
+enum TGenericSettingTypes
+{
+	EEnablePlugin,
+	EOutputSettings,
+	ESaveDrive,
+	EFilePrefix,
+	ETracingMode
+};
+
+
+enum TSamplerCaptionTypes
+	{
+	ECaptionLengthShort,
+	ECaptionLengthMedium,
+	ECaptionLengthLong,
+    ESettingsCaption
+	};
+
+
+/**
+* Used by GetValue(). These are the keys for retrieving a specific
+* value. This enum can be extended to provide other values as well as
+* long as the original keys are not changed.
+*/
+enum TSamplerPluginValueKeys
+    {
+
+    ESamplerPluginKeySettingsItemValueString = 1,
+    ESamplerPluginSettings,
+    ESamplerPluginEnabled,
+    ESamplerPluginDisabled,
+    ESamplerPluginType,
+    ESamplerPluginVersion
+    };
+ 
+
+/**
+ * Class:       CSamplerInterfaceDefinition
+ *
+ * Description: Custom ECOM interface definition. This interface is used by
+ *              clients to find specific instance and do corresponding
+ *              calculation operation for given too numbers. Plugin
+ *              implementations implement the Calculate function.
+ */
+class TBapBuf;
+class CProfilerSampleStream;
+
+class CSamplerPluginInterface : public CBase 
+{
+
+    // CSamplerPluginLoader accesses iOrder which should not be accessed outside.
+    friend class CSamplerPluginLoader;
+
+public: 
+	// Wrapper functions to handle ECOM "connectivity".
+    // These are implemented in EComInterfaceDefinition.inl.
+    // These functions are used only by the client.
+    
+	/**
+     * Function:   NewL
+     *
+     * Description: Wraps ECom object instantitation. Will search for
+     *              interface implementation, which matches to given
+     *              aOperationName.
+     *
+     * Param:       aOperationName name of requested implementation.
+     *              Implementations advertise their "name" as specified
+     *              in their resource file field
+     *                 IMPLEMENTATION_INFO::default_data.
+     *              For details, see EcomInterfaceDefinition.inl comments.
+     *              In this example, the allowed values are "sum" and
+     *              "multiply".
+     *
+     * Note:        This is not a "normal" NewL method, since normally NewL
+     *              methods are only defined for concrete classes.
+     *              Note that also implementations of this interface provide
+     *              NewL methods. They are the familiar NewL's, which create
+     *              instance of classes.
+     */
+    static CSamplerPluginInterface* NewL(const TUid aImplementationUid, TAny* aInitParams);
+
+    /**
+     * Function:   ~CSamplerPluginInterface
+     *
+     * Description: Wraps ECom object destruction. Notifies the ECOM
+     *              framework that specific instance is being destroyed.
+     *              See EcomInterfaceDefinition.inl for details.
+     */
+    virtual ~CSamplerPluginInterface();
+protected: // New
+
+	/**
+	* C++ constructor.
+	*/
+	CSamplerPluginInterface();
+        
+public: 
+	// Public pure virtual functions, which are implemented by
+    // interface implementations (See ..\plugin)
+    
+    /**
+     * Method for initializing and starting of profiling in single plugin implementation
+     * @param aStream is a data stream to store the gathered data, provided by engine
+     * @return TInt if no error KErrNone, else any of system-wide errors
+     */
+    virtual TInt	ResetAndActivateL(CProfilerSampleStream& aStream) = 0;
+
+	/**
+     * Method for stopping of profiling in single plugin implementation
+     * @return TInt if no error KErrNone, else any of system-wide errors
+     */
+    virtual TInt	StopSampling() = 0;
+	
+    /**
+     * Method for checking if plugin is enabled
+     * @return TBool if enabled return ETrue else EFalse
+     */
+    virtual TBool   Enabled() = 0;
+ 	
+    /**
+    * Method for getting an array of sampler attributes, size of an array: 1...n
+    * @return array of settings of one or several sampler plugins
+    */
+    virtual void GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributeArray) = 0;	
+    
+    /**
+    * Method for setting configurations of single sampler attributes
+    * @param aAttributes contains settings of a single sampler plugin 
+    */
+    virtual TInt SetAttributesL(TSamplerAttributes aAttributes) = 0; 
+    
+    /**
+    * Method for parsing text formatted settings block and converting
+    * it to TSamplerAttributes data structure
+    * @param aSingleSettingArray containing setting lines of a single sampler
+    * @return status of conversion, if success KErrNone, else KErrGeneral
+    */
+    virtual TInt ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray) = 0;
+ 
+    /**
+    * Method for getting UID of this plugin.
+    * @param aSubId the implementation id of sub sampler
+    * @returns uid of sampler or sub sampler, if aSubId -1 uid of sampler, else uid of sub sampler
+    */
+    virtual TUid 	Id(TInt aSubId) const = 0;
+    
+    /**
+    * Method for getting locally defined sub ID value inside a specific plug-in.
+    * @param aUid of a specific sampler
+    * @returns local ID of sampler or sub sampler
+    */
+    virtual TInt 	SubId(TUid aUid) const = 0;
+    
+    /**
+    * Method for getting sampler type.
+    * @returns PROFILER_USER_MODE_SAMPLER, PROFILER_KERNEL_MODE_SAMPLER or PROFILER_DUMMY_MODE_SAMPLER
+    */
+    virtual TInt 	GetSamplerType() = 0;
+	 
+	 
+	 // some internal inline methods, used by engine
+    inline TInt     Flush();
+    inline TInt     AddSample(TUint8* sample, TUint32 length, TInt limitSize);  
+    inline void     SetOrder( TInt aOrder );
+    inline static void ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray);
+
+    /**
+    * Static methods for getting setting value out of descriptor
+    * 
+    * @param aBuf buffer where to convert the value
+    * @param aValue parameter where to store the requested type of value
+    */
+    inline static void     Str2Bool(const TDesC8& aBuf, TBool& aValue);
+    inline static void     Str2Int(const TDesC8& aBuf, TInt& aValue);
+    inline static void     Str2Int(const TDesC8& aBuf, TUint32& aValue);
+     
+    /** iDtor_ID_Key Instance identifier key. When instance of an
+     *               implementation is created by ECOM framework, the
+     *               framework will assign UID for it. The UID is used in
+     *               destructor to notify framework that this instance is
+     *               being destroyed and resources can be released.
+     */
+    TUid iDtor_ID_Key;
+    
+    /**
+	* Index of the plugin in listbox. Used for CSamplerPluginLoader. Default
+	* value is KSamplerPluginNotIndexed which means not ordered. This value is
+	* read, if defined, from the opaque_data field of the plugin's resource
+	* definition. Index starts from 0.
+	*/
+	TInt iOrder;
+
+public:	    
+	TInt 					iSamplerType;
+	
+	// this variable must be defined by the extending classes!!
+	TInt					iSamplerId;
+	
+	CProfilerSampleStream*	iStream;
+    TBool                   iEnabled;
+		
+private:
+	TBapBuf*				iBuffer;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <piprofiler/SamplerPluginInterface.inl>
+
+
+#endif // __SAMPLER_PLUGIN_INTERFACE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/SamplerPluginInterface.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// LITERALS
+_LIT8(KTrue, "true");
+_LIT8(KFalse, "false");
+
+inline CSamplerPluginInterface::CSamplerPluginInterface()
+    : iOrder( KSamplerPluginNotIndexed )
+    {
+    iBuffer = 0;
+    iStream = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CSamplerPluginInterface::~CSamplerPluginInterface()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+inline CSamplerPluginInterface::~CSamplerPluginInterface()
+    {
+    iBuffer = 0;
+    REComSession::DestroyedImplementation(iDtor_ID_Key);
+    }
+
+
+inline CSamplerPluginInterface* CSamplerPluginInterface::NewL(const TUid aImplementationUid, TAny* aInitParams)
+    {
+    // Define options, how the default resolver will find appropriate
+    // implementation.
+    return REINTERPRET_CAST(CSamplerPluginInterface*, 
+                            REComSession::CreateImplementationL(aImplementationUid,
+                                                                _FOFF( CSamplerPluginInterface, iDtor_ID_Key ),
+                                                                aInitParams)); 
+    }
+
+inline void CSamplerPluginInterface::ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray)
+    {
+    REComSession::ListImplementationsL(KSamplerPluginInterfaceUid, aImplInfoArray);
+    }
+
+inline void CSamplerPluginInterface::SetOrder( TInt aOrder )
+    {
+    iOrder = aOrder;
+    }
+
+inline TInt CSamplerPluginInterface::Flush() 
+    {
+	// complete the header
+	TUint32 header;
+	header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+	header += (iSamplerId << 24);
+
+	// flush the header info
+	iBuffer->iBuffer[0] = header;
+	iBuffer->iBuffer[1] = header >> 8;
+	iBuffer->iBuffer[2] = header >> 16;
+	iBuffer->iBuffer[3] = header >> 24;
+	
+    // write data to filled buffers
+    iStream->AddToFilledBuffers(iBuffer);
+    // notify selected writer plugin to write data to output
+    iStream->NotifyWriter();
+
+    iBuffer = 0;
+
+	return KErrNone;
+}
+
+
+inline TInt CSamplerPluginInterface::AddSample(TUint8* aSample, TUint32 aLength, TInt aLimitSize)
+    {
+    LOGTEXT(_L("CSamplerPluginInterface::AddSample - entry"));
+	if(iBuffer == 0) 
+	    {
+	    // get next free buffer where to write data
+		iBuffer = iStream->GetNextFreeBuffer();
+		iBuffer->iBufDes->Zero();
+		
+		// get space for the header
+		TUint32 header = 0;
+		iBuffer->iBufDes->Append((TUint8*)&header, 4);	
+		iBuffer->iDataSize += 4;
+	    }
+		
+	// add data to the buffer...
+	// if all data fit to the current buffer
+	if(iBuffer->iBufferSize - iBuffer->iDataSize >= (TInt)aLength)
+	    {
+		iBuffer->iBufDes->Append(aSample, (TInt)aLength);
+		iBuffer->iDataSize += (TInt)aLength;
+	    }
+	else 
+	    {	
+		// fill in the buffer
+		TUint32 rest = iBuffer->iBufferSize - iBuffer->iDataSize;
+		iBuffer->iBufDes->Append(aSample, rest);
+		iBuffer->iDataSize += (TInt)rest;
+		
+		// The buffer is full now, complete the header
+		TUint32 header;
+		header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+		header += (iSamplerId << 24);
+		iBuffer->iBuffer[0] = header;
+		iBuffer->iBuffer[1] = header >> 8;
+		iBuffer->iBuffer[2] = header >> 16;
+		iBuffer->iBuffer[3] = header >> 24;
+		
+		// write data to filled buffers
+		iStream->AddToFilledBuffers(iBuffer);
+	    // notify selected writer plugin to write data to output
+	    iStream->NotifyWriter();
+		
+		// Fetch an empty buffer and reserve space for the header
+		iBuffer = iStream->GetNextFreeBuffer();
+		iBuffer->iBufDes->Zero();
+		header = 0;
+		iBuffer->iBufDes->Append((TUint8*)&header, 4);	
+		iBuffer->iDataSize += 4;
+			
+		// copy the rest of data to the new buffer
+		iBuffer->iBufDes->Append(aSample+rest, aLength-rest);
+		iBuffer->iDataSize += (TInt)aLength-rest;
+	    }
+	
+	// Once iBuffer->dataSize reaches the limitSize, data from iBuffer is flushed to file/debug port.
+	// If limitSize is set to zero, buffer is not changed until iBuffer gets full.
+	if(aLimitSize != 0) 
+	    {
+		if(iBuffer->iDataSize >= aLimitSize) 
+		    {
+			// The buffer is full now, complete the header
+			TUint32 header;
+			header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+			header += (iSamplerId << 24);
+			iBuffer->iBuffer[0] = header;
+			iBuffer->iBuffer[1] = header >> 8;
+			iBuffer->iBuffer[2] = header >> 16;
+			iBuffer->iBuffer[3] = header >> 24;
+	
+
+            // write data to filled buffers
+            iStream->AddToFilledBuffers(iBuffer);
+            // notify selected writer plugin to write data to output
+            iStream->NotifyWriter();
+		    
+			// Fetch an empty buffer and reserve space for the header
+			iBuffer = iStream->GetNextFreeBuffer();
+			iBuffer->iBufDes->Zero();
+			header = 0;
+			iBuffer->iBufDes->Append((TUint8*)&header, 4);	
+			iBuffer->iDataSize += 4;
+		    }
+	    }
+	return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TBool value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Bool(const TDesC8& aBuf, TBool& aValue)
+    {
+    if (aBuf.CompareF(KFalse) == 0)
+        aValue = EFalse;
+    else
+        aValue = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Int(const TDesC8& aBuf, TInt& aValue)
+    {
+    TLex8 conv;
+    conv.Assign(aBuf);
+    
+    if (conv.Val(aValue) != KErrNone)
+        aValue = 0;
+    }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Int(const TDesC8& aBuf, TUint32& aValue)
+    {
+    TInt temp(0);
+    
+    TLex8 conv;
+    conv.Assign(aBuf);
+    
+    if (conv.Val(temp) != KErrNone)
+        aValue = 0;
+    else
+        aValue = (TUint32)temp;
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/WriterPluginInterface.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __WRITERPLUGIN_INTERFACE__
+#define __WRITERPLUGIN_INTERFACE__
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <badesca.h>
+
+
+// Constant for indexing (iOrder):
+const TInt KWriterPluginNotIndexed      = -1;
+
+/**
+ * Constant:    KWriterPluginInterfaceUid
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *              It is used to identify this specific custom interface.
+ *              Implementations of this interface will use this ID, when they
+ *              publish the implementation. Clients use this UID to search for
+ *              implementations for this interface (the
+ *              EcomInterfaceDefinition.inl does this).
+ */
+const TUid KWriterPluginInterfaceUid = {0x2001E5BD};
+
+/**
+* Used by GetValue(). These are the keys for retrieving a specific
+* value. This enum can be extended to provide other values as well as
+* long as the original keys are not changed.
+*/
+enum TWriterPluginValueKeys
+    {
+    EWriterPluginKeySettingsItemValueString = 1,
+    EWriterPluginSettings,
+    EWriterPluginEnabled,
+    EWriterPluginDisabled,
+    EWriterPluginType,
+    EWriterPluginVersion
+    };
+/**
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *
+ */
+    
+/**
+ * Class:       CWriterInterfaceDefinition
+ *
+ * Description: Custom ECOM interface definition. This interface is used by
+ *              clients to find specific instance and do corresponding
+ *              calculation operation for given too numbers. Plugin
+ *              implementations implement the Calculate function.
+ */
+
+class CProfilerSampleStream;
+
+class CWriterPluginInterface : public CBase
+    {
+
+    // CSamplerPluginLoader accesses iOrder which should not be accessed outside.
+    friend class CWriterPluginLoader;
+
+public: // Wrapper functions to handle ECOM "connectivity".
+        // These are implemented in EComInterfaceDefinition.inl.
+        // These functions are used only by the client.
+    /**
+     * Function:   NewL
+     *
+     * Description: Wraps ECom object instantitation. Will search for
+     *              interface implementation, which matches to given
+     *              aOperationName.
+     *
+     * Param:       aOperationName name of requested implementation.
+     *              Implementations advertise their "name" as specified
+     *              in their resource file field
+     *                 IMPLEMENTATION_INFO::default_data.
+     *              For details, see EcomInterfaceDefinition.inl comments.
+     *              In this example, the allowed values are "sum" and
+     *              "multiply".
+     *
+     * Note:        This is not a "normal" NewL method, since normally NewL
+     *              methods are only defined for concrete classes.
+     *              Note that also implementations of this interface provide
+     *              NewL methods. They are the familiar NewL's, which create
+     *              instance of classes.
+     */
+    static CWriterPluginInterface* NewL(const TUid aImplementationUid, TAny* aInitParams);
+
+    /**
+     * Function:   ~CWriterPluginInterface
+     *
+     * Description: Wraps ECom object destruction. Notifies the ECOM
+     *              framework that specific instance is being destroyed.
+     *              See EcomInterfaceDefinition.inl for details.
+     */
+    virtual ~CWriterPluginInterface();
+protected: // New
+
+        /**
+        * C++ constructor.
+        */
+        CWriterPluginInterface();
+       
+public: 
+     /**
+      * Method for getting caption of this plugin. This should be the
+      * localized name of the settings view to be shown in parent view.
+      *
+      * @param aCaption pointer to Caption variable
+      */
+	 virtual TInt 	Start() = 0;
+	 
+	 virtual void 	Stop() = 0;
+
+	 virtual TUid 	Id() const = 0;
+	 
+	 virtual void 	GetValue( const TWriterPluginValueKeys aKey, TDes& aValue ) = 0;
+	 
+	 virtual void 	SetValue( const TWriterPluginValueKeys aKey, TDes& aValue ) = 0;
+	
+	 virtual void 	GetWriterVersion(TDes* aDes) = 0;
+
+	 virtual TUint32 GetWriterType() = 0;
+
+	 virtual TBool GetEnabled() = 0;
+
+     virtual void   WriteData() = 0;
+     virtual void   SetStream( CProfilerSampleStream& aStream ) = 0;
+     
+	 // internal inline functions
+	 inline static void ListAllImplementationsL( RImplInfoPtrArray& aImplInfoArray );
+     inline void    SetOrder( TInt aOrder );
+     
+private:
+
+    /** iDtor_ID_Key Instance identifier key. When instance of an
+    * implementation is created by ECOM framework, the
+    * framework will assign UID for it. The UID is used in
+    * destructor to notify framework that this instance is
+    * being destroyed and resources can be released.
+    */
+    TUid iDtor_ID_Key;
+    
+    /**
+    * Index of the plugin in listbox. Used for CSamplerPluginLoader. Default
+    * value is KSamplerPluginNotIndexed which means not ordered. This value is
+    * read, if defined, from the opaque_data field of the plugin's resource
+    * definition. Index starts from 0.
+    */
+    TInt iOrder;
+public:
+	TInt	                      iAdditionalSettings;	
+	TBool                         isEnabled;
+    };
+
+#include <piprofiler/WriterPluginInterface.inl>
+
+#endif // __WRITERPLUGIN_INTERFACE__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/WriterPluginInterface.inl	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+inline CWriterPluginInterface::CWriterPluginInterface()
+    : iOrder( KWriterPluginNotIndexed ) 
+    {
+        
+    }
+
+// -----------------------------------------------------------------------------
+// CWriterPluginInterface::~CWriterPluginInterface()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+inline CWriterPluginInterface::~CWriterPluginInterface()
+    {
+    // We don't unload the plugin object here. The loader
+    // has to do this for us. Without this kind of destruction idiom, 
+    // the view framework can potentially unload an ECOM plugin dll whilst 
+    // there are still child views (Created by the plugin) that are registered 
+    // with the view framework. If this occurs, the plugin code segment isn't 
+    // loaded anymore and so there is no way to run the subsequent destructor 
+    // code => exception.
+    
+    // If in the NewL some memory is reserved for member data, it must be
+    // released here. This interface does not have any instance variables so
+    // no need to delete anything.
+
+    // Inform the ECOM framework that this specific instance of the
+    // interface has been destroyed.
+    REComSession::DestroyedImplementation(iDtor_ID_Key);
+    }
+
+inline CWriterPluginInterface* CWriterPluginInterface::NewL(const TUid aImplementationUid, TAny* aInitParams)
+    {
+    // Define options, how the default resolver will find appropriate
+    // implementation.
+    return REINTERPRET_CAST(CWriterPluginInterface*, 
+                            REComSession::CreateImplementationL(aImplementationUid,
+                                                                _FOFF( CWriterPluginInterface, iDtor_ID_Key ),
+                                                                aInitParams)); 
+    }
+
+inline void CWriterPluginInterface::ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray)
+    {
+    REComSession::ListImplementationsL(KWriterPluginInterfaceUid, aImplInfoArray);
+    }
+
+inline void CWriterPluginInterface::SetOrder( TInt aOrder )
+    {
+    iOrder = aOrder;
+    }
+
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/piprofiler_api.metaxml	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<api id="59f5d0509cc9c1556b04d7b6ff036bd0" dataversion="2.0">
+  <name>PIProfiler API</name>
+  <description>Defines the PIProfiler API, which is used for different PI Profiler sub projects.</description>
+  <type>c++</type>
+  <collection>piprofiler</collection>
+  <libs>
+    <lib name="piprofilerapi.lib"/>
+  </libs>
+  <release category="platform" sinceversion=""/>
+  <attributes>
+    <!-- This indicates wether the api provedes separate html documentation -->
+    <!-- or is the additional documentation generated from headers. -->
+    <!-- If you are unsuere then the value is "no" -->
+    <htmldocprovided>no</htmldocprovided>
+    <adaptation>no</adaptation>
+  </attributes>
+</api>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/data/2001E5B6.rss	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL. See mmp files
+    //__SERIES60_3X__ can't be used in resource files
+    dll_uid = 0x2001E5B6;
+
+    // Declare array of interface info. This dll contains implementations for 
+    // only one interface (CSamplerInterfaceDefinition).
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = 0x2001E5BC;
+
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = 0x2001E5B6;
+
+                    version_no = 1;
+                    display_name = "BUP Sampler";
+                    default_data = "bup";
+                    opaque_data = "6";
+                    }
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/BUPPlugin.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET          PIProfilerBUP.dll
+TARGETTYPE      PLUGIN
+UID             0x10009D8D 0x2001E5B6
+VENDORID        VID_DEFAULT
+CAPABILITY      ALL -TCB
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE     ../inc
+SOURCEPATH      ../src
+
+START RESOURCE  ../data/2001E5B6.rss
+TARGET PIProfilerBUP.rsc
+END
+
+SOURCE      BupPluginImplementationTable.cpp
+SOURCE      BupPlugin.cpp 
+SOURCE      TouchEventClientDll.cpp
+
+LIBRARY     euser.lib
+LIBRARY		bafl.lib
+LIBRARY     ECom.lib
+LIBRARY     apparc.lib
+LIBRARY     cone.lib
+LIBRARY     gdi.lib
+LIBRARY     ws32.lib
+LIBRARY     EFSRV.LIB
+LIBRARY     charconv.lib
+LIBRARY     commonengine.lib
+LIBRARY		flogger.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/TouchAnimDll.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET      	PIProfilerTouchEventAnim.DLL
+UID 			0x10003B22 0x2001E5B7
+TARGETTYPE		ANI
+EPOCSTACKSIZE	0x5000
+VENDORID		VID_DEFAULT
+CAPABILITY		ALL -TCB // -AllFiles -NetworkControl -DiskAdmin -MultimediaDD -TCB -DRM
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE 	../inc
+SOURCEPATH		../src
+
+SOURCE 			TouchEventAnimDll.cpp
+
+LIBRARY 		euser.lib 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+PRJ_MMPFILES
+TouchAnimDll.mmp
+BUPPlugin.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/BupPlugin.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,211 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PIPROFILER_BUPECOM_SAMPLER_H
+#define PIPROFILER_BUPECOM_SAMPLER_H
+
+#include <w32std.h>
+#include <w32std.h>			// RWsSession
+#include <w32adll.h>		// RAnim DLL
+#include <e32std.h>
+#include <e32property.h>	// RProperty
+
+#include <piprofiler/ProfilerTraces.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+
+#include <data_caging_path_literals.hrh> // for KDC_SHARED_LIB_DIR
+
+// Button press&touch event Anim DLL interface
+#include "TouchEventClientDll.h"
+
+// caption definitions
+_LIT8(KBUPShortName, "bup");
+_LIT8(KBUPLongName, "Button and touch event capture");
+_LIT8(KBUPDescription, "Button and touch event sampler\nTracing button and touch screen events\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+const TUid KProfilerKeyEventPropertyCat={0x2001E5AD};
+enum TProfilerKeyEventPropertyKeys
+	{
+	EProfilerKeyEventPropertySample = 7
+	};
+
+const TUid KGppPropertyCat={0x20201F70};
+enum TGppPropertyKeys
+	{
+	EGppPropertySyncSampleNumber
+	};
+
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_C1(KCapabilityNone, ECapability_None);
+
+_LIT(KDllName, "PIProfilerTouchEventAnim.DLL");	// animation server dll	on user disk
+
+/*
+ *	
+ *	BUP sampler definition
+ *	
+ */
+class CProfilerButtonListener;
+class CSamplerPluginInterface;
+
+class CBupPlugin : public CSamplerPluginInterface
+{
+public:	
+	static CBupPlugin* NewL(const TUid aImplementationUid, TAny* aInitParams);
+			~CBupPlugin();
+
+	TInt	ResetAndActivateL(CProfilerSampleStream& aStream);
+	TInt	StopSampling();
+    TBool   Enabled() { return iEnabled; }
+
+	TInt	CreateFirstSample();
+
+	// no sub samplers, from CSamplerPluginInterface
+	TInt 	SubId(TUid /*aId*/) const {return KErrNotFound;}
+    TInt    GetSamplerType();
+	
+	void    GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+    TInt    SetAttributesL(TSamplerAttributes aAttributes);
+    void    InitiateSamplerAttributesL();
+	
+    TInt    ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray);
+    
+    TInt    DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex);
+    void    SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex);
+    
+	TUid  Id(TInt aSubId) const;
+
+	void FillThisStreamBuffer(TBapBuf* nextFree,TRequestStatus& aStatus); 
+	
+private:
+			CBupPlugin();
+	void 	ConstructL();
+
+private:
+	TUint8					iVersion[20];
+	TPtr8					iVersionDescriptor;
+	
+	TInt 					iSamplerType;
+
+	CProfilerButtonListener* 	iButtonListener;
+    CArrayFixFlat<TSamplerAttributes>* iSamplerAttributes;
+public:
+	TUint32* 				iSampleTime;
+};
+
+
+/*
+*
+*  Base class for all windows
+*
+*/
+class CWsClient : public CActive
+	{
+	protected:
+		//construct
+		CWsClient();
+		CWsScreenDevice* iScreen;
+		RWsSession iWs;
+	public:
+		void ConstructL();
+		// destruct
+		~CWsClient();
+		// main window
+		virtual void ConstructMainWindowL();
+		// terminate cleanly
+		void Exit();
+		// active object protocol
+		void IssueRequest(); // request an event
+		void DoCancel(); // cancel the request
+		virtual TInt RunError(TInt aError) = 0;
+		virtual void RunL() = 0; // handle completed request
+		virtual void HandleKeyEventL (TKeyEvent& aKeyEvent) = 0;
+
+		RWindowGroup Group() {return iGroup;};
+
+    private:
+		RWindowGroup    iGroup;
+		CWindowGc*      iGc;
+		friend class    CWindow; // needs to get at session
+		RProperty       iProperty;
+
+	};
+
+
+
+class CWindow;
+
+class CProfilerButtonListener : public CWsClient 
+{
+public:
+	static 	CProfilerButtonListener* NewL(CBupPlugin* aSamplerm);
+			~CProfilerButtonListener();
+private:
+			CProfilerButtonListener(CBupPlugin* aSampler);
+
+	
+public:
+	void 	ConstructMainWindowL();
+	void 	HandleKeyEventL (TKeyEvent& aKeyEvent);
+	void 	RunL();
+	TInt    RunError(TInt aError);
+	TInt 	StartL();
+	TInt	Stop();
+	
+private:
+	TUint8							iSample[8];
+
+	CBupPlugin*						iSampler;
+	RProfilerTouchEventAnim*			iAnim;
+	RAnimDll*						iAnimDll;
+	CWindow* 						iMainWindow;	// main window
+
+	TInt	 						iSampleStartTime;
+};
+
+
+
+/*
+*
+*  CWindow declaration
+*
+*/
+class CWindow : public CBase
+	{
+	protected:
+		RWindow iWindow; 	// window server window
+		TRect iRect; 		// rectangle re owning window
+	public:
+		CWindow(CWsClient* aClient);
+		void ConstructL (const TRect& aRect, CWindow* aParent=0);
+		~CWindow();
+		// access
+		RWindow& Window(); // our own window
+		CWindowGc* SystemGc(); // system graphics context
+
+		CWsClient* Client() {return iClient;};
+	private:
+		CWsClient* iClient; // client including session and group
+	};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/TouchEventAnimDll.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef _PROFILER_TOUCH_EVENT_ANIM_DLL_
+#define _PROFILER_TOUCH_EVENT_ANIM_DLL_
+
+/*
+*
+*	TouchEventAnimDll.h
+*
+*/
+
+// system includes
+#include <w32adll.h>
+#include <e32def.h>
+
+
+
+/*
+*
+* Class definition of CProfilerTouchEventAnim
+*
+*/
+class CProfilerTouchEventAnim : public CWindowAnim
+{
+public:
+	CProfilerTouchEventAnim();
+	virtual ~CProfilerTouchEventAnim();
+
+	// from CWindowAnim
+	void ConstructL(TAny*	aAny, TBool aHasFocus);
+	void Redraw();
+	void FocusChanged(TBool aState);
+	// from MEventHandler
+	TBool OfferRawEvent(const TRawEvent& aRawEvent);
+	// from CAnim
+	void Animate(TDateTime* aDateTime);
+	void Command(TInt aOpcode, TAny* aArgs);
+	TInt CommandReplyL(TInt aOpcode, TAny* aArgs);
+	
+private:
+	TBool HandlePointerDown(TPoint aPoint);
+	TBool HandlePointerUp(TPoint aPoint);
+	TBool HandleKeyDown(TInt aScanCode);
+	TBool HandleKeyUp(TInt aScanCode);
+private:
+	TInt iState;
+};
+
+
+/*
+*
+* Class definition of CProfilerTouchEventAnimDll
+*
+*/
+
+class CProfilerTouchEventAnimDll : public CAnimDll
+{
+public:
+	CProfilerTouchEventAnimDll();
+
+public:
+	 IMPORT_C CAnim* CreateInstanceL(TInt aType);
+	
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/TouchEventClientDll.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef _PROFILER_TOUCH_EVENT_CLIENT_DLL__
+#define _PROFILER_TOUCH_EVENT_CLIENT_DLL__
+
+#include <w32adll.h>
+
+class CProfilerTouchEventControl;
+
+class RProfilerTouchEventAnim : public RAnim
+{
+   public: 
+      RProfilerTouchEventAnim( RAnimDll& aAnimDll );
+      void ConstructL( const RWindow& aParent  );
+
+	  void Activate();
+	  void Deactivate();
+
+
+      enum KAnimCommands
+      {
+         KActivate       = 70002,
+         KDeactivate	 = 70003
+      };
+      /**
+       * Closes the animation object
+       */
+   	  void Close();
+
+   private:        
+	  CProfilerTouchEventControl* iTouchEventControl;   
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/sis/BupPlugin_S60-30.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,44 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; ShapeImplementation_30_gcce.pkg
+;
+
+;Language - standard language definitions
+&EN
+
+; standard sis file header
+#{"Shape plugin"},(0xE01F614F),2,0,0
+
+
+;
+;Localised Vendor name
+;
+%{"Forum Nokia"}
+
+;
+;Unique Vendor name
+;
+:"Forum Nokia"
+
+;
+;Supports Series 60 v 3.0
+;
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+
+;Files to include. Check the source paths they match your SDK setup. 
+"\Symbian\9.1\S60_3rd_MR\Epoc32\release\gcce\urel\shapeimplementation.dll"     -   "!:\sys\bin\shapeimplementation.dll"
+"\Symbian\9.1\S60_3rd_MR\epoc32\data\Z\Resource\plugins\shapeimplementation.rsc"   -   "!:\Resource\Plugins\shapeimplementation.RSC"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/BupPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,582 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+ 
+#include "BupPlugin.h"	
+//#include <piprofiler/EngineUIDs.h>
+
+#include <w32std.h> 	// for listening key events
+
+	
+// LITERALS
+// CONSTANTS
+const TUid KSamplerBupPluginUid = { 0x2001E5B6 };
+
+/*
+ *	
+ *	class CBupPlugin implementation
+ * 
+ */
+
+CBupPlugin* CBupPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+	{
+	LOGTEXT(_L("CBupPlugin::NewL() - entry"));
+    CBupPlugin* self = new (ELeave) CBupPlugin();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CBupPlugin::NewL() - exit"));
+    return self;
+	}
+
+CBupPlugin::CBupPlugin() :
+	iVersionDescriptor(&(this->iVersion[1]),0,19), 	
+	iSamplerType(PROFILER_USER_MODE_SAMPLER)
+	{
+	iSamplerId = PROFILER_BUP_SAMPLER_ID;
+    iEnabled = EFalse;
+	LOGTEXT(_L("CBupPlugin::CBupPlugin() - konstruktori"));
+	}
+
+void CBupPlugin::ConstructL() 
+	{
+	LOGTEXT(_L("CBupPlugin::ConstructL() - entry"));
+	
+	// initiate sampler attributes array
+	iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(1); // only one sampler
+	
+	// insert default attributes to array
+	InitiateSamplerAttributesL();
+	
+	LOGTEXT(_L("CBupPlugin::ConstructL() - exit"));
+	}
+
+
+CBupPlugin::~CBupPlugin()
+	{
+	LOGTEXT(_L("CBupPlugin::~CBupPlugin() - entry"));
+	if(iButtonListener)
+	    {
+	    // check if button listener still running
+	    if(Enabled())
+	        {
+	        // stop profiling
+	        iButtonListener->Stop();
+	        }
+        delete iButtonListener;
+	    }
+	
+	if(iSamplerAttributes)
+	    {
+	    iSamplerAttributes->Reset();
+	    }
+    delete iSamplerAttributes;
+	
+	LOGTEXT(_L("CBupPlugin::~CBupPlugin() - exit"));
+	}
+
+TUid CBupPlugin::Id(TInt /*aUid*/) const
+	{
+    LOGSTRING2("CBupPlugin::Id():0x%X", KSamplerBupPluginUid.iUid );
+    return KSamplerBupPluginUid;
+	}
+
+void CBupPlugin::InitiateSamplerAttributesL()
+    {
+    // create sampler attribute container
+    TSamplerAttributes attr(KSamplerBupPluginUid.iUid,
+            KBUPShortName(),
+            KBUPLongName(),
+            KBUPDescription(),
+            -1,
+            ETrue,
+            EFalse,
+            0); // default item count
+    this->iSamplerAttributes->AppendL(attr);
+    }
+
+// returns setting array
+void CBupPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    // append my own attributes to complete array, requested by profiler engine
+    aAttributes->AppendL(iSamplerAttributes->At(0));
+    }
+
+TInt CBupPlugin::SetAttributesL(TSamplerAttributes aAttributes)
+    {
+    TSamplerAttributes attr;
+
+    attr = iSamplerAttributes->At(0);
+    // if UIDs match replace the old 
+    if(attr.iUid == aAttributes.iUid)
+        {
+        // replace the old attribute container
+        iSamplerAttributes->Delete(0);
+        iSamplerAttributes->InsertL(0, aAttributes);
+        return KErrNone;
+        }
+    return KErrNotFound;
+    }
+
+/* 
+ * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
+ * called by CSamplerController class
+ * 
+ * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
+ */
+TInt CBupPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
+    {
+    // local literals
+    _LIT8(KBUPShort, "bup");
+
+    TInt err(KErrNone);
+    TBuf8<16> samplerSearchName;
+    samplerSearchName.Copy(KBUPShort);
+    
+    // get sampler specific settings  
+    err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, 0);
+    
+    // returns KErrNone if settings found, otherwise KErrNotFound
+    return err;
+    }
+
+TInt CBupPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
+    {
+    // 
+    TBuf8<16> samplerSearch;
+    samplerSearch.Copy(KBracketOpen);
+    samplerSearch.Append(aSamplerName);
+    samplerSearch.Append(KBracketClose);
+    
+    // read a line
+    for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
+        {
+        // check if this line has a setting block start, i.e. contains [xxx] in it
+        if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
+            {
+            // right settings block found, now loop until the next block is found
+            for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
+                {
+                // check if the next settings block was found
+                if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
+                    {
+                    // save found setting value directly to its owners attributes
+                    SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
+                    }
+                else
+                    {
+                    // next block found, return KErrNone
+                    return KErrNone;
+                    }
+                }
+            }
+        }
+    
+    return KErrNotFound;
+    }
+
+/**
+ * Method for setting a specific descriptor (from settings file) to attribute structure
+ * 
+ * @param aSetting  
+ * @param aName  
+ */
+void CBupPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
+    {
+    // find the equal mark from the setting line
+    TInt sepPos = aSetting.Find(KSettingItemSeparator);
+    // check that '=' is found
+    if (sepPos > 0)
+        {
+        // check that the element matches
+        if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
+            {
+            TBool en;
+            CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
+            if(iSamplerAttributes->At(aIndex).iEnabled != en)
+                {
+                iSamplerAttributes->At(aIndex).iEnabled = en;
+                }
+            }
+        }
+    }
+
+TInt CBupPlugin::GetSamplerType()
+	{
+	return iSamplerType;
+	}
+
+TInt CBupPlugin::ResetAndActivateL(CProfilerSampleStream& aStream) 
+	{
+	LOGTEXT(_L("CBupPlugin::ResetAndActivate() - entry"));
+	TInt ret(KErrNone);
+	
+	// check if sampler enabled
+	if(iSamplerAttributes->At(0).iEnabled)
+	    {
+        // create first the listener instance
+        iButtonListener = CProfilerButtonListener::NewL(this);
+        
+        LOGTEXT(_L("CBupPlugin::ResetAndActivate() - listener created"));
+        
+        iStream = &aStream;
+        TInt length = this->CreateFirstSample();
+        iVersion[0] = (TUint8)length;
+        LOGSTRING2("CBupPlugin::ResetAndActivate() - AddSample, length %d",length);
+        ret = AddSample(iVersion, length+1, 0);
+        if(ret != KErrNone)
+            return ret;
+        
+        // activate button listener
+        ret = iButtonListener->StartL();
+
+        iEnabled = ETrue;
+        
+        LOGTEXT(_L("CBupPlugin::ResetAndActivate() - exit"));
+	    }
+	return ret;
+
+	}
+	
+TInt CBupPlugin::CreateFirstSample()
+	{
+	LOGTEXT(_L("CBupPlugin::CreateFirstSample - entry"));
+	this->iVersionDescriptor.Zero();
+	this->iVersionDescriptor.Append(_L8("Bappea_BUP_V"));
+	this->iVersionDescriptor.Append(PROFILER_BUP_SAMPLER_VERSION);
+	LOGTEXT(_L("CBupPlugin::CreateFirstSample - exit"));
+	return (TInt)(this->iVersionDescriptor.Length());
+	}
+
+TInt CBupPlugin::StopSampling() 
+	{
+	if(iButtonListener)
+		{
+		iButtonListener->Stop();
+		delete iButtonListener;	// delete listener after every trace
+		iButtonListener = NULL;
+		}
+	
+    // set disabled
+    iEnabled = EFalse;
+
+	return KErrNone;
+	}
+
+void CBupPlugin::FillThisStreamBuffer(TBapBuf* /*aBapBuf*/, TRequestStatus& /*aStatus*/)
+	{
+	}
+
+/*
+ * 
+ * Implementation of class CProfilerButtonListener
+ * 
+ */
+CProfilerButtonListener::CProfilerButtonListener(CBupPlugin* aSampler) 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori"));
+	this->iSampler = aSampler;
+	iSampleStartTime = 0;
+	LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori exit"));
+	}
+
+CProfilerButtonListener* CProfilerButtonListener::NewL(CBupPlugin* aSampler)
+	{
+	LOGTEXT(_L("CProfilerButtonListener::NewL() - entry"));
+	CProfilerButtonListener* self = new (ELeave) CProfilerButtonListener(aSampler);
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop();
+	LOGTEXT(_L("CProfilerButtonListener::NewL() - exit"));
+	return self;
+	}
+
+CProfilerButtonListener::~CProfilerButtonListener() 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - entry af"));
+
+	if(iMainWindow)
+		{
+		LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): flushing iWs"));
+		iWs.Flush();
+		LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): finishing"));
+		}
+	delete iMainWindow;
+	LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - exit"));
+	}
+	
+void CProfilerButtonListener::ConstructMainWindowL()
+	{
+    LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Entry"));
+
+    CWindow* window = new (ELeave) CWindow(this);
+    CleanupStack::PushL( window );
+	window->ConstructL(TRect(TPoint(0,0), TSize(0,0)));
+    delete iMainWindow;
+    iMainWindow = window;
+    CleanupStack::Pop( window );
+	
+    LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Exit"));
+	}
+
+void CProfilerButtonListener::HandleKeyEventL (TKeyEvent& /*aKeyEvent*/)
+    {
+    LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - Start"));
+    LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - End"));
+	}
+
+
+TInt CProfilerButtonListener::RunError(TInt aError)
+    {
+    // get rid of everything we allocated
+    // deactivate the anim dll before killing window, otherwise anim dll dies too early
+    iAnim->Deactivate();
+    iAnim->Close();
+
+    iAnimDll->Close();
+    
+    return aError;
+    }
+
+void CProfilerButtonListener::RunL() 
+	{	
+    // resubscribe before processing new value to prevent missing updates
+	IssueRequest();
+	
+	TInt c = 0;
+	if(RProperty::Get(KProfilerKeyEventPropertyCat, EProfilerKeyEventPropertySample, c) == KErrNone)
+		{
+		// do something with event
+		LOGSTRING2("CProfilerButtonListener::RunL() - event [%d] received",c);
+	
+		iSample[0] = c;
+		iSample[1] = c >> 8;
+		iSample[2] = c >> 16;
+		iSample[3] = c >> 24;
+		
+		// Space for GPP sample time		
+		TUint32 sampleTime = User::NTickCount() - iSampleStartTime; 
+		LOGSTRING2("CProfilerButtonListener::RunL() - sample time is %d",sampleTime);
+		
+		iSample[4] = sampleTime;
+		iSample[5] = sampleTime >> 8;
+		iSample[6] = sampleTime >> 16;
+		iSample[7] = sampleTime >> 24;
+		
+		iSampler->AddSample(iSample, 8, 0xb0);
+		}
+	}
+	
+TInt CProfilerButtonListener::StartL()
+	{
+	LOGTEXT(_L("CProfilerButtonListener::StartL() - Activate touch server dll"));
+	TInt err(KErrNone);
+	
+	// get the property value
+	TInt r = RProperty::Get(KGppPropertyCat, EGppPropertySyncSampleNumber, iSampleStartTime);
+	if(r != KErrNone)
+		{
+		LOGSTRING2("CProfilerButtonListener::StartL() - getting iSyncOffset failed, error %d", r);
+		}
+	
+	iAnimDll = new (ELeave) RAnimDll(iWs);
+	LOGTEXT(_L("CProfilerButtonListener::StartL() - #1"));
+	
+	TParse* fp = new (ELeave) TParse();
+	CleanupStack::PushL(fp);
+	fp->Set( KDllName, &KDC_SHARED_LIB_DIR , NULL );    
+	LOGSTRING2("CProfilerButtonListener::StartL() - touch event server: %S" , &(fp->FullName()));
+
+	err = iAnimDll->Load(fp->FullName());
+	// check if anim dll load failed
+	if(err != KErrNone)
+	    {
+        CleanupStack::PopAndDestroy(fp);
+	    // stop plugin if failed
+	    iAnimDll->Close();
+	    return KErrGeneral;
+	    }
+    CleanupStack::PopAndDestroy(fp);
+ 	LOGTEXT(_L("CProfilerButtonListener::StartL() - #2"));
+
+	iAnim = new (ELeave) RProfilerTouchEventAnim(*iAnimDll);
+ 	LOGTEXT(_L("CProfilerButtonListener::StartL() - #3"));
+	iAnim->ConstructL(iMainWindow->Window());
+	
+	// activate the animation dll for collecting touch and key events
+	iAnim->Activate();
+
+	// wait for a new sample
+	IssueRequest();
+	
+	// hide this window group from the app switcher
+	iMainWindow->Client()->Group().SetOrdinalPosition(-1);
+	iMainWindow->Client()->Group().EnableReceiptOfFocus(EFalse);
+	return KErrNone;
+	}
+
+TInt CProfilerButtonListener::Stop() 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::Stop() - enter"));
+	// deactivate the anim dll before killing window, otherwise anim dll dies too early
+	iAnim->Deactivate();
+	iAnim->Close();
+
+	iAnimDll->Close();
+
+	Cancel();
+	LOGTEXT(_L("CProfilerButtonListener::Stop() - exit"));
+	return KErrNone;
+	}
+
+
+///////////////////////////////////////////////////////////////////////////////
+////////////////////////// CWindow implementation /////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CWindow::CWindow(CWsClient* aClient)
+: iClient(aClient)
+	{
+    LOGTEXT(_L("CWindow::CWindow()"));
+	}
+
+void CWindow::ConstructL (const TRect& aRect, CWindow* aParent)
+	{
+	LOGTEXT(_L("CWindow::ConstructL(): Start"));
+
+	// If a parent window was specified, use it; if not, use the window group
+	// (aParent defaults to 0).
+	RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
+	iWindow=RWindow(iClient->iWs); // use app's session to window server
+	User::LeaveIfError(iWindow.Construct(*parent,(TUint32)this));
+	LOGSTRING2("CWindow::ConstructL(): Start - window handle is: 0x%08x", this);
+	iRect = aRect;
+	iWindow.SetExtent(iRect.iTl, iRect.Size()); // set extent relative to group coords
+	iWindow.Activate(); // window is now active
+	LOGTEXT(_L("CWindow::ConstructL(): End"));
+	}
+
+
+CWindow::~CWindow()
+	{
+    LOGTEXT(_L("CWindow::~CWindow(): Start"));
+	iWindow.Close(); // close our window
+    LOGTEXT(_L("CWindow::~CWindow(): End"));
+	}
+
+RWindow& CWindow::Window()
+	{
+    LOGTEXT(_L("CWindow::Window()"));
+	return iWindow;
+	}
+
+CWindowGc* CWindow::SystemGc()
+	{
+    LOGTEXT(_L("CWindow::SystemGc()"));
+	return iClient->iGc;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// CWsClient implementation ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+CWsClient::CWsClient()
+: CActive(CActive::EPriorityStandard)
+	{
+    LOGTEXT(_L("CWsClient::CWsClient()"));
+	}
+
+void CWsClient::ConstructL()
+	{
+    LOGTEXT(_L("CWsClient::ConstructL() - Start"));
+    TInt r = RProperty::Define(EProfilerKeyEventPropertySample, RProperty::EInt, KAllowAllPolicy, KCapabilityNone);
+    if (r!=KErrAlreadyExists)
+        {
+        User::LeaveIfError(r);
+        }
+    
+	CActiveScheduler::Add(this);
+
+	// attach to 
+	User::LeaveIfError(iProperty.Attach(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample));
+    
+	// get a session going
+	User::LeaveIfError(iWs.Connect());
+
+	// construct screen device and graphics context
+	iScreen=new (ELeave) CWsScreenDevice(iWs); // make device for this session
+	User::LeaveIfError(iScreen->Construct( 0 )); // and complete its construction
+	User::LeaveIfError(iScreen->CreateContext(iGc)); // create graphics context
+
+	// construct our one and only window group
+	iGroup=RWindowGroup(iWs);
+	User::LeaveIfError(iGroup.Construct((TInt)this, EFalse)); // meaningless handle; enable focus
+	
+	// construct main window
+	ConstructMainWindowL();
+
+	LOGTEXT(_L("CWsClient::CWsClient() - End"));
+	}
+
+CWsClient::~CWsClient()
+	{
+    LOGTEXT(_L("CWsClient::~CWsClient() - Start"));
+    
+	// get rid of everything we allocated
+	delete iGc;
+	delete iScreen;
+	
+	iGroup.Close();
+	// finish with window server
+	iWs.Close();
+	
+    LOGTEXT(_L("CWsClient::~CWsClient() - Exit"));
+	}
+
+void CWsClient::Exit()
+	{
+    LOGTEXT(_L("CWsClient::Exit() - Start"));
+
+	// destroy window group
+	iGroup.Close();
+	// finish with window server
+    iProperty.Close();
+	iWs.Close();
+    LOGTEXT(_L("CWsClient::Exit() - Exit"));
+	}
+
+void CWsClient::IssueRequest()
+	{
+    LOGTEXT(_L("CWsClient::IssueRequest() - Start"));
+    iProperty.Subscribe( iStatus );
+    SetActive(); // so we're now active
+    LOGTEXT(_L("CWsClient::IssueRequest() - Exit"));
+	}
+
+void CWsClient::DoCancel()
+	{
+    LOGTEXT(_L("CWsClient::DoCancel() - Start"));
+	// clean up the sample property
+    iProperty.Cancel();
+    iProperty.Close();
+    LOGTEXT(_L("CWsClient::DoCancel() - Exit"));
+	}
+
+void CWsClient::ConstructMainWindowL()
+	{
+    LOGTEXT(_L("CWsClient::ConstructMainWindowL()"));
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/BupPluginImplementationTable.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "BupPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+         IMPLEMENTATION_PROXY_ENTRY(0x2001E5B6,  CBupPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/TouchEventAnimDll.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <w32std.h>
+#include <in_sock.h>
+#include <txtfrmat.h>
+#include <e32property.h>
+#include <piprofiler/ProfilerTraces.h>
+
+// user includes
+#include "TouchEventAnimDll.h"
+
+// control commands
+static const TInt KActivate   = 70002;
+static const TInt KDeactivate = 70003;
+
+// touch events
+static const TInt KTouchEventDown = 69999;
+static const TInt KTouchEventUp = 70000;
+
+static const TInt KUpEventOffset = 70000;
+
+_LIT( KTouchEventServer, "PIProfilerTouchEvent server" );
+enum TAnimationPanics
+    {
+    EProfilerTouchEventServerPanic = 100
+    };
+
+const TUid KProfilerKeyEventPropertyCat={0x2001E5AD};
+enum TProfilerKeyEventPropertyKeys
+	{
+	EProfilerKeyEventPropertySample = 7
+	};
+
+/*
+*
+* Implementation of CProfilerTouchEventAnim
+*
+*/
+CProfilerTouchEventAnim::CProfilerTouchEventAnim() : iState(EFalse)
+    {
+	LOGTEXT(_L("CProfilerTouchEventAnim::CProfilerTouchEventAnim - entry"));
+    }
+
+CProfilerTouchEventAnim::~CProfilerTouchEventAnim()
+    {
+	LOGTEXT(_L("CProfilerTouchEventAnim::~CProfilerTouchEventAnim - entry"));
+	//iFunctions->GetRawEvents( EFalse );	// disable capture
+	LOGTEXT(_L("CProfilerTouchEventAnim::~CProfilerTouchEventAnim - exit"));
+    }
+
+void CProfilerTouchEventAnim::ConstructL(TAny* /*aArgs*/, TBool /*aHasFocus*/)
+    {
+	LOGTEXT(_L("CProfilerTouchEventAnim::ConstructL - entry"));
+    iFunctions->GetRawEvents( ETrue );
+	LOGTEXT(_L("CProfilerTouchEventAnim::ConstructL - exit"));
+    }
+
+void CProfilerTouchEventAnim::Command(TInt /*aOpcode*/, TAny* /*aArgs*/)
+    {
+
+    }
+
+TInt CProfilerTouchEventAnim::CommandReplyL(TInt aOpcode, TAny* /*aArgs*/)
+    {
+	LOGSTRING2("CProfilerTouchEventAnim::CommandReplyL - entry, aOpcode: %d", aOpcode);
+	switch(aOpcode)
+	    {
+		case KActivate:	// activate
+			iState = ETrue;
+			LOGTEXT(_L("CProfilerTouchEventAnim::CommandReplyL - activate"));
+			break;
+		case KDeactivate: // deactivate
+			iState = EFalse;
+			iFunctions->GetRawEvents( EFalse );	// disable capture
+			LOGTEXT(_L("CProfilerTouchEventAnim::CommandReplyL - deactivate"));
+			break;
+		default:
+			User::Panic( KTouchEventServer, EProfilerTouchEventServerPanic );
+			LOGSTRING2("CProfilerTouchEventAnim::CommandReplyL - panic, code %d", EProfilerTouchEventServerPanic);
+			return EProfilerTouchEventServerPanic;
+
+        }
+	return KErrNone;
+    }
+
+
+TBool CProfilerTouchEventAnim::OfferRawEvent(const TRawEvent& aRawEvent)
+    {
+	LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - entry"));
+	if(iState == EFalse)
+		return EFalse; // if not activated yet just pass through
+	
+
+	switch(aRawEvent.Type())
+	    {
+        // handle the pointer events here
+        case TRawEvent::EButton1Down:
+            {
+            LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - pointer down"));
+            return HandlePointerDown(aRawEvent.Pos());
+            }
+        case TRawEvent::EButton1Up:
+            {
+            LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - pointer up"));
+            return HandlePointerUp(aRawEvent.Pos());
+            }
+                
+            // handle the key events here, replacing the BUP trace functionality
+        case TRawEvent::EKeyDown:
+            {
+            TInt scan = aRawEvent.ScanCode() & 0xFFFF;
+                    return HandleKeyDown(scan);
+            }
+        case TRawEvent::EKeyUp:
+            {
+            TInt scan = (aRawEvent.ScanCode() & 0xFFFF)+KUpEventOffset;	// 
+                    return HandleKeyUp(scan);
+            }
+            default:
+                return EFalse;	// no action
+        }
+    }
+
+TBool CProfilerTouchEventAnim::HandlePointerDown( TPoint /*aPoint*/ )
+    {
+	RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, KTouchEventDown);
+	return EFalse;
+    }
+
+TBool CProfilerTouchEventAnim::HandlePointerUp( TPoint /*aPoint*/ )
+    {
+	RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, KTouchEventUp);
+	return EFalse;
+    }
+
+TBool CProfilerTouchEventAnim::HandleKeyDown( TInt aScanCode )
+    {
+	LOGSTRING2("CProfilerTouchEventAnim::HandleKeyDown - scancode = %d", aScanCode);
+	RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, aScanCode);
+	return EFalse;
+    }
+
+TBool CProfilerTouchEventAnim::HandleKeyUp( TInt aScanCode )
+    {
+	LOGSTRING2("CProfilerTouchEventAnim::HandleKeyUp - scancode = %d", aScanCode);
+	RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, aScanCode);
+	return EFalse;
+    }
+
+
+void CProfilerTouchEventAnim::Animate(TDateTime* /*aDateTime*/)
+    {
+    }
+
+void CProfilerTouchEventAnim::Redraw()
+    {
+    }
+
+void CProfilerTouchEventAnim::FocusChanged(TBool /*aState*/)
+    {
+    }
+
+
+/*
+*
+* Implementation of CProfilerTouchEventAnimDll
+*
+*/
+CProfilerTouchEventAnimDll::CProfilerTouchEventAnimDll() : CAnimDll()
+    {
+    }
+
+CAnim* CProfilerTouchEventAnimDll::CreateInstanceL(TInt /*aType*/)
+    {
+	LOGTEXT(_L("CProfilerTouchEventAnimDll::CreateInstanceL - entry"));
+	return (new (ELeave) CProfilerTouchEventAnim());
+    }
+
+
+// DLL entry
+EXPORT_C CAnimDll* CreateCAnimDllL()
+    {
+	return (new (ELeave) CProfilerTouchEventAnimDll);
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/TouchEventClientDll.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include "TouchEventClientDll.h"
+#include <piprofiler/ProfilerTraces.h>
+
+/*
+ *	
+ *	class RProfilerTouchEventAnim implementation
+ * 
+ */
+void RProfilerTouchEventAnim::ConstructL( const RWindow& aParent)
+{
+	LOGTEXT(_L("RProfilerTouchEventAnim::ConstructL - entry"));
+	LOGTEXT(_L("RProfilerTouchEventAnim::ConstructL - calling RAnim::Construct..."));
+	RAnim::Construct(aParent, 0, TPtrC8());
+}
+
+
+RProfilerTouchEventAnim::RProfilerTouchEventAnim( RAnimDll &aAnimDll ) :
+    RAnim( aAnimDll )
+{
+}
+
+void RProfilerTouchEventAnim::Activate()
+{
+	LOGTEXT(_L("RProfilerTouchEventAnim::Activate - entry"));
+	TInt err = RAnim::CommandReply(KActivate);
+	LOGSTRING2("RProfilerTouchEventAnim::Activate - error: %d", err);
+}
+
+void RProfilerTouchEventAnim::Deactivate()
+{
+	LOGTEXT(_L("RProfilerTouchEventAnim::Deactivate - entry"));
+	TInt err = RAnim::CommandReply(KDeactivate);
+	LOGSTRING2("RProfilerTouchEventAnim::Deactivate - error: %d", err);
+}
+
+void RProfilerTouchEventAnim::Close()
+	{
+	RAnim::Close();
+	}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/data/2001E5BA.rss	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+ 
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL. See mmp files
+    //__SERIES60_3X__ can't be used in resource files
+    dll_uid = 0x2001E5BA;
+
+    // Declare array of interface info. This dll contains implementations for 
+    // only one interface (CSamplerInterfaceDefinition).
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = 0x2001E5BD;
+
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = 0x2001E5BA;
+
+                    version_no = 1;
+                    display_name = "Debug output writer implementation";
+                    default_data = "dow";
+                    opaque_data = "1";
+                    }
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/group/DebOutWriterPlugin.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET		    PIProfilerDebugWriter.dll
+TARGETTYPE	    PLUGIN
+UID             0x10009D8D 0x2001E5BA
+#ifdef WINSCW
+VENDORID      0
+#else
+VENDORID      VID_DEFAULT
+#endif
+CAPABILITY 	    ALL -TCB // AllFiles ReadDeviceData ReadUserData UserEnvironment WriteDeviceData WriteUserData
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE 	../inc ../traces 
+#ifdef OST_TRACE_COMPILER_IN_USE
+USERINCLUDE 	../traces
+#endif
+SOURCEPATH		../src
+
+START RESOURCE  ../data/2001E5BA.rss
+TARGET piprofilerdebugwriter.rsc
+END
+
+SOURCE			DebOutWriterPlugin.cpp
+SOURCE 			DebOutWriterPluginImplementationTable.cpp
+
+LIBRARY		    euser.lib
+LIBRARY         ECom.lib
+LIBRARY         EFSRV.LIB
+LIBRARY         commonengine.lib
+LIBRARY			flogger.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+PRJ_MMPFILES
+DebOutWriterPlugin.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/inc/DebOutWriterPlugin.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// This file defines the API for DebOutWriterPlugin.dll
+
+#ifndef __DEBOUTWRITERPLUGIN_H__
+#define __DEBOUTWRITERPLUGIN_H__
+
+//  Include Files
+#include <w32std.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <e32base.h>	// CBase
+#include <e32std.h>	 // TBuf
+#include <e32property.h>
+
+#ifdef OST_TRACE_COMPILER_IN_USE
+// trace core ldd activation/deactivation interface
+#include <TcDriverIf.h>
+
+// trace core ldd global definitions
+_LIT( KTcLdd, "tcldd.ldd" );
+GLDEF_D RTcDriver tcldd;
+
+#endif
+
+_LIT(KDebOutShortName, "dow");
+
+// forward declarations
+class CDebOutWriterHandler;
+
+//  Class Definitions
+
+class CDebOutWriterPlugin : public CWriterPluginInterface
+	{
+public:
+	// new function
+	static CDebOutWriterPlugin* NewL(const TUid aImplementationUid, TAny* /*aInitParams*/);
+	~CDebOutWriterPlugin();
+
+	void	DoCancel();
+	static void 	PrintDescriptorAsBase64(TDesC8& aDes, TRequestStatus* aStatus, TUint32 sampleTime, TBool aEmptying);
+
+public: // new functions
+
+	TInt 	Start();
+
+	void 	Stop();
+    
+	void 	GetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+	
+	void 	SetValue( const TWriterPluginValueKeys aKey, TDes& aValue ); 
+    
+	TUid 	Id() const;
+		 
+	void 	GetWriterVersion(TDes* aDes);
+	
+	TUint32 GetWriterType();
+	
+	void    SetStream(CProfilerSampleStream& aStream) { iStream = &aStream; }
+	
+	void   HandleError(TInt aError);
+	   
+	void   WriteData();
+private: // new functions
+	CDebOutWriterPlugin(const TUid aImplementationUid);
+	void 	ConstructL();
+	
+	void 	GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+	void 	SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+	TBool	GetEnabled();
+public:
+    CProfilerSampleStream*          iStream;
+private: // data
+	TBapBuf*						iBufferBeingWritten;
+	
+	TInt 							iWriterType;
+	TInt							iWriterId;
+	CDebOutWriterHandler*			iWriterHandler;
+	RProperty                       iErrorStatus;
+
+	};
+
+/*
+ * 
+ * Definition of class CDebOutWriterHandler
+ * 
+ */
+class CDebOutWriterHandler : public CActive
+	{
+public:
+ 
+
+	static CDebOutWriterHandler* NewL(CDebOutWriterPlugin* aWriter);
+	~CDebOutWriterHandler();
+    void DoCancel();
+	void StartL();
+
+	void Stop();
+    
+    void Reset();
+private:
+	CDebOutWriterHandler(CDebOutWriterPlugin* aWriter); 
+	
+	void ConstructL();
+    void RunL();
+    
+	void WriteBufferToOutput(TBapBuf* aBuf);
+	void PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus);
+	void HandleFullBuffers();
+private:
+	CDebOutWriterPlugin* 			iWriter;
+    RFile                           iFile;
+    RFs                             iFs;
+    TBuf<256>                       iFileName;
+//  CPeriodic*                      iTimer;
+    TBapBuf*                        iBufferBeingWritten;
+    TBool                           iStopping;
+	};
+
+#endif  // __DEBOUTWRITERPLUGIN_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/sis/DebOutWriterPlugin_EKA2.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for DebOutWriterPlugin dll
+;
+; This is an auto-generated PKG file by Carbide.
+; This file uses variables specific to Carbide builds that will not work
+; on command-line builds. If you want to use this generated PKG file from the
+; command-line tools you will need to modify the variables with the appropriate
+; values: $(EPOCROOT), $(PLATFORM), $(TARGET)
+
+;
+; UID is the dll's UID
+;
+#{"DebOutWriterPlugin DLL"},(0x00DA58C7),1,0,0
+
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\DebOutWriterPlugin.dll"		  -"!:\sys\bin\DebOutWriterPlugin.dll"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+//  Include Files  
+
+#include "DebOutWriterPlugin.h"	
+#include <e32base.h>
+//#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include <OpenSystemTrace.h>
+#include "DebOutWriterPluginTraces.h"
+#endif
+
+// engine properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+    {
+    EProfilerEngineStatus = 8,
+    EProfilerErrorStatus
+    };
+
+// CONSTANTS
+// own UID
+const TUid KDebOutWriterPluginUid = { 0x2001E5BA };
+
+//  Member Functions
+/*
+ *
+ *	Class CDebOutWriterPlugin implementation
+ *
+ */
+
+CDebOutWriterPlugin* CDebOutWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::NewL() - entry"));
+	CDebOutWriterPlugin* self = new (ELeave) CDebOutWriterPlugin(KDebOutWriterPluginUid);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDebOutWriterPlugin::NewL() - exit"));
+    return self;
+}
+
+CDebOutWriterPlugin::CDebOutWriterPlugin(const TUid aImplementationUid) :
+	iWriterType(aImplementationUid.iUid)
+    {
+    LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - entry"));
+    isEnabled = EFalse;
+    iWriterId = Id().iUid;
+    LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - exit"));
+    }
+
+CDebOutWriterPlugin::~CDebOutWriterPlugin()
+    {
+    LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - entry"));
+
+    iErrorStatus.Close();
+    
+    if(iWriterHandler)
+        {
+        iWriterHandler->Cancel();
+        delete iWriterHandler;
+        }
+    LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - exit"));
+    }    
+    
+void CDebOutWriterPlugin::ConstructL()
+	{
+	// second phase constructor, anything that may leave must be constructed here
+
+	LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - entry"));
+	iWriterHandler = CDebOutWriterHandler::NewL(this);
+    User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+    
+	LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - exit"));
+	}
+
+TInt CDebOutWriterPlugin::Start()
+	{
+	LOGTEXT(_L("CDebOutWriterPlugin::Start() - entry"));
+	
+#ifdef OST_TRACE_COMPILER_IN_USE
+    TInt err(KErrNone);
+	// activate traces on TraceCore
+    RTcDriverParameters tcdp_ThreadIdentification;
+    tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    RDebug::Print(_L("Debug output activated"));
+    if(err != KErrNone)
+        RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+
+	LOGTEXT(_L("CDebOutWriterPlugin::Start() - exit"));
+	return KErrNone;
+	}
+
+void CDebOutWriterPlugin::Stop()
+	{
+	LOGTEXT(_L("CDebOutWriterPlugin::Stop() - entry"));
+	iWriterHandler->Stop();
+#ifdef OST_TRACE_COMPILER_IN_USE
+	TInt err(KErrNone);
+    // activate traces on TraceCore
+    RTcDriverParameters tcdp_ThreadIdentification;
+    tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    RDebug::Print(_L("Debug output deactivated"));
+    if(err != KErrNone)
+        RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+	LOGTEXT(_L("CDebOutWriterPlugin::Stop() - exit"));
+	}
+
+TUid CDebOutWriterPlugin::Id() const
+	{
+    LOGSTRING2("CDebOutWriterPlugin::Id(): 0x%X", KDebOutWriterPluginUid.iUid );
+    return KDebOutWriterPluginUid;
+	//return iDtor_ID_Key;
+	}
+
+TBool CDebOutWriterPlugin::GetEnabled()
+	{
+	return isEnabled;
+	}
+
+void CDebOutWriterPlugin::SetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( SetValueL( aKey, aValue ) );
+    }
+
+
+void CDebOutWriterPlugin::GetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( GetValueL( aKey, aValue ) );
+    }
+
+
+
+void CDebOutWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& /*aValue*/ )
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - entry"));	
+	
+    switch( aKey )
+        {
+        case EWriterPluginEnabled:
+            isEnabled = ETrue;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled"));
+        	break;
+        case EWriterPluginDisabled:
+            isEnabled = EFalse;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled"));	
+            break;
+        case EWriterPluginSettings:
+        	//result = StringLoader::LoadL(PROFILER_KERNEL_MODE_SAMPLER);
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - setting plugin settings"));	
+        	break;
+        default:
+        	break;
+        }
+	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - exit"));	
+
+}
+
+TUint32 CDebOutWriterPlugin::GetWriterType()
+	{
+	return iWriterType;
+	}
+
+
+void CDebOutWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+    {
+    switch( aKey )
+        {
+        case EWriterPluginVersion:
+
+        	GetWriterVersion(&aValue);
+        	break;
+        case EWriterPluginType:
+        	break;
+           default:
+                break;
+        }
+    }
+
+void CDebOutWriterPlugin::GetWriterVersion(TDes* aDes)
+	{
+	_LIT(KDebugOutputWriterVersion, "1.0.0");
+	aDes->Append(KDebugOutputWriterVersion);
+	}
+
+void CDebOutWriterPlugin::DoCancel()
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry"));
+}
+
+void CDebOutWriterPlugin::WriteData()
+    {
+    // Activate handler to write data from buffer to output
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry"));
+    TRAP_IGNORE(iWriterHandler->StartL());
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit"));
+    }
+
+void CDebOutWriterPlugin::HandleError(TInt aError)
+    {
+    TInt err(KErrNone);
+    err = iErrorStatus.Set(aError);
+    if(err != KErrNone)
+        {
+        RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error: %d"), err);
+        }
+    }
+
+void CDebOutWriterPlugin::PrintDescriptorAsBase64(	TDesC8& aDes,
+                                                    TRequestStatus* aStatus,
+													TUint32 sampleTime,
+													TBool aEmptying)
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - entry"));
+	TUint len = aDes.Length();
+
+	// we must wait for the sample tick to be printed, in case
+	// prints are performed at user side, otherwise the kernel
+	// prints will corrupt the data
+	if(sampleTime != 0xffffffff)
+	{
+		TUint32 remains = sampleTime%1000;
+	
+		if(remains > 800) 
+		{
+			TTimeIntervalMicroSeconds32 timeToWait = ((1050-remains)*1000);
+			User::After(timeToWait);
+		}
+	}
+	
+	TBuf16<75> buf;
+
+	// Header
+#ifdef OST_TRACE_COMPILER_IN_USE
+    OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START, 
+            "<PIPROF>=================================================================" );
+#else
+	RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+	buf.Zero();
+
+	// base64 encoding table
+	const char uu_base64[64] =
+	{
+		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+		'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+		'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+		'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+		'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+		'w', 'x', 'y', 'z', '0', '1', '2', '3',
+		'4', '5', '6', '7', '8', '9', '+', '/'
+	};
+
+	TChar byte1, byte2, byte3, byte4;
+	TUint8 count = 0x30;
+	// base64 encoding 
+	for(TUint i = 0, j = 0; i < len; i += 3, j = (j + 1) % 18) 
+	{
+    // byte 1
+		byte1 = uu_base64[(aDes[i] >> 2) & 0x3F];
+		
+		// byte 2
+		if(i+1 < len)
+			byte2 = uu_base64[(aDes[i] << 4) & 0x3f | (aDes[i+1] >> 4)];
+		else
+			byte2 = uu_base64[(aDes[i] << 4) & 0x3f];
+
+		// byte 3
+		if(i+1 < len && i+2 < len)
+			byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f | (aDes[i+2] >> 6)];
+		else if(i+1 < len)
+			byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f];
+		else
+			byte3 = '=';
+
+		// byte 4
+		if(i+2 < len) 
+			byte4 = uu_base64[aDes[i+2] & 0x3f];
+		else
+			byte4 = '=';
+	
+		// append to buffer
+		buf.Append(byte1);
+		buf.Append(byte2);
+		buf.Append(byte3);
+		buf.Append(byte4);
+
+		// output 72 chars / line
+		if(j == 17) 
+		{		
+			// add check number at the end of line
+			buf.Append(count);
+#ifdef OST_TRACE_COMPILER_IN_USE
+			OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE, "<PIPROF>%S", &buf );
+#else
+			RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+			count++;
+			if(count > 0x39)
+				count = 0x30;
+			buf.Zero();
+		}
+	}
+	
+#ifdef OST_TRACE_COMPILER_IN_USE
+	OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN, "<PIPROF>%S", &buf );
+#else
+	RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+	buf.Zero();
+
+	// footer
+#ifdef OST_TRACE_COMPILER_IN_USE
+	OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END, 
+	        "<PIPROF>=================================================================" );
+#else
+	RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+
+	if(!aEmptying)
+	    {
+        if(aStatus != 0) 
+            User::RequestComplete(aStatus,0);
+	    }
+	
+	LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - exit"));
+}
+
+
+
+/*
+ * 
+ * Implementation of class CDebOutWriterHandler
+ * 
+ */
+CDebOutWriterHandler::CDebOutWriterHandler(CDebOutWriterPlugin* aWriter) :
+    CActive(EPriorityStandard)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - entry"));
+    iWriter = aWriter;
+    
+    // set initial mode to non-stopping
+    iStopping = EFalse;
+    
+    // add the handler to the active scheduler
+    CActiveScheduler::Add(this);
+    LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - exit"));
+    }
+
+CDebOutWriterHandler* CDebOutWriterHandler::NewL(CDebOutWriterPlugin* aWriter)
+{
+	LOGTEXT(_L("CDebOutWriterHandler::NewL() - entry"));
+	CDebOutWriterHandler* self = new (ELeave) CDebOutWriterHandler(aWriter);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDebOutWriterHandler::NewL() - exit"));
+    return self;
+}
+
+CDebOutWriterHandler::~CDebOutWriterHandler()
+    {
+	LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - entry"));
+    
+    LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - exit"));
+    }    
+    
+void CDebOutWriterHandler::ConstructL()
+	{
+
+	}
+
+void CDebOutWriterHandler::StartL()
+	{
+	LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+    if(!IsActive())
+        {
+        LOGTEXT(_L("CDiskWriterHandler::StartL - is not active"));
+    
+        TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf);
+    
+        if(nextBuf != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file"));
+            WriteBufferToOutput(nextBuf);
+            }
+        }
+	LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+	}
+
+void CDebOutWriterHandler::Stop()
+	{
+	LOGTEXT(_L("CDebOutWriterHandler::Stop - entry"));
+   
+	// do write once more to write the logged data to output
+    // set to stopping mode, needed for emptying the remaining full buffers
+    iStopping = ETrue;
+
+    // stop the timer
+    Reset();
+
+    // set mode back to non-stopping
+    iStopping = EFalse;
+	LOGTEXT(_L("CDebOutWriterHandler::Stop - exit"));
+	}
+
+void CDebOutWriterHandler::Reset()
+    {
+  
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+    
+    // empty the rest of the buffers synchronously
+    while(nextBuf != 0)
+        {
+        if(nextBuf->iDataSize != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+            iWriter->PrintDescriptorAsBase64(*(nextBuf->iBufDes),&iStatus,0xffffffff, iStopping);
+            }
+        
+        // empty buffers when profiling stopped
+        iWriter->iStream->AddToFreeBuffers(nextBuf);
+
+        LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer"));
+        // start writing new buffer if there is one available
+        nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf);
+        }
+    }
+
+void CDebOutWriterHandler::HandleFullBuffers()
+    {
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry"));
+    // previous write operation has finished
+    // release the previous buffer 
+    iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten);
+
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer"));
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+    if(nextBuf != 0)
+        {
+        LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file"));
+        if(nextBuf->iDataSize != 0)
+            {
+            WriteBufferToOutput(nextBuf);
+            }
+        } 
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit"));
+    }
+
+void CDebOutWriterHandler::RunL()
+    {
+    // call function to complete full buffer handling
+    HandleFullBuffers();
+    }
+
+void CDebOutWriterHandler::DoCancel()
+    {
+    
+    }
+
+void CDebOutWriterHandler::WriteBufferToOutput(TBapBuf* aBuf)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - entry"));
+    iBufferBeingWritten = aBuf;
+
+    // set the data length just to be sure
+    iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize);
+
+    LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file"));
+//    PrintBufferToOutput(iBufferBeingWritten, iStatus);
+    iWriter->PrintDescriptorAsBase64(*(iBufferBeingWritten->iBufDes),&iStatus,0xffffffff, iStopping);
+    // set AO back to active, until filled buffers are emptied 
+    SetActive();
+    
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - exit"));
+    }
+
+// private
+void CDebOutWriterHandler::PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput() - debug out writer tick activated"));
+
+    TPtrC8& aDes = (TPtrC8&)*(aBuffer->iBufDes);
+#ifdef BAPPEA_SAMPLE_MARKS
+    TUint32 time = iSampler->GetSampleTime();
+#else
+    TUint32 time = 0xffffffff;
+#endif
+    iWriter->PrintDescriptorAsBase64(aDes,&aStatus,time, iStopping);
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPluginImplementationTable.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "DebOutWriterPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+         IMPLEMENTATION_PROXY_ENTRY(0x2001E5BA,  CDebOutWriterPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/data/2001E5BB.rss	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL. See mmp files
+    //__SERIES60_3X__ can't be used in resource files
+    dll_uid = 0x2001E5BB;
+
+    // Declare array of interface info. This dll contains implementations for 
+    // only one interface (CSamplerInterfaceDefinition).
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = 0x2001E5BD;
+
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = 0x2001E5BB;
+
+                    version_no = 1;
+                    display_name = "Disk output writer implementation";
+                    default_data = "dsw";
+                    opaque_data = "0";
+                    }
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/group/DiskWriterPlugin.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET        PIProfilerDiskWriter.dll
+TARGETTYPE    PLUGIN
+UID           0x10009D8D 0x2001E5BB
+#ifdef WINSCW
+VENDORID      0
+#else
+VENDORID      VID_DEFAULT
+#endif
+CAPABILITY    ALL -TCB // AllFiles ReadDeviceData ReadUserData UserEnvironment WriteDeviceData WriteUserData
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE     ../inc
+SOURCEPATH      ../src
+
+START RESOURCE ../data/2001E5BB.rss
+TARGET piprofilerdiskwriter.rsc
+END
+
+SOURCE          DiskWriterPlugin.cpp
+SOURCE          DiskWriterPluginImplementationTable.cpp
+
+LIBRARY			sysutil.lib 
+LIBRARY         euser.lib
+LIBRARY         ECom.lib
+LIBRARY         EFSRV.LIB
+LIBRARY         commonengine.lib
+LIBRARY			flogger.lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+PRJ_MMPFILES
+DiskWriterPlugin.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/inc/DiskWriterPlugin.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __DISKWRITERPLUGIN_H__
+#define __DISKWRITERPLUGIN_H__
+
+//  Include Files
+#include <w32std.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <e32base.h>	// CBase
+#include <e32std.h>	 // TBuf
+#include <e32property.h>
+
+_LIT(KFileOutShortName, "dsw");
+
+// forward declarations
+class CDiskWriterHandler;
+class CProfilerSampleStream;
+
+//  Class Definitions
+
+class CDiskWriterPlugin : public CWriterPluginInterface
+	{
+public:
+	// new function
+	static CDiskWriterPlugin* NewL(const TUid aImplementationUid, TAny* aInitParams);
+	~CDiskWriterPlugin();
+
+	void	DoCancel();
+
+	
+public: // new functions
+	
+	TInt 	Start();
+
+	void 	Stop();
+    
+	void 	GetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+	
+	void 	SetValue( const TWriterPluginValueKeys aKey, TDes& aValue ); 
+    
+	TUid 	Id() const;
+		 
+	void 	GetWriterVersion(TDes* aDes);
+	
+	TUint32 GetWriterType();
+
+	void   HandleError(TInt aError);
+	
+	void   WriteData();
+	
+	void   SetStream(CProfilerSampleStream& aStream) { iStream = &aStream; }
+	
+private: // new functions
+	CDiskWriterPlugin(const TUid aImplementationUid);
+	void 	ConstructL();
+
+	void 	GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+	void 	SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+    TBool   GetEnabled();
+	
+	TInt   DisplayNotifier(const TDesC& aLine1, const TDesC& aLine2, const TDesC& aButton1, const TDesC& aButton2);
+public: 
+    CProfilerSampleStream*          iStream;
+private: // data
+
+    TBuf<256>                       iFileName;
+	TInt 							iWriterType;
+	TInt							iWriterId;
+	CDiskWriterHandler*				iWriterHandler;
+	RProperty                       iErrorStatus;
+	};
+
+/*
+ * 
+ * Definition of class CDiskWriterHandler
+ * 
+ */
+class CDiskWriterHandler : public CActive //CBase
+	{
+public:
+ 
+
+	static CDiskWriterHandler* NewL(CDiskWriterPlugin* aWriter);
+	~CDiskWriterHandler();
+
+	void StartL();
+
+	void Stop();
+	void RunL();
+	TInt RunError(TInt aError);
+	
+	void DoCancel();
+	void WriteBufferToOutput(TBapBuf* aBuf);
+	void Reset();
+	   
+    TInt TestFile(const TDesC& totalPrefix);
+private:
+	CDiskWriterHandler(CDiskWriterPlugin* aWriter); 
+	
+	void ConstructL();
+    void WriteMemBufferToFile(TDesC8& aDes, TRequestStatus& aStatus);
+	static TInt Write(TAny* aObject);
+	void HandleFullBuffers();
+	void DoWrite();
+	
+private:
+    RFile                           iFile;
+    RFs                             iFs;
+    TBuf<256>                       iFileName;
+	CDiskWriterPlugin* 				iWriter;
+    TBapBuf*                        iBufferBeingWritten;
+    TBool                           iStopping;
+	};
+
+#endif  // __DEBOUTWRITERPLUGIN_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/sis/DiskWriterPlugin_EKA2.pkg	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for DebOutWriterPlugin dll
+;
+; This is an auto-generated PKG file by Carbide.
+; This file uses variables specific to Carbide builds that will not work
+; on command-line builds. If you want to use this generated PKG file from the
+; command-line tools you will need to modify the variables with the appropriate
+; values: $(EPOCROOT), $(PLATFORM), $(TARGET)
+
+;
+; UID is the dll's UID
+;
+#{"DebOutWriterPlugin DLL"},(0x00DA58C7),1,0,0
+
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\DebOutWriterPlugin.dll"		  -"!:\sys\bin\DebOutWriterPlugin.dll"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,476 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+//  Include Files  
+
+#include "DiskWriterPlugin.h"	// CDiskWriterPlugin
+#include <e32base.h>
+#include <sysutil.h>
+//#include <piprofiler/EngineUIDs.h>
+
+// constants
+const TUid KDiskWriterPluginUid = { 0x2001E5BB };   // own UID
+
+// engine properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+    {
+    EProfilerEngineStatus = 8,
+    EProfilerErrorStatus
+    };
+
+/*
+ *
+ *	Class CDiskWriterPlugin implementation
+ *
+ */
+
+//  Member Functions
+CDiskWriterPlugin* CDiskWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+    {
+	LOGTEXT(_L("CDiskWriterPlugin::NewL() - entry"));
+	CDiskWriterPlugin* self = new (ELeave) CDiskWriterPlugin(KDiskWriterPluginUid);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDiskWriterPlugin::NewL() - exit"));
+    return self;
+    }
+
+CDiskWriterPlugin::CDiskWriterPlugin(const TUid aImplementationUid) :
+	iWriterType(aImplementationUid.iUid)
+    {
+    LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - entry"));
+    isEnabled = EFalse;
+    iWriterId = Id().iUid;
+    LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - exit"));
+    }
+
+CDiskWriterPlugin::~CDiskWriterPlugin()
+    {
+    LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - entry"));
+
+    iErrorStatus.Close();
+    
+    if(iWriterHandler)
+        {
+        iWriterHandler->Cancel();
+        delete iWriterHandler;
+        }
+    LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - exit"));
+    }
+
+void CDiskWriterPlugin::ConstructL()
+	{
+	// second phase constructor, anything that may leave must be constructed here
+	LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - entry"));
+	iWriterHandler = CDiskWriterHandler::NewL(this);
+	User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+	LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - exit"));
+	}
+
+TUid CDiskWriterPlugin::Id() const 
+	{
+    LOGSTRING2("CDiskWriterPlugin::Id():0x%X", KDiskWriterPluginUid.iUid );
+    return KDiskWriterPluginUid;
+	}
+	 
+void CDiskWriterPlugin::GetWriterVersion(TDes* aDes)
+	{
+	_LIT(KDiskWriterVersion, "1.0.0");
+	aDes->Append(KDiskWriterVersion);
+	}
+
+TInt CDiskWriterPlugin::Start()
+	{
+//	if(isEnabled)
+//		{
+//		TRAPD(err, iWriterHandler->StartL());
+//		if( err != KErrNone)
+//		    {
+//		    LOGTEXT(_L("Could not start writer plugin"));
+//		    return err;
+//		    }
+//		}
+	return KErrNone;
+	}
+
+void CDiskWriterPlugin::Stop()
+	{
+	// stop writer handler normally
+	iWriterHandler->Stop();
+	}
+
+TBool CDiskWriterPlugin::GetEnabled()
+	{
+	return isEnabled;
+	}
+
+TUint32 CDiskWriterPlugin::GetWriterType()
+	{
+	return iWriterType;
+	}
+
+
+void CDiskWriterPlugin::SetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( SetValueL( aKey, aValue ) );
+    }
+
+
+void CDiskWriterPlugin::GetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( GetValueL( aKey, aValue ) );
+    }
+
+void CDiskWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+    {
+    TInt error(KErrNone);
+    
+    switch( aKey )
+        {
+        case EWriterPluginEnabled:
+            isEnabled = ETrue;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled"));
+        	break;
+        case EWriterPluginDisabled:
+            isEnabled = EFalse;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled"));	
+            break;
+        case EWriterPluginSettings:	// file name in case of disk writer plugin
+        	iFileName.Zero();
+        	iFileName.Append(aValue);
+        	error = iWriterHandler->TestFile(iFileName);
+        		User::LeaveIfError(error);
+        	break;
+        default:
+        	break;
+        }
+    }
+
+void CDiskWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+    {
+    switch( aKey )
+        {
+        case EWriterPluginVersion:
+        	GetWriterVersion(&aValue);
+        	break;
+        case EWriterPluginType:
+        	break;
+        case EWriterPluginSettings:	// file name in disk writer case
+        	aValue.Copy(iFileName);
+           default:
+                break;
+        }
+    }
+
+void CDiskWriterPlugin::DoCancel()
+    {
+	LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry"));
+    }
+
+void CDiskWriterPlugin::WriteData()
+    {
+    // Activate handler to write data from buffer to output
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry"));
+    TRAP_IGNORE(iWriterHandler->StartL());
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit"));
+    }
+
+void CDiskWriterPlugin::HandleError(TInt aError)
+    {
+    TInt err(KErrNone);
+    RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error received: %d"), aError);
+    err = iErrorStatus.Set(aError);
+    if(err != KErrNone)
+        {
+        RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error in updating property: %d"), err);
+        }
+    }
+
+/*
+ * 
+ * Implementation of class CDiskWriterHandler
+ * 
+ */
+
+CDiskWriterHandler* CDiskWriterHandler::NewL(CDiskWriterPlugin* aWriter)
+    {
+	LOGTEXT(_L("CDiskWriterHandler::NewL() - entry"));
+	CDiskWriterHandler* self = new (ELeave) CDiskWriterHandler(aWriter);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDiskWriterHandler::NewL() - exit"));
+    return self;
+    }
+
+CDiskWriterHandler::CDiskWriterHandler(CDiskWriterPlugin* aWriter)  :
+    CActive(EPriorityStandard)
+    {
+    LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - entry"));
+
+    iWriter = aWriter;
+    
+    // set initial mode to non-stopping
+    iStopping = EFalse;
+    
+    // add the handler to the active scheduler
+    CActiveScheduler::Add(this);
+    
+    LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - exit"));
+    }
+
+
+CDiskWriterHandler::~CDiskWriterHandler()
+    {
+	LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - entry"));
+
+	LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - exit"));
+    }    
+    
+void CDiskWriterHandler::ConstructL()
+	{
+	}
+
+TInt CDiskWriterHandler::TestFile(const TDesC& totalPrefix) 
+    {
+    TParse parse;
+
+    TInt err(KErrNone);
+    if((err = parse.Set(totalPrefix, NULL, NULL)) != KErrNone)
+        return err;
+
+    err = iFs.Connect();
+    if(err != KErrNone)
+        {
+        LOGTEXT(_L("CDiskWriterHandler::TestFile() - Failed to open a session to file server"));
+        return KErrNotFound;
+        }
+    
+    iFs.MkDirAll(parse.FullName());
+    
+    err = iFile.Replace(iFs,parse.FullName(),EFileWrite);
+    if(err != KErrNone)
+        {
+        iFs.Close();
+        return KErrNotFound;
+        }
+    
+    iFileName.Copy(parse.FullName());
+
+    return KErrNone;
+    }
+
+void CDiskWriterHandler::Reset()
+    {
+    // cancel active object
+    Cancel();
+    
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+    
+    // empty the rest of the buffers synchronously
+    while(nextBuf != 0)
+        {
+        LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+        if(nextBuf->iDataSize != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+            WriteMemBufferToFile(*(nextBuf->iBufDes),iStatus);
+            }
+        
+        // empty buffers when profiling stopped
+        iWriter->iStream->AddToFreeBuffers(nextBuf);
+
+        LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer"));
+        // start writing new buffer if there is one available
+        nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf);
+        }
+    }
+
+void CDiskWriterHandler::HandleFullBuffers()
+    {
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry"));
+    // previous write operation has finished
+    // release the previous buffer 
+    iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten);
+
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer"));
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+    if(nextBuf != 0)
+        {
+        LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file"));
+        if(nextBuf->iDataSize != 0)
+            {
+            WriteBufferToOutput(nextBuf);
+            }
+        } 
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit"));
+    }
+
+void CDiskWriterHandler::RunL()
+    {
+    LOGTEXT(_L("CDiskWriterHandler::RunL - entry"));
+    // call function to complete full buffer handling
+    HandleFullBuffers();
+    LOGTEXT(_L("CDiskWriterHandler::RunL - exit"));
+    }
+
+void CDiskWriterHandler::DoCancel()
+    {
+    
+    }
+
+//-----------------------------------------------------------------------------
+// CPIProfilerTraceCoreLauncher::RunError(TInt aError)
+// Handle leaves from RunL().
+//-----------------------------------------------------------------------------
+TInt CDiskWriterHandler::RunError(TInt aError)
+    {
+    // no reason to continue if disk full or removed
+    iFile.Close();
+    // close handle to file server too
+    iFs.Close();
+    iFileName.Zero();
+    
+    iWriter->HandleError(KErrDiskFull);
+    return aError;
+    }
+
+void CDiskWriterHandler::WriteMemBufferToFile(TDesC8& aDes, TRequestStatus& aStatus)
+    {   
+    LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - entry"));
+
+    TUint sampleSize(aDes.Length());
+    TInt err(KErrNone);
+    TInt drive(0);
+    TDriveInfo info;
+    TBool noDiskSpace(EFalse);
+    
+    err = iFile.Drive(drive,info);
+
+    // test available disk space 
+    TRAP_IGNORE((noDiskSpace = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, sampleSize, drive))); 
+    // check first if still space on disk
+    if(noDiskSpace)
+        {
+        // set error to disk full
+        err = KErrDiskFull;
+        LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - disk full, cannot write"));
+        }
+    else
+        {
+        // check if profiling in stopping mode
+        if(iStopping)
+            {
+            // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d, stopping"), aDes.Length());
+            // write to file without status
+            err = iFile.Write(aDes);
+            }
+        else
+            {
+            // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d"), aDes.Length());
+            // write to file with status
+            iFile.Write(aDes,aStatus);
+            }
+        }
+    
+    // check if error in write
+    if(err != KErrNone)
+        {
+        // stop writer handler (and its timer) immediately, DO NOT try write data!
+        Cancel();
+        
+        // no reason to continue if disk full or removed
+        // end of stream detected, file can be closed
+        iFile.Close();
+        // close handle to file server too
+        iFs.Close();
+        iFileName.Zero();
+        
+        // set error status for engine to read
+        iWriter->HandleError(err);
+        }
+    LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - exit"));
+    }
+
+void CDiskWriterHandler::WriteBufferToOutput(TBapBuf* aBuf)
+    {
+    LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - entry"));
+    iBufferBeingWritten = aBuf;
+
+    // set the data length just to be sure
+    iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize);
+
+    LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file"));
+    WriteMemBufferToFile(*(iBufferBeingWritten->iBufDes), iStatus);
+
+    // set AO back to active, until filled buffers are emptied 
+    SetActive();
+    
+    LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - exit"));
+    }
+
+void CDiskWriterHandler::StartL()
+	{
+	LOGTEXT(_L("CDiskWriterHandler::StartL - entry"));
+    if(!IsActive())
+        {
+        LOGTEXT(_L("CDiskWriterHandler::StartL - is not active"));
+    
+        TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf);
+    
+        if(nextBuf != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file"));
+            WriteBufferToOutput(nextBuf);
+            }
+        }
+    LOGTEXT(_L("CDiskWriterHandler::StartL - exit"));
+	}
+
+void CDiskWriterHandler::Stop()
+	{
+	LOGTEXT(_L("CDiskWriterHandler::Stop - entry"));
+	
+	// set to stopping mode, needed for emptying the remaining full buffers
+	iStopping = ETrue;
+	
+	// stop the timer
+	Reset();
+
+    // end of stream detected, file can be closed
+    iFile.Close();
+    // close handle to file server too
+    iFs.Close();
+    iFileName.Zero();
+    
+    // set mode back to non-stopping
+    iStopping = EFalse;
+    
+    LOGTEXT(_L("CDiskWriterHandler::Stop - exit"));
+	}
+
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPluginImplementationTable.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "DiskWriterPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+         IMPLEMENTATION_PROXY_ENTRY(0x2001E5BB,  CDiskWriterPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/data/2001E5B2.rss	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+    {
+    // UID for the DLL. See mmp files
+    //__SERIES60_3X__ can't be used in resource files
+    dll_uid = 0x2001E5B2;
+
+    // Declare array of interface info. This dll contains implementations for 
+    // only one interface (CSamplerInterfaceDefinition).
+    interfaces = 
+        {
+        INTERFACE_INFO
+            {
+            // UID of interface that is implemented
+            interface_uid = 0x2001E5BC;
+
+            implementations = 
+                {
+                IMPLEMENTATION_INFO
+                    {
+                    implementation_uid = 0x2001E5B2;
+
+                    version_no = 1;
+                    display_name = "General Samplers; GPP, ITT, GFC, MEM, PRI";
+                    default_data = "gen";
+                    opaque_data = "0";	// the order number
+                    }
+                };
+            }
+        };
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/GeneralsPlugin.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET              PIProfilerGenerals.dll
+TARGETTYPE          PLUGIN
+UID                 0x10009D8D 0x2001E5B2
+VENDORID            VID_DEFAULT
+CAPABILITY          ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE     	0x10000
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE     ../inc
+SOURCEPATH      ../src
+
+START RESOURCE  ../data/2001E5B2.rss
+TARGET PIProfilerGenerals.rsc
+END
+
+SOURCE              GeneralsPluginImplementationTable.cpp
+SOURCE              GeneralsPlugin.cpp
+
+LIBRARY             euser.lib
+LIBRARY     		bafl.lib 
+LIBRARY             ECom.lib
+LIBRARY             apparc.lib
+LIBRARY             cone.lib
+LIBRARY             ws32.lib
+LIBRARY             charconv.lib
+LIBRARY             commonengine.lib
+LIBRARY				flogger.lib
+
+epocallowdlldata
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/GeneralsSampler.mmp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform_paths.hrh>
+#include "kernel/kern_ext.mmh"
+
+TARGET              PIProfilerGeneralsSampler.ldd
+CAPABILITY          ALL
+TARGETTYPE          LDD
+UID                 0x100000AF 0x2001E5B3
+VENDORID            VID_DEFAULT 
+SMPSAFE
+
+OS_LAYER_KERNEL_SYSTEMINCLUDE
+USERINCLUDE         ../inc
+SOURCEPATH          ../src
+
+SOURCE              GeneralsDriver.cpp 
+SOURCE              GeneralsSampler.cia
+SOURCE              GppSamplerImpl.cpp 
+SOURCE              IttEventHandler.cpp
+SOURCE              IttSamplerImpl.cpp
+SOURCE              MemoryEventHandler.cpp 
+SOURCE              MemSamplerImpl.cpp 
+SOURCE              PriSamplerImpl.cpp
+
+#ifdef SMP
+LIBRARY				ekernsmp.lib
+#else
+LIBRARY				ekern.lib
+#endif
+
+epocallowdlldata
+
+start wins
+win32_headers
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/bld.inf	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+//PRJ_PLATFORMS
+//DEFAULT ARMV5SMP
+
+PRJ_MMPFILES
+#ifdef MARM
+  GeneralsPlugin.mmp
+  GeneralsSampler.mmp
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsConfig.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,99 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef GENERALS_CONFIG_H
+#define GENERALS_CONFIG_H
+
+
+	// change this to reflect the ISA task amount
+	#define PROFILER_ISA_OS_TASK_AMOUNT	50	
+
+	// don't change these definitions
+	#define	PROFILER_DEFINE_ISA_TASK_NAME_ARRAY 			TBuf8<64> isaTaskNames[PROFILER_ISA_OS_TASK_AMOUNT];
+	#define PROFILER_DEFINE_ISA_TASK_NAME(name,number)	isaTaskNames[number].Append(_L8(name));										
+
+	// change these to reflect the real ISA task names and numbers
+	// the last number must be PROFILER_ISA_OS_TASK_AMOUNT-1
+
+	#define PROFILER_ISA_TASK_NAMES		PROFILER_DEFINE_ISA_TASK_NAME("SRVSCKT_TASK",0)\
+		PROFILER_DEFINE_ISA_TASK_NAME("CSD_SRV_TASK",1)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CSD_NTB_TASK",2)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CSD_WTB_TASK",3)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("PH_TASK",4)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("L2_TASK",5)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("RR_TASK",6)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("GPRS_RLC_TASK",7)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("GPRS_MAC_TASK",8)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("RANC_TASK",9)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MM_TASK",10)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CC_TASK",11)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SMS_TASK",12)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("RM_CONTROL_TASK",13)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("GSS_SERVER_TASK",14)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CS_MAIN_TASK",15)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("GPRS_TASK",16)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WMAC_TASK",17)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WMHS_TASK",18)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WRRC_TASK",19)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WRLC_UL_TASK",20)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WRLC_DL_TASK",21)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WPH_TASK",22)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("WRAN_TASK",23)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SSOM_TASK",24)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("ACCESSORY_TASK",25)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("ADL_TASK",26)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("AUDIO_TASK",27)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("PN_TASK",28)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CORE_HI_TASK",29)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("CORE_LO_TASK",30)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("ENERGY_TASK",31)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("FBUS_TASK",32)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("PMM_FILE2_TASK",33)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MDI_RCV_TASK",34)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MDI_SEND_TASK",35)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MONITOR_TASK",36)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MTC_CTRL_TASK",37)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("MTC_WD_TASK",38)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("OBEX_TASK",39)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("APDU_SERVER_TASK",40)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SIMSON_SERVER_TASK",41)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SIMLOCK_TASK",42)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SOS_USB_MM_TASK",43)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("SOS_PROXY_AUX_TASK",44)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("TERMINAL_ADAPTER_TASK",45)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("XTI_RECEIVE_TASK",46)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("XTI_SEND_TASK",47)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("STARTUP_AND_BACKGROUND_TASK",48)						\
+		PROFILER_DEFINE_ISA_TASK_NAME("OS_IDLE_TASK",49)	
+
+	// old definitions
+	#define 	PROFILER_GENERALS_SAMPLER_ID		100
+	#define		PROFILER_GPP_SAMPLER_ID			1
+	#define		PROFILER_GFC_SAMPLER_ID			2
+	#define		PROFILER_ITT_SAMPLER_ID			3
+	#define		PROFILER_MEM_SAMPLER_ID			4
+	#define		PROFILER_PRI_SAMPLER_ID			5
+
+	#define		PROFILER_GPP_SAMPLER_NAME _L("GPP")
+	#define		PROFILER_GFC_SAMPLER_NAME _L("GFC")
+	#define		PROFILER_ITT_SAMPLER_NAME _L("ITT")
+	#define		PROFILER_MEM_SAMPLER_NAME _L("MEM")
+	#define		PROFILER_PRI_SAMPLER_NAME _L("PRI")
+
+	
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsDriver.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __GENERALSSAMPLER_H__
+#define __GENERALSSAMPLER_H__
+
+/*
+ * The user-interface to the sampling device driver sued by the profiling engine
+ */
+#include <piprofiler/PluginSampler.h>
+
+#ifndef __KERNEL_MODE__
+#include <utf.h>
+#endif
+
+
+/**
+ * The user device driver class for controlling the plugin sampler.
+ */
+
+class RGeneralsSampler :  public RPluginSampler 
+{	
+	public:
+		#ifndef __KERNEL_MODE__
+		
+		/** Open a channel to the sampling device **/
+		inline TInt Open();
+		
+		#endif	// !__KERNEL_MODE__	
+};
+	
+_LIT(KPluginSamplerName,"PIProfilerGeneralsSampler");
+
+#ifndef __KERNEL_MODE__
+
+inline TInt RGeneralsSampler::Open()
+{
+	return DoCreate(KPluginSamplerName,TVersion(1,0,1),KNullUnit,NULL,NULL);
+}
+
+
+#endif
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsPlugin.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_GENERALSECOM_SAMPLER_H
+#define PROFILER_GENERALSECOM_SAMPLER_H
+
+#include <w32std.h>
+
+#include "GeneralsDriver.h"
+#include "GeneralsConfig.h"
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+
+// constants 
+const TUint KDefaultOutputCombination = 3;
+
+const TUint KSubSamplerCount = 5;
+
+// parent itself
+_LIT(KGENShortName, "gen");
+_LIT(KGENMediumName, "Generic samplers plug-in");
+_LIT(KGENLongName, "Generic samplers plug-in");
+
+// gpp caption definitions
+_LIT8(KGPPShortName, "gpp");
+#ifdef CARBIDE_NAMES
+_LIT8(KGPPLongName, "Address/Thread sampling");
+#else
+_LIT8(KGPPLongName, "CPU load sampler");
+#endif
+_LIT8(KGPPDescription, "CPU load sampler\nSampling thread and process load\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// gfc caption definitions
+_LIT8(KGFCShortName, "gfc");
+#ifdef CARBIDE_NAMES
+_LIT8(KGFCLongName, "Function call sampling");
+#else
+_LIT8(KGFCLongName, "Function call sampler");
+#endif
+_LIT8(KGFCDescription, "Function call sampler\nCapturing function call info\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// itt caption definitions
+_LIT8(KITTShortName, "itt");
+#ifdef CARBIDE_NAMES
+_LIT8(KITTLongName, "Dynamic binary support");
+#else
+_LIT8(KITTLongName, "Dynamic binary sampler");
+#endif
+_LIT8(KITTDescription, "Dynamic binary sampler\nTracing dynamically loaded binaries, e.g. from ROFS\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// mem caption definitions
+_LIT8(KMEMShortName, "mem");
+#ifdef CARBIDE_NAMES
+_LIT8(KMEMLongName, "Memory usage sampler");
+#else
+_LIT8(KMEMLongName, "Memory trace sampler");
+#endif
+_LIT8(KMEMDescription, "Memory trace sampler\nTracing memory, i.e. stack and chunk usage\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// pri caption definitions
+_LIT8(KPRIShortName, "pri");
+#ifdef CARBIDE_NAMES
+_LIT8(KPRILongName, "Thread priority sampling");
+#else
+_LIT8(KPRILongName, "Priority trace sampler");
+#endif
+_LIT8(KPRIDescription, "Priority trace sampler\nTracing thread priorities\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+
+// forward definitions
+class CConfigInfoArray;
+class CProfilerBufferHandler;
+class CProfilerSampleStream;
+class TSamplerAttributes;
+
+class CGeneralsPlugin : public CSamplerPluginInterface
+{
+public:
+	static CGeneralsPlugin* NewL(const TUid aImplementationUid, TAny* /*aInitParams*/);
+	~CGeneralsPlugin();
+
+	TUint32 GetSampleTime();
+	
+	/* 
+	 * Sub sampler specific functions
+	 * 
+	 */
+	
+	// from CSamplerPluginInterface
+	TInt 	ResetAndActivateL(CProfilerSampleStream& aStream);
+	TInt 	StopSampling();
+    TBool   Enabled() { return iEnabled; }
+
+	TUid 	Id( TInt aSubId ) const;
+	TInt 	SubId( TUid aSubId ) const;	// internal
+
+	void    GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+	TInt    SetAttributesL(TSamplerAttributes aAttributes);
+	void    InitiateSamplerAttributesL();
+	
+	TInt    ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray);
+	TInt    DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex);
+	void    SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex);
+
+	TInt 	GetSamplerType();
+	
+	void    InstallStreamForActiveTraces(RGeneralsSampler& sampler, CProfilerSampleStream& aStream);
+	
+private:
+	CGeneralsPlugin();
+	void ConstructL();
+
+	TInt InitiateSamplerL();
+	TInt CleanSampler();
+    void SetSettingsToSamplers();
+	
+private:
+	TUint8						iVersion[20];
+	TPtr8						iVersionDescriptor;
+	
+	RGeneralsSampler 			iGeneralsSampler;
+
+	CProfilerBufferHandler*		iBufferHandler;
+	
+	CArrayFixFlat<TSamplerAttributes>* iSamplerAttributes;
+
+	TBuf8<9>                    iSearchTexts;
+public:
+	TUint32* 					iSampleTime;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GfcSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,249 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_GFC_SAMPLER_H
+#define PROFILER_GFC_SAMPLER_H
+
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+
+extern void UsrModLr(TUint32*);
+
+
+/*
+ *	
+ *	GFC sampler definition
+ *	
+ */
+
+template <int BufferSize>
+class DProfilerGfcSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+	DProfilerGfcSampler(struct TProfilerGppSamplerData* );
+	~DProfilerGfcSampler();
+
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+private:
+	struct TProfilerGppSamplerData* gppSamplerData;
+	TUint32 gfcSample[3];
+
+	TUint8	encodedSample[15];
+	TUint32	repeat;
+};
+
+/*
+ *	
+ *	GFC sampler implementation
+ *	
+ */
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::DProfilerGfcSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) :
+	DProfilerGenericSampler<BufferSize>(PROFILER_GFC_SAMPLER_ID)
+{
+	this->gppSamplerData = gppSamplerDataIn;
+	LOGSTRING2("CProfilerGfcSampler<%d>::CProfilerGfcSampler",BufferSize);	
+}
+
+template <int BufferSize>
+TInt DProfilerGfcSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+{
+	LOGSTRING2("CProfilerGfcSampler<BufferSize> - entry",BufferSize);
+	
+	this->repeat = 0;
+	for(TInt i(0);i<3;i++)
+	{
+		this->gfcSample[i] = 0;
+	}
+
+	LOGSTRING2("CProfilerGfcSampler<%d>::Reset - calling superclass reset",BufferSize);
+	DProfilerGenericSampler<BufferSize>::Reset(aStream);
+	LOGSTRING2("CProfilerGfcSampler<%d>::Reset - called superclass reset",BufferSize);
+	
+	// add the first sample, indicating the gfc trace version
+	TUint8 firstSample[33];
+	TPtr8 firstSampleDesc(&(firstSample[1]),32);
+	firstSampleDesc.Zero();
+
+	firstSampleDesc.Append(_L8("Bappea_V"));
+	firstSampleDesc.Append(PROFILER_GFC_SAMPLER_VERSION);
+	firstSampleDesc.Append(_L8("_GFC"));
+	firstSample[0] = firstSampleDesc.Size();
+
+	this->iSampleBuffer->AddSample(firstSample,(firstSample[0]+1));
+
+	LOGSTRING2("CProfilerGfcSampler<BufferSize> - exit",BufferSize);
+
+	return KErrNone;
+}
+
+template <int BufferSize>
+void DProfilerGfcSampler<BufferSize>::Sample()
+{
+	LOGSTRING2("CProfilerGfcSampler<%d>::Sample",BufferSize);	
+
+	TUint32 usr_mod_link_reg;
+
+	UsrModLr(&usr_mod_link_reg);
+
+	TUint32 pc(gppSamplerData->lastPcValue);
+	TUint32 lr(usr_mod_link_reg);
+	TUint32 sa(gppSamplerData->sampleNumber);
+
+	if(pc == gfcSample[0] && lr == gfcSample[1] && sa == gfcSample[2]+1)
+	{
+		// encode repeat
+		repeat++;
+		gfcSample[2] = sa;
+		LOGSTRING2("CProfilerGfcSampler<%d>::Sample - repeat",BufferSize);
+		return;
+	}
+	else if(repeat > 0)
+	{
+		TUint8 repeatSample[3];
+		repeatSample[0] = 0xff;
+		repeatSample[1] = (TUint8)(repeat>>8);
+		repeatSample[2] = (TUint8)repeat;
+		this->iSampleBuffer->AddSample(repeatSample,3);
+
+		LOGSTRING3("CProfilerGfcSampler<%d>::Sample - Encoded repeat %d",BufferSize,repeat);
+
+		repeat = 0;
+	}
+
+	TInt ptr(3);
+
+	// encode program counter value
+	if(pc>=gfcSample[0]) 
+	{
+		pc = (pc-gfcSample[0]);
+		encodedSample[0] = 0x80;
+	}
+	else 
+	{
+		pc = (gfcSample[0]-pc);
+		encodedSample[0] = 0x00;
+	}
+
+	if(pc <= (TUint32)0xff) 
+	{
+		encodedSample[0] |= 1;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+	}
+	else if(pc <= (TUint32)0xffff) 
+	{
+		encodedSample[0] |= 2;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+	}
+	else if(pc <= (TUint32)0xffffff) 
+	{
+		encodedSample[0] |= 3;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+	}
+	else 
+	{
+		encodedSample[0] |= 4;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>24);ptr++;
+	}
+
+	// encode link register value
+	if(lr>=gfcSample[1]) 
+	{
+		lr = (lr-gfcSample[1]);
+		encodedSample[1] = 0x80;
+	}
+	else 
+	{
+		lr = (gfcSample[1]-lr);
+		encodedSample[1] = 0x00;
+	}
+
+	if(lr <= (TUint32)0xff) 
+	{
+		encodedSample[1] |= 1;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+	}
+	else if(lr <= (TUint32)0xffff) 
+	{
+		encodedSample[1] |= 2;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+	}
+	else if(lr <= (TUint32)0xffffff) 
+	{
+		encodedSample[1] |= 3;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+	}
+	else 
+	{
+		encodedSample[1] |= 4;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>24);ptr++;
+	}
+	
+	// endcode sample number difference
+	if( (sa - gfcSample[2]) < (TUint8)0xff) 
+	{
+		encodedSample[2] = (sa-gfcSample[2]);
+	}
+	else
+	{
+		encodedSample[2] = 0xff;
+		encodedSample[ptr] = (TUint8)sa;ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>24);ptr++;
+	}
+
+	// store the values for the next sample
+	gfcSample[0] = gppSamplerData->lastPcValue;
+	gfcSample[1] = usr_mod_link_reg;
+	gfcSample[2] = gppSamplerData->sampleNumber;
+	
+	this->iSampleBuffer->AddSample(encodedSample,ptr);
+
+	LOGSTRING3("CProfilerGfcSampler<%d>::Sample Size %d",BufferSize,ptr);
+
+	return;
+
+}
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::~DProfilerGfcSampler()
+{
+	LOGSTRING2("CProfilerGfcSampler<%d>::~CProfilerGfcSampler",BufferSize);		
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GppSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_GPP_SAMPLER_H
+#define PROFILER_GPP_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <e32cmn.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+
+// for RPropertyRef
+#include <sproperty.h> 
+#include <e32cmn.h>
+
+/*
+ *	
+ *	GPP sampler definition
+ *	
+ */
+class DGppSamplerImpl //: public DBase
+{
+public:
+
+	DGppSamplerImpl();
+	~DGppSamplerImpl();
+
+	TUint8* EncodeTag(TUint8* aPtr);
+	TUint8* EncodeInt(TUint8* aPtr,TInt aValue);
+	TUint8* EncodeUint(TUint8* aPtr,TUint aValue);
+	TUint8* EncodeText(TUint8* aPtr, const TDesC& aDes);
+
+	TUint8* EncodeName(TUint8* aPtr, DObject& aObject,TUint32 id);
+	TUint8* EncodeThread(TUint8* aPtr, DThread& aThread);
+
+	TBool	IsaTaskKnown(TUint8 task);
+	TUint8* EncodeIsaTask(TUint8* aPtr, TUint task);
+	TUint8* EncodeIsaName(TUint8* aPtr, TUint task,TBool process);
+	
+	TUint8* EncodeRepeat(TUint8* aPtr);
+
+	TInt	CreateFirstSample();
+	TInt	SampleImpl();
+#ifdef __SMP__
+    TSpinLock* LockPtr();
+#endif
+    TInt    iGppSamplingPeriod;
+	TUint8	tempBuf[512];
+	TUint	iLastPc;
+	
+	TBool	iIsaSample;
+	TInt	knownIsaTasks[256];
+	TUint8	knownIsaTaskCount;
+	TInt*	isaOsTaskRunningAddr;
+	void	Reset();
+    TUint32 iSampleCount;
+#ifdef __SMP__
+    TInt        iCpuNumber;
+    TUint32     iStartTime;
+#endif	   
+	PROFILER_DEFINE_ISA_TASK_NAME_ARRAY
+
+private:
+	enum TState {EStop,ERunning,EStopping};
+
+	const TUint* iInterruptStack;
+	
+	TUint		iLastThread;
+	TUint		iRepeat;
+#ifndef __SMP__
+	TUint32 	iStartTime;
+#endif
+	RPropertyRef iIsaStartAddr;
+	RPropertyRef iIsaEndAddr;
+	RPropertyRef iIsaPluginStatus;
+	RPropertyRef iIsaOsTaskRunning;
+	TInt 		iIsaStatus;
+	TInt 		iIsaStart;
+	TInt 		iIsaEnd;
+	TUint32     iMask;
+	TUint32     iCpuSelector;
+};
+
+struct TProfilerGppSamplerData
+{
+//public:
+	TUint32		lastPcValue;
+	TUint32		sampleNumber;
+    TInt        samplingPeriod;
+};
+
+template <int BufferSize>
+class DProfilerGppSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+#ifndef __SMP__
+	DProfilerGppSampler();
+#else
+    DProfilerGppSampler(TInt aCpuNumber);
+#endif
+	~DProfilerGppSampler();
+
+	struct TProfilerGppSamplerData* GetExportData();
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+	TInt 	GetPeriod();
+	
+private:
+	DGppSamplerImpl gppSamplerImpl;
+	struct TProfilerGppSamplerData exportData;
+#ifdef __SMP__
+	TInt   iCpuNumber;
+#endif
+};
+
+/*
+ *	
+ *	GPP sampler implementation
+ *	
+ */
+#ifndef __SMP__
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::DProfilerGppSampler() :
+	DProfilerGenericSampler<BufferSize>(PROFILER_GPP_SAMPLER_ID) 
+    {
+	LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+    }
+#else
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::DProfilerGppSampler(TInt aCpuNumber) :
+    DProfilerGenericSampler<BufferSize>(PROFILER_GPP_SAMPLER_ID+(aCpuNumber*20)), iCpuNumber(aCpuNumber) 
+    {
+    LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+    }
+#endif
+
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::~DProfilerGppSampler()
+    {
+	LOGSTRING2("CProfilerGppSampler<%d>::~CProfilerGppSampler",BufferSize);		
+    }
+
+template <int BufferSize>
+TInt DProfilerGppSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+        {
+	LOGSTRING2("CProfilerGppSampler<%d>::Reset - calling superclass reset",BufferSize);
+	DProfilerGenericSampler<BufferSize>::Reset(aStream, 0);
+	LOGSTRING2("CProfilerGppSampler<%d>::Reset - called superclass reset",BufferSize);
+
+	this->gppSamplerImpl.Reset();
+	
+#ifdef __SMP__
+	this->gppSamplerImpl.iCpuNumber = this->iCpuNumber;
+	
+	// set common start time for all CPU samplers
+	this->gppSamplerImpl.iStartTime = aSyncOffset;
+#endif
+	this->gppSamplerImpl.iGppSamplingPeriod = this->iSamplingPeriod;
+	this->gppSamplerImpl.iSampleCount = 0;
+	this->exportData.sampleNumber = 0;
+	this->exportData.lastPcValue = 0;
+    this->exportData.samplingPeriod = this->gppSamplerImpl.iGppSamplingPeriod;
+
+	TInt length = gppSamplerImpl.CreateFirstSample();
+	LOGSTRING3("CProfilerGPPSampler<%d>::Reset - got first sample, size %d",BufferSize,length);	
+	
+	this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,length);
+
+	// check if sampling period > 1 ms
+	// NOTE: feature supported in Performance Investigator 2.01 and above
+	if(this->gppSamplerImpl.iGppSamplingPeriod > 1)
+	    {
+        // For Address/Thread (GPP) version 2.01 or above, the first word is the sampling period in milliseconds
+        TUint8* w = gppSamplerImpl.tempBuf;
+        
+        (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >> 24) & 0xFF;
+        (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >> 16) & 0xFF;
+        (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >>  8) & 0xFF;
+        (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod) & 0xFF;
+        
+        this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,4);
+	    }
+	
+	LOGSTRING2("CProfilerGPPSampler<%d>::Reset finished",BufferSize);
+	return KErrNone;
+    }
+
+template <int BufferSize>
+void DProfilerGppSampler<BufferSize>::Sample()
+    {
+	LOGSTRING2("CProfilerGppSampler<%d>::Sample",BufferSize);
+//	if(this->gppSamplerImpl.iSampleCount % 1000 == 0) 
+//	    {
+//#ifdef __SMP__
+//	    if(this->iCpuNumber == 0)  // print sample tick only from CPU 0 context
+//	        {
+//#endif
+//	        Kern::Printf(("PIPROF SAMPLE TICK, #%d"),exportData.sampleNumber);
+//#ifdef __SMP__
+//	        }
+//#endif
+//	    }
+	
+	TInt length(gppSamplerImpl.SampleImpl());
+
+    this->gppSamplerImpl.iSampleCount++;
+	this->exportData.sampleNumber += this->gppSamplerImpl.iGppSamplingPeriod;
+	this->exportData.lastPcValue = gppSamplerImpl.iLastPc;
+
+	if(length > 0)
+        {
+        this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,length);
+        }
+
+	LOGSTRING3("CProfilerGppSampler<%d>::Sample - length %d",BufferSize,length);
+
+	return;
+    }
+
+
+template <int BufferSize>
+struct TProfilerGppSamplerData* DProfilerGppSampler<BufferSize>::GetExportData()
+    {
+	LOGSTRING2("CProfilerGppSampler<%d>::GetExportData",BufferSize);
+	return &(this->exportData);	
+    }
+
+template <int BufferSize>
+TInt DProfilerGppSampler<BufferSize>::GetPeriod()
+    {
+	return this->gppSamplerImpl.iGppSamplingPeriod;
+    }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/IttEventHandler.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Event based ITT sampler skeleton copypasted from MemoryEventHandler.h
+*
+*/
+#include "IttSamplerImpl.h"
+
+#ifndef __PI_ITT_EVENT_HANDLER__
+#define __PI_ITT_EVENT_HANDLER__
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+// CONSTANTS
+const TInt KITTBufferSize = 256;
+
+class DProfilerSampleBuffer;
+
+/*
+ * ITT event handler for listaning kernel events 
+ */
+class DIttEventHandler : public DKernelEventHandler
+    {
+public:
+    // constructor
+    DIttEventHandler(DProfilerSampleBuffer*  aSampleBuffer, TProfilerGppSamplerData* aGppSamplerDataIn);
+    TInt Create();
+    ~DIttEventHandler();
+    TInt Start();
+    TInt Stop();
+    TBool Tracking() {return iTracking;}
+       
+    TBool SampleNeeded();
+    
+private:
+    static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
+    TUint HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2);
+    // handle code segments
+    TBool HandleAddCodeSeg(DCodeSeg* aSeg);
+    TBool HandleRemoveCodeSeg(DCodeSeg* aSeg);
+
+private:
+    /** Lock serialising calls to event handler */
+        DMutex*     iLock;
+        TBool       iTracking;
+        DProfilerSampleBuffer*  iSampleBuffer;
+
+        TUint32     iCount;        
+        
+        TUint8      iSample[KITTBufferSize];
+        TPtr8       iSampleDescriptor;
+        TProfilerGppSamplerData*     gppSamplerData;
+    };
+
+#endif  //__PI_ITT_EVENT_HANDLER__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/IttSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,327 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#ifndef PROFILER_ITT_SAMPLER_H
+#define PROFILER_ITT_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+#include "IttEventHandler.h"
+
+// CONSTANTS
+const TInt KITTSampleBufferSize = 256;
+
+// flags
+#define ITT_EVENT_HANDLER   // enable event based ITT sampling
+
+/*
+ *	
+ *	ITT sampler definition
+ *	
+ */
+class DIttEventHandler;
+
+/*
+ * User side ITT sampler
+ */
+class IttSamplerImpl
+{
+public:
+	IttSamplerImpl();
+	~IttSamplerImpl();
+
+	TInt	SampleImpl(TUint32 pc,TUint32 sampleNum);
+	TBool	SampleNeeded(TUint32 sampleNum);
+	TInt 	CreateFirstSample();
+	void	Reset();
+	TInt    ProcessEvent();
+	
+	TUint8*         itt_sample;
+	TInt            iIttSamplingPeriod;
+	TInt            iIttSamplingPeriodDiv2;
+	TBool           iTimeToSample;
+#ifdef ITT_EVENT_HANDLER
+    TBool           iEventReceived;
+    TBool           iFirstSampleTaken;
+#endif
+	
+private:
+#ifdef ITT_EVENT_HANDLER    
+    TInt            iCount;
+#endif
+    TInt            currentLibCount;
+    TInt            currentProcCount;
+    
+	TUint8          sample[KITTSampleBufferSize ];
+	TPtr8           sampleDescriptor;
+		
+	TBuf8<64>		iVersionData;
+	SDblQue* 		codeSegList;
+
+};
+
+/*
+ * ITT sampler kernel part
+ * 
+ */
+template <int BufferSize>
+class DProfilerIttSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+	DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn);
+	~DProfilerIttSampler();
+
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+	TInt	PostSample();
+	TBool	PostSampleNeeded();
+
+private:
+#ifdef ITT_EVENT_HANDLER
+    DIttEventHandler*               iEventHandler;
+#endif
+	IttSamplerImpl					ittSamplerImpl;
+	struct TProfilerGppSamplerData*     gppSamplerData;
+	TBool							sampleInProgress;
+	TBool							sampleNeeded;
+};
+
+/*  
+ *	ITT sampler implementation
+ *	
+ */ 
+template <int BufferSize>
+DProfilerIttSampler<BufferSize>::DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) :
+	DProfilerGenericSampler<BufferSize>(PROFILER_ITT_SAMPLER_ID)
+{
+	this->gppSamplerData = (struct TProfilerGppSamplerData*)gppSamplerDataIn;
+	this->sampleInProgress = false;
+	LOGSTRING2("CProfilerIttSampler<%d>::CProfilerIttSampler",BufferSize);	
+}
+
+/*
+ *  DProfilerIttSampler::Reset()
+ *  
+ *  @param DProfilerSampleStream* sample stream
+ *  @param TUint32 Offset 
+ */
+template <int BufferSize>
+TInt DProfilerIttSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+{
+    Kern::Printf("DProfilerIttSampler<%d>::Reset - calling superclass reset",BufferSize);
+    DProfilerGenericSampler<BufferSize>::Reset(aStream);
+
+    // check if reset called in stop (by driver)
+    if(aSyncOffset != 999999)
+        {
+#ifdef ITT_EVENT_HANDLER
+        // Itt event handler
+        if(iEventHandler)
+            {
+            // stop previous sampling if still running
+            Kern::Printf("Stopping DIttEventHandler");
+            iEventHandler->Stop();
+            iEventHandler->Close();
+            iEventHandler = NULL;
+            }
+    
+        Kern::Printf("Initiating DIttEventHandler");
+        iEventHandler = new DIttEventHandler(this->iSampleBuffer, this->gppSamplerData);
+        if(iEventHandler)
+            {
+            Kern::Printf("Creating DIttEventHandler");
+            TInt err(iEventHandler->Create());
+            if(err != KErrNone)
+                {
+                Kern::Printf("Error in creation of DIttEventHandler, error %d", err);
+                return err;
+                }
+            }
+        else
+            {
+            Kern::Printf("Could not initiate DIttEventHandler");
+            return KErrGeneral;
+            }
+    
+        // set first sample at the 10 ms, should be enough
+        this->ittSamplerImpl.iIttSamplingPeriod = 10;
+#else
+        this->ittSamplerImpl.iIttSamplingPeriod = this->iSamplingPeriod;
+#endif
+        this->ittSamplerImpl.iIttSamplingPeriodDiv2 = (TInt)(this->ittSamplerImpl.iIttSamplingPeriod / 2);
+        LOGSTRING3("CProfilerIttSampler<%d>::Reset - set ITT sampling period to %d",
+                                BufferSize,this->ittSamplerImpl.iIttSamplingPeriod);
+        }
+    else
+        {
+        LOGSTRING2("DProfilerIttSampler<%d>::Reset - reset in stop", BufferSize);
+#ifdef ITT_EVENT_HANDLER
+        // destroy memory event handler
+        if(iEventHandler)
+            {
+            // stop previous sampling if still running
+            iEventHandler->Stop();
+            iEventHandler->Close();
+            iEventHandler = NULL;
+            }
+#endif
+        return KErrNone;    // return if reset called in stop
+        }
+
+    TInt length(ittSamplerImpl.CreateFirstSample());
+    this->iSampleBuffer->AddSample((TUint8*)&length,1);
+    this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample, length);
+    this->sampleInProgress = false;
+    this->sampleNeeded = false;
+    //LOGSTRING("DProfilerIttSampler::Reset - exit");
+	this->ittSamplerImpl.Reset();
+    return KErrNone;
+
+}
+
+/*
+ * DProfilerIttSampler::PostSample
+ * 
+ * Function for finishing sample
+ */
+template <int BufferSize> 
+TInt DProfilerIttSampler<BufferSize>::PostSample()
+{
+#ifdef ITT_EVENT_HANDLER
+    if(!ittSamplerImpl.iFirstSampleTaken)   // if we haven't read the initial state
+    {
+#endif
+        if(sampleNeeded)
+        {
+            this->sampleNeeded = false;
+            //LOGSTRING3("CProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+            //Kern::Printf("DProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+    
+            TInt length = this->ittSamplerImpl.SampleImpl(this->gppSamplerData->lastPcValue,
+                                                          this->gppSamplerData->sampleNumber);
+            if(length != 0)
+            {		
+                LOGSTRING("ITT sampler PostSample - starting to sample");
+    
+                while(length > 0)
+                {
+                    this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample,length);
+                    length = this->ittSamplerImpl.SampleImpl( this->gppSamplerData->lastPcValue,
+                                                          this->gppSamplerData->sampleNumber );	
+                    if(length == 0) 
+                    {
+                        LOGSTRING("MEM sampler PostSample - all samples generated!");
+                    }
+                }
+                LOGSTRING("ITT sampler PostSample - finished sampling");
+            }
+            this->sampleInProgress = false;
+        }
+#ifdef ITT_EVENT_HANDLER
+    }   
+        if(!iEventHandler->Tracking())
+            {
+            iEventHandler->Start();
+            Kern::Printf("DProfilerITTSampler<%d>::PostSample - ITT handler started",BufferSize);
+            }
+
+#endif    
+	
+    LOGSTRING2("ITT sampler PostSample - finished sampling, time: %d", gppSamplerData->sampleNumber);
+    
+	// finally perform superclass postsample
+	TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+	return i;
+}
+
+/*
+ *  DProfilerIttSampler::PostSampleNeeded()
+ *  
+ *  Function for deciding if sample handling is needed 
+ */
+template <int BufferSize> 
+TBool DProfilerIttSampler<BufferSize>::PostSampleNeeded()
+{
+	LOGSTRING3("CProfilerIttSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+	TUint32 status = this->iSampleBuffer->iBufferStatus;
+
+	if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+/*
+ * DProfilerIttSampler::Sample
+ * 
+ * Function for initiating sampling
+ */
+template <int BufferSize>
+void DProfilerIttSampler<BufferSize>::Sample()
+{
+	LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);	
+	
+	//#ifdef ITT_TEST
+	LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);	
+	
+	if(ittSamplerImpl.SampleNeeded(this->gppSamplerData->sampleNumber) && this->sampleInProgress == false) 
+	{
+		this->sampleInProgress = true;
+		this->sampleNeeded = true;
+
+		LOGSTRING2("CProfilerIttSampler<%d>::Sample - sample needed",BufferSize);	
+	}	
+#ifdef ITT_EVENT_HANDLER
+    // call this to increase the time stamp
+    else if(iEventHandler->SampleNeeded())
+        {
+        // set the flag for post sampling
+        this->sampleNeeded = true;
+        }
+#endif
+
+	LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);
+	return;
+}
+
+/*
+ * Destructor
+ */
+template <int BufferSize>
+DProfilerIttSampler<BufferSize>::~DProfilerIttSampler()
+{
+	LOGSTRING2("CProfilerIttSampler<%d>::~CProfilerIttSampler",BufferSize);
+#ifdef ITT_EVENT_HANDLER
+     if(iEventHandler)
+         {
+         // stop previous sampling if still running
+         iEventHandler->Stop();
+         iEventHandler->Close();
+         iEventHandler = NULL;
+         }
+#endif
+}
+#endif
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/MemSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_MEM_SAMPLER_H
+#define PROFILER_MEM_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+#include "MemoryEventHandler.h"
+#include <e32btrace.h>
+
+
+// constants
+// defines the maximum thread amount that is assumed to
+// be possible with MEM trace
+const TInt KSampleBufferSize = 257;
+const TInt KProfilerMaxThreadsAmount = 512;
+const TInt KProfilerMaxChunksAmount = 1024;
+const TInt KProfilerMaxLibrariesAmount = 1024;
+const TInt KProfilerTotalMemorySamplePeriod = 100;
+
+// flags
+#define MEM_EVENT_HANDLER
+//#define MEM_EVENT_HANDLER_LIBRARY_EVENTS
+
+/*
+ *	
+ *	MEM sampler definition
+ *	
+ */
+
+class DMemoryEventHandler;
+
+class DMemSamplerImpl //: public DBase
+{
+public:
+	enum EProcessingState
+	{
+		EStartingToProcess,
+		EProcessingNames,
+		EProcessingData,
+		ENothingToProcess
+	};
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	enum ESampleType
+	{
+	    ESampleChunks,
+	    ESampleThreads,
+	    ESampleLibraries
+	};
+#endif
+
+	DMemSamplerImpl();
+	~DMemSamplerImpl();
+
+	TInt	CreateFirstSample();
+	TInt	SampleImpl();
+	TBool	SampleNeeded();
+	void	Reset();
+	TInt	ProcessChunks();
+	TInt    ProcessThreads();
+    TInt    GatherChunks();
+    TInt    GatherThreads();
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+    TInt    GatherLibraries();
+    TInt    ProcessLibraries();
+#endif
+    
+	TInt	EncodeChunkData(DChunk& chunk);
+	TInt	EncodeChunkName(DChunk& chunk);
+	TInt	EncodeChunkData(DThread& thread);
+	TInt	EncodeChunkName(DThread& thread);
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	TInt    EncodeChunkData(DLibrary& library);
+	TInt    EncodeChunkName(DLibrary& library);
+#endif
+
+	TInt 	EncodeTotalMemoryName();
+	TInt 	EncodeTotalMemory();
+	
+	TInt	EncodeNameCode();
+	TInt	EncodeDataCode();
+
+	DChunk*		heapChunksToSample[KProfilerMaxChunksAmount];
+	DChunk*		heapChunkNamesToReport[KProfilerMaxChunksAmount];
+	TInt		iCount;
+	TInt		iChunkCount;
+	TInt		iNewChunkCount;
+	TBuf8<0x50> name;
+	DThread*	threadsToSample[KProfilerMaxThreadsAmount];
+	DThread*	threadNamesToReport[KProfilerMaxThreadsAmount];
+	TInt		iThreadCount;
+	TInt		iNewThreadCount;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	DLibrary*   librariesToSample[KProfilerMaxLibrariesAmount];
+	DLibrary*   libraryNamesToReport[KProfilerMaxLibrariesAmount];
+	TInt        iLibraryCount;
+	TInt        iNewLibraryCount;
+	TInt        iLibrariesProcessing;
+#endif
+
+	TInt		iChunksProcessing;
+    TInt        iThreadsProcessing;
+	TInt		iMemSamplingPeriod;
+	TInt		iMemSamplingPeriodDiv2;
+	TInt        iMemSamplingPeriodDiv3;
+	
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	ESampleType iSampleType;
+#else
+	TBool		iSampleThreads;
+#endif	
+	
+	TBool       iTimeToSample;
+	
+	TBool 		iTotalMemoryOk;
+	TBool		iTotalMemoryNameOk;
+
+	TUint8		sample[KSampleBufferSize];
+	TPtr8		sampleDescriptor;
+	
+	// test
+#ifdef MEM_EVENT_HANDLER
+//	DMemoryEventHandler*   iEventHandler;
+	TBool      iChunksGathered;
+	TBool      iThreadsGathered;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	TBool      iLibrariesGathered;
+#endif
+#endif
+};
+
+
+template <int BufferSize>
+class DProfilerMemSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+	DProfilerMemSampler(struct TProfilerGppSamplerData*, TInt id);
+	~DProfilerMemSampler();
+
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+	TInt	PostSample();
+	TBool	PostSampleNeeded();
+	
+private:
+#ifdef MEM_EVENT_HANDLER
+    DMemoryEventHandler*               iEventHandler;
+#endif
+	DMemSamplerImpl			           memSamplerImpl;
+	struct TProfilerGppSamplerData*    gppSamplerData;
+	TBool                              sampleNeeded;
+};
+
+/*
+ *	
+ *	MEM sampler implementation
+ *	
+ */
+
+template <int BufferSize>
+DProfilerMemSampler<BufferSize>::DProfilerMemSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id) :
+	DProfilerGenericSampler<BufferSize>(PROFILER_MEM_SAMPLER_ID)
+    {
+    LOGSTRING2("DProfilerMemSampler<%d>::CProfilerMemSampler",BufferSize);
+	this->gppSamplerData = gppSamplerDataIn;
+	this->iSamplingPeriod = 3000;	// set default setting
+    }
+
+template <int BufferSize>
+TInt DProfilerMemSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+    {
+//#ifdef MEM_EVENT_HANDLER
+//    Kern::Printf("DProfilerMemSampler<%d>::Reset - calling superclass reset",BufferSize);
+    
+//#endif
+    // check if reset called in stop (by driver)
+    if(aSyncOffset != 999999)
+        {
+        DProfilerGenericSampler<BufferSize>::Reset(aStream);
+        memSamplerImpl.Reset();
+
+#ifdef MEM_EVENT_HANDLER
+        // reset member variables
+        this->memSamplerImpl.iThreadsGathered = false;
+        this->memSamplerImpl.iChunksGathered = false;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+        this->memSamplerImpl.iLibrariesGathered = false;
+#endif
+        
+        // memory event handler
+        if(iEventHandler)
+            {
+            // stop previous sampling if still running
+//            Kern::Printf("Stopping DMemoryEventHandler");
+            iEventHandler->Stop();
+            iEventHandler->Close();
+            iEventHandler = NULL;
+            }
+    
+//        Kern::Printf("Initiating DMemoryEventHandler");
+        iEventHandler = new DMemoryEventHandler(this->iSampleBuffer);
+        if(iEventHandler)
+            {
+//            Kern::Printf("Creating DMemoryEventHandler");
+            TInt err(iEventHandler->Create());
+            if(err != KErrNone)
+                {
+                Kern::Printf("Error in creation of DMemoryEventHandler, error %d", err);
+                return err;
+                }
+            }
+        else
+            {
+            Kern::Printf("Could not initiate DMemoryEventHandler");
+            return KErrGeneral;
+            }
+    
+        // set first chunk&thread memory lookup at the 5 ms, should be enough
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+        this->memSamplerImpl.iMemSamplingPeriod = 45;
+#else
+        this->memSamplerImpl.iMemSamplingPeriod = 10;
+#endif
+        
+#else
+        this->memSamplerImpl.iMemSamplingPeriod = this->iSamplingPeriod;
+#endif
+        this->memSamplerImpl.iMemSamplingPeriodDiv2 = (TInt)(this->memSamplerImpl.iMemSamplingPeriod / 2);
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+        this->memSamplerImpl.iMemSamplingPeriodDiv3 = (TInt)(this->memSamplerImpl.iMemSamplingPeriod / 3);
+#endif
+	
+        LOGSTRING3("CProfilerMemSampler<%d>::Reset - set mem sampling period to %d",
+                                BufferSize,this->memSamplerImpl.iMemSamplingPeriod);
+        }
+	else
+        {
+        LOGSTRING2("DProfilerMemSampler<%d>::Reset - reset in stop", BufferSize);
+#ifdef MEM_EVENT_HANDLER
+        // destroy memory event handler
+        if(iEventHandler)
+            {
+            // stop previous sampling if still running
+//            Kern::Printf("Stopping DMemoryEventHandler");
+            iEventHandler->Stop();
+            iEventHandler->Close();
+            iEventHandler = NULL;
+            }
+#endif
+        return KErrNone;    // return if reset called in stop
+        }
+
+	// add MEM sample header
+	TInt length(memSamplerImpl.CreateFirstSample());
+	this->iSampleBuffer->AddSample(memSamplerImpl.sample,length);
+	
+	this->sampleNeeded = false;
+	LOGSTRING("DProfilerMemSampler::Reset - exit");
+	return KErrNone;
+    }
+
+template <int BufferSize> 
+TInt DProfilerMemSampler<BufferSize>::PostSample()
+    {
+    this->sampleNeeded = false;
+
+    LOGSTRING3("DProfilerMemSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+    
+#ifdef MEM_EVENT_HANDLER
+    // check if all threads and chunks (and libraries) are gathered
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+    if(!memSamplerImpl.iThreadsGathered || !memSamplerImpl.iChunksGathered || !memSamplerImpl.iLibrariesGathered)
+#else
+    if(!memSamplerImpl.iThreadsGathered || !memSamplerImpl.iChunksGathered)
+#endif
+        {
+#endif
+        // disable interrupts for checking the kernel containers (EChunk, EThread)
+//        TInt interruptLevel(NKern::DisableInterrupts(0));
+        
+        // first collect chunk data
+        TInt length(this->memSamplerImpl.SampleImpl());
+        if(length != 0)
+            {
+            // then, encode the sample to the buffer until no further data available
+            while(length > 0)
+                {
+                this->iSampleBuffer->AddSample(memSamplerImpl.sample,length);
+                length = this->memSamplerImpl.SampleImpl();
+                
+                // indicate that the whole MEM sample ends by having a 0x00 in the end
+                if(length == 0)
+                    {
+                    TUint8 number(0);
+                    LOGSTRING("MEM sampler PostSample - all samples generated!");
+                    
+                    this->iSampleBuffer->AddSample(&number,1);
+                    LOGSTRING2("MEM sampler PostSample - end mark added, time: %d", gppSamplerData->sampleNumber);
+                    }
+                } 
+            }
+        // restore interrupts and continue normal execution
+//        NKern::RestoreInterrupts(interruptLevel);
+#ifdef MEM_EVENT_HANDLER
+    }
+    // check if all threads and chunks are gathered
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+    if(memSamplerImpl.iThreadsGathered && memSamplerImpl.iChunksGathered && memSamplerImpl.iLibrariesGathered)
+#else
+    if(memSamplerImpl.iThreadsGathered && memSamplerImpl.iChunksGathered)
+#endif
+        {
+        // start memory event tracking after checking the current memory status
+        if(!iEventHandler->Tracking())
+            {
+            iEventHandler->Start();
+//            Kern::Printf("DProfilerMemSampler<%d>::PostSample - memory event handler started",BufferSize);
+            }
+        
+        }
+#endif
+    
+    LOGSTRING2("MEM sampler PostSample - finished sampling, time: %d", gppSamplerData->sampleNumber);
+    
+    // finally perform superclass postsample
+	TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+	return i;
+    }
+
+template <int BufferSize> 
+TBool DProfilerMemSampler<BufferSize>::PostSampleNeeded()
+    {
+	LOGSTRING3("DProfilerMemSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+	TUint32 status(this->iSampleBuffer->iBufferStatus);
+
+	if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+	    {
+		return true;
+	    }
+	
+	return false;
+    }
+
+template <int BufferSize>
+void DProfilerMemSampler<BufferSize>::Sample()
+    {
+    LOGSTRING2("DProfilerMemSampler<%d>::Sample",BufferSize);	
+
+    // check if sample is needed, i.e. the sampling interval is met
+	if(memSamplerImpl.SampleNeeded()) 
+	    {
+        // set the flag for post sampling
+		this->sampleNeeded = true;
+
+		// start the MEM sample with the sample time
+		TUint8 number(4);    // mem sampler id
+		this->iSampleBuffer->AddSample(&number,1);
+		this->iSampleBuffer->AddSample((TUint8*)&(gppSamplerData->sampleNumber),4);
+
+		// leave the rest of the processing for PostSample()
+	    }	
+	
+#ifdef MEM_EVENT_HANDLER
+	// call this to increase the time stamp
+	else if(iEventHandler->SampleNeeded())
+	    {
+        // set the flag for post sampling
+        this->sampleNeeded = true;
+	    }
+	
+//	// check if time stamp is divibable with 
+//	if((memSamplerImpl.iCount % KProfilerTotalMemorySamplePeriod) == 0 && 
+//	        memSamplerImpl.iCount > 0)
+//	    {
+//        // sample total memory once per 100 ms 
+//        memSamplerImpl.EncodeTotalMemory();
+//
+//        // add end mark
+//        TUint8 number(0);
+//        this->iSampleBuffer->AddSample(&number,1);
+//	    }
+#endif
+	
+	LOGSTRING2("CProfilerMemSampler<%d>::Sample",BufferSize);
+	return;
+    }
+
+template <int BufferSize>
+DProfilerMemSampler<BufferSize>::~DProfilerMemSampler()
+    {
+	LOGSTRING2("CProfilerMemSampler<%d>::~CProfilerMemSampler",BufferSize);		
+#ifdef MEM_EVENT_HANDLER
+    // memory event handler
+     if(iEventHandler)
+         {
+         // stop previous sampling if still running
+//         Kern::Printf("Stopping DMemoryEventHandler");
+         iEventHandler->Stop();
+         iEventHandler->Close();
+         iEventHandler = NULL;
+         }
+#endif
+    }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/MemoryEventHandler.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+#include "MemSamplerImpl.h"
+
+#ifndef __PI_MEMORY_EVENT_HANDLER__
+#define __PI_MEMORY_EVENT_HANDLER__
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+// CONSTANTS
+const TInt KEventBufferSize = 257;
+
+class DProfilerSampleBuffer;
+
+class DMemoryEventHandler : public DKernelEventHandler
+    {
+public:
+    // constructor
+    DMemoryEventHandler(DProfilerSampleBuffer*  aSampleBuffer);
+    TInt Create();
+    ~DMemoryEventHandler();
+    TInt Start();
+    TInt Stop();
+    TBool Tracking() {return iTracking;}
+       
+    TBool SampleNeeded();
+    
+private:
+    static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
+    TUint HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2);
+    // handle chunk activity
+    TBool HandleAddChunk(DChunk* aChunk);
+    TBool HandleUpdateChunk(DChunk* aChunk);
+    TBool HandleDeleteChunk(DChunk* aChunk);
+    // handle chunk activity
+    TBool HandleAddThread(DThread* aThread);
+    TBool HandleUpdateThread(DThread* aThread);
+    TBool HandleDeleteThread(DThread* aThread);
+    // handle chunk activity
+    TBool HandleAddProcess(DProcess* aProcess);
+    TBool HandleUpdateProcess(DProcess* aProcess);
+    TBool HandleDeleteProcess(DProcess* aProcess);
+    // handle library activity
+    TBool HandleAddLibrary(DLibrary* aLibrary, DThread* aThread);
+    TBool HandleDeleteLibrary(DLibrary* aLibrary);
+    
+    // data handling
+    TInt AddHeader();
+    TInt AddFooter();
+    TInt EncodeTotalMemory();
+    TInt EncodeNameCode();
+    TInt EncodeNewCode();
+    TInt EncodeUpdateCode();
+    TInt EncodeRemoveCode();
+    TInt EncodeChunkName(DThread& t);
+    TInt EncodeChunkName(DChunk& c);
+    TInt EncodeChunkName(DLibrary& l);
+    TInt EncodeChunkData(DThread& t);
+    TInt EncodeChunkData(DChunk& c);
+    TInt EncodeChunkData(DLibrary& l, DThread& t);
+private:
+    /** Lock serialising calls to event handler */
+    DMutex* iLock;
+    TBool iTracking;
+
+    DProfilerSampleBuffer*  iSampleBuffer;
+    TInt iCounters[EEventLimit];
+    
+    TUint32     iCount;
+    
+    TUint8      iSample[KEventBufferSize];
+    TPtr8       iSampleDescriptor;
+    
+    TUint32     iPreviousCount;
+    };
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/PriSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,245 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_PRI_SAMPLER_H
+#define PROFILER_PRI_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+
+// defines the maximum thread amount that is assumed to
+// be possible with PRI trace
+const TInt KProfilerMaxThreadAmount = 512;
+
+/*
+ *	
+ *	PRI sampler definition
+ *	
+ */
+
+class DPriSamplerImpl //: public DBase
+{
+public:
+	enum EProcessingState
+	{
+		EStartingToProcess,
+		EProcessingNames,
+		EProcessingData,
+		ENothingToProcess
+	};
+
+	DPriSamplerImpl();
+	~DPriSamplerImpl();
+
+	TInt	CreateFirstSample();
+	TInt	SampleImpl();
+	TBool	SampleNeeded();
+	void	Reset();
+	TInt	ProcessChunks();
+
+	TInt	EncodeChunkData(DThread& thread);
+	TInt	EncodeChunkName(DThread& thread);
+	
+	TInt	EncodeNameCode();
+	TInt	EncodeDataCode();
+
+	TInt		iCountti;
+	DThread*	threadsToSample[KProfilerMaxThreadAmount];
+	DThread*	threadNamesToReport[KProfilerMaxThreadAmount];
+
+	TInt		iThreadCount;
+	TInt		iNewThreadCount;
+
+	TInt		iProcessing;
+	TInt		iPriSamplingPeriod;
+
+	TUint8		sample[257];
+	TPtr8		sampleDescriptor;
+#ifdef __SMP__
+    TInt        iCpuNumber;
+    TUint32     iStartTime;
+#endif   
+
+};
+
+template <int BufferSize>
+class DProfilerPriSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+	DProfilerPriSampler(struct TProfilerGppSamplerData*, TInt id);
+	~DProfilerPriSampler();
+
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+	TInt	PostSample();
+	TBool	PostSampleNeeded();
+
+private:
+	DPriSamplerImpl				 	priSamplerImpl;
+	struct TProfilerGppSamplerData* 	    gppSamplerData;
+	TBool						 	sampleNeeded;
+	TBool							sampleInProgress;
+#ifdef __SMP__
+    TInt   iCpuNumber;
+#endif
+};
+
+/*
+ *	
+ *	PRI sampler implementation
+ *	
+ */
+//#ifndef __SMP__
+template <int BufferSize>
+DProfilerPriSampler<BufferSize>::DProfilerPriSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id) :
+	DProfilerGenericSampler<BufferSize>(PROFILER_PRI_SAMPLER_ID)
+    {
+	LOGSTRING2("CProfilerPriSampler<%d>::CProfilerPriSampler",BufferSize);
+	this->gppSamplerData = gppSamplerDataIn;
+	this->sampleInProgress = false;
+	this->iSamplingPeriod = 3000;	// set default setting
+    }
+//#else
+//template <int BufferSize>
+//DProfilerPriSampler<BufferSize>::DProfilerPriSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id, TInt aCpuNumber) :
+//    DProfilerGenericSampler<BufferSize>(PROFILER_PRI_SAMPLER_ID+(aCpuNumber*20)), iCpuNumber(aCpuNumber) 
+//    {
+//    LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+//    }
+//#endif
+
+template <int BufferSize>
+TInt DProfilerPriSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+    {
+	LOGSTRING2("CProfilerPriSampler<%d>::Reset - calling superclass reset",BufferSize);
+	DProfilerGenericSampler<BufferSize>::Reset(aStream);
+	LOGSTRING2("CProfilerPriSampler<%d>::Reset - called superclass reset",BufferSize);
+	priSamplerImpl.Reset();
+
+#ifdef __SMP__
+//    this->priSamplerImpl.iCpuNumber = this->iCpuNumber;
+//    
+//    // set common start time for all CPU samplers
+//    this->priSamplerImpl.iStartTime = aSyncOffset;
+#endif
+	this->priSamplerImpl.iPriSamplingPeriod = this->iSamplingPeriod;
+
+
+	LOGSTRING3("CProfilerPriSampler<%d>::Reset - set pri sampling period to", 
+							BufferSize,this->priSamplerImpl.iPriSamplingPeriod);
+
+	TInt length(priSamplerImpl.CreateFirstSample());
+	this->iSampleBuffer->AddSample(priSamplerImpl.sample,length);
+
+	this->sampleInProgress = false;	
+	this->sampleNeeded = false;
+
+	return KErrNone;
+    }
+
+template <int BufferSize> 
+TInt DProfilerPriSampler<BufferSize>::PostSample()
+    {
+	if(sampleNeeded)
+	    {
+		this->sampleNeeded = false;
+
+		LOGSTRING3("CProfilerPriSampler<%d>::PostSample - state %d",BufferSize,this->sampleBuffer->GetBufferStatus());
+		
+		//TInt interruptLevel = NKern::DisableInterrupts(0);
+		
+		TInt length(this->priSamplerImpl.SampleImpl());
+		if(length != 0)
+		    {
+			LOGSTRING("PRI sampler PostSample - starting to sample");
+
+			// then, encode the sample to the buffer
+			while(length > 0)
+			    {
+			    this->iSampleBuffer->AddSample(priSamplerImpl.sample,length);
+				length = this->priSamplerImpl.SampleImpl();
+				// indicate that the whole PRI sample ends by having a 0x00 in the end
+				if(length == 0)
+				    {
+					TUint8 number(0);
+					LOGSTRING("PRI sampler PostSample - all samples generated!");
+					
+					this->iSampleBuffer->AddSample(&number,1);
+					LOGSTRING("PRI sampler PostSample - end mark added");
+                    }
+			    }
+			LOGSTRING("PRI sampler PostSample - finished sampling");
+		    }
+		this->sampleInProgress = false;
+		
+		//NKern::RestoreInterrupts(interruptLevel);
+	    }
+	
+	// finally perform superclass postsample
+	TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+	return i; 
+    }
+
+template <int BufferSize> 
+TBool DProfilerPriSampler<BufferSize>::PostSampleNeeded()
+    {
+	LOGSTRING3("CProfilerPriSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->sampleBuffer->GetBufferStatus());
+
+	TUint32 status = this->iSampleBuffer->iBufferStatus;
+
+	if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+	    {
+		return true;
+	    }
+	
+	return false;
+    }
+
+
+template <int BufferSize>
+void DProfilerPriSampler<BufferSize>::Sample()
+    {
+	LOGSTRING2("CProfilerPriSampler<%d>::Sample",BufferSize);	
+	
+	if(priSamplerImpl.SampleNeeded() && this->sampleInProgress == false) 
+	    {
+		this->sampleInProgress = true;
+		this->sampleNeeded = true;
+		// start the PRI sample with the sample time
+		TUint8 number(4);
+		this->iSampleBuffer->AddSample(&number,1);
+		this->iSampleBuffer->AddSample((TUint8*)&(gppSamplerData->sampleNumber),4);
+
+		// leave the rest of the processing for PostSample()
+	    }	
+
+	LOGSTRING2("CProfilerPriSampler<%d>::Sample",BufferSize);
+	return;
+    }
+
+template <int BufferSize>
+DProfilerPriSampler<BufferSize>::~DProfilerPriSampler()
+    {
+	LOGSTRING2("CProfilerPriSampler<%d>::~CProfilerPriSampler",BufferSize);		
+    }
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,1152 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+//
+// LDD for thread time profiling
+//
+
+#include <kern_priv.h>
+#include <platform.h>
+#include <arm.h>
+
+#ifdef __SMP__
+#include <assp/naviengine/naviengine.h> 
+#include <nkernsmp/arm/arm_gic.h>
+#include <nkernsmp/arm/arm_tmr.h>
+#endif
+
+#include "GeneralsDriver.h"
+#include <piprofiler/PluginDriver.h>
+#include <piprofiler/PluginSampler.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include "GppSamplerImpl.h"
+#include "GfcSamplerImpl.h"
+#include "IttSamplerImpl.h"
+#include "MemSamplerImpl.h"
+#include "PriSamplerImpl.h"
+
+
+#ifndef __SMP__
+extern TUint* IntStackPtr();
+extern void UsrModLr(TUint32*);
+#endif
+// for security check
+#define KProfilerExeSecurUid 0x2001E5AD
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
+
+#define SEPARATE_DFC_QUEUE
+// CONSTANTS
+
+//_LIT(DProfilerThread,"DProfilerThread");
+//const TInt KDProfilerThreadPriority = 27;
+
+#ifdef SEPARATE_DFC_QUEUE
+const TInt KGeneralsDriverThreadPriority = 24;
+_LIT(KGeneralsDriverThread, "PIGeneralsDriver");
+
+#endif
+
+// global Dfc Que
+//TDynamicDfcQue* gDfcQ;
+
+//#ifdef __SMP__
+//
+//enum  TNaviEngineAsspInterruptIdExtension
+//{
+//    KIntProfilerBase = 99      //  Sampling profiler interrupt base. 
+//    //  Each CPU is assigned a sampling interrupt from this base
+//    //  CPU-0's sampling interrupt is KIntIdSamplingBase + 0
+//    //  CPU-n's sampling interrupt is KIntIdSamplingBase + n
+//};
+//#endif
+
+/*
+ *
+ *
+ *	Class DGfcProfilerFactory definition
+ *
+ *
+ */
+
+class DGeneralsProfilerFactory : public DLogicalDevice
+{
+	public:
+		DGeneralsProfilerFactory();
+		~DGeneralsProfilerFactory();
+
+	public:
+		virtual TInt Install();
+		virtual void GetCaps(TDes8& aDes) const;
+		virtual TInt Create(DLogicalChannelBase*& aChannel);
+};
+
+/*
+ *
+ *
+ *	Class DGfcDriver definition
+ *
+ *
+ */
+class DPluginDriver;
+
+class DGeneralsDriver : public DPluginDriver
+{
+
+public:
+	DGeneralsDriver();
+	~DGeneralsDriver();
+
+private:
+	TInt					NewStart(TInt aRate);
+	static void				NewDoProfilerProfile(TAny*);
+	static void				NewDoDfc(TAny*);
+	
+	// called by each core
+	static void				Sample(TAny*);
+
+	TInt					GetSampleTime(TUint32* time);
+	//TInt					Test(TUint32 testCase); 
+
+	TInt					StartSampling();
+	TInt                    StopSampling();
+
+	void					InitialiseSamplerList(); 
+
+	DProfilerSamplerBase*	GetSamplerForId(TInt samplerId);
+	TInt					GetSamplerVersion(TDes* aDes);
+	
+#ifdef __SMP__
+	void                    UnbindInterrupts();
+#endif
+	TInt					ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus);
+
+	TInt					MarkTraceActive(TInt samplerIdToActivate);
+	TInt					MarkTraceInactive(TInt samplerIdToDisable);
+	TInt					OutputSettingsForTrace(TInt samplerId,TInt settings);
+	TInt					AdditionalTraceSettings(TInt samplerId,TInt settings);
+	TInt					AdditionalTraceSettings2(TInt samplerId,TInt settings);
+	TInt					SetSamplingPeriod(TInt /*samplerId*/,TInt settings);
+private:
+	// create the driver in EKA-2 version
+	TInt			        DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+
+	// receive commands and control in EKA-2 version
+	void					HandleMsg(TMessageBase* aMsg);
+private:
+	// timer mechanism in EKA-2 version
+	NTimer						iTimer;
+	TDfc						iNewDfc;
+	TInt						iCount;
+	TInt						iLastPcVal;					
+	TInt						iPeriod;
+	
+	// sync sample number property for synchronizing other samplers
+	RPropertyRef 				iSampleStartTimeProp;
+	TInt						iSampleStartTime;
+	
+	DProfilerGppSampler<10000> 	gppSampler;
+#ifdef __SMP__
+	DProfilerGppSampler<10000>  gppSampler2;
+    DProfilerGppSampler<10000>  gppSampler3;
+    DProfilerGppSampler<10000>  gppSampler4;
+#endif
+	DProfilerGfcSampler<10000> 	gfcSampler;
+	DProfilerIttSampler<10000> 	ittSampler;
+	DProfilerMemSampler<40000> 	memSampler;
+	DProfilerPriSampler<10000> 	priSampler;
+#ifdef __SMP__
+//    DProfilerPriSampler<10000>  priSampler2;
+//    DProfilerPriSampler<10000>  priSampler3;
+//    DProfilerPriSampler<10000>  priSampler4;
+#endif
+	
+#ifndef __SMP__
+	static const TInt			KSamplerAmount = 5;
+#else
+    static const TInt           KSamplerAmount = 8;
+#endif
+	DProfilerSamplerBase*		iSamplers[KSamplerAmount];
+    TInt                        iMaxCpus;
+    TUint32                     iStartTime; 
+	
+#ifdef SEPARATE_DFC_QUEUE
+	TDynamicDfcQue*             iDfcQ;
+#endif
+};
+
+/*
+ *
+ *
+ *	Class DGeneralsProfilerFactory implementation
+ *
+ *
+ */
+
+DECLARE_STANDARD_LDD()
+    {
+	return new DGeneralsProfilerFactory();
+    }
+
+TInt DGeneralsProfilerFactory::Create(DLogicalChannelBase*& aChannel)
+    {
+	aChannel = new DGeneralsDriver;
+	return aChannel?KErrNone:KErrNoMemory;
+    }
+
+
+DGeneralsProfilerFactory::DGeneralsProfilerFactory()
+    {
+	// major, minor, and build version number
+    iVersion=TVersion(1,0,1);
+    }
+
+DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
+    {
+//    if (gDfcQ)
+//        {
+//        gDfcQ->Destroy();
+//        }
+    }
+
+TInt DGeneralsProfilerFactory::Install()
+    {
+    return(SetName(&KPluginSamplerName));
+    }
+
+void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const
+    {
+    TCapsSamplerV01 b;
+    
+    b.iVersion=TVersion(1,0,1);
+    
+    aDes.FillZ(aDes.MaxLength());
+    aDes.Copy((TUint8*)&b,Min(aDes.MaxLength(),sizeof(b)));
+    }
+
+/*
+ *
+ *
+ *	Class DGeneralsDriver implementation
+ *
+ *
+ */
+ 
+DGeneralsDriver::DGeneralsDriver() :
+	iTimer(NewDoProfilerProfile,this),
+	iNewDfc(NewDoDfc,this,NULL,7),
+#ifdef __SMP__
+	gppSampler(0),
+	gppSampler2(1),
+    gppSampler3(2),
+    gppSampler4(3),
+#endif
+	gfcSampler(gppSampler.GetExportData()),
+	ittSampler(gppSampler.GetExportData()),
+	memSampler(gppSampler.GetExportData(), PROFILER_MEM_SAMPLER_ID),
+	priSampler(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
+#ifdef __SMP__
+//    ,priSampler2(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
+//    priSampler3(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
+//    priSampler4(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
+#endif
+    {
+	LOGSTRING("DGeneralsDriver::DGeneralsDriver()");
+
+	iState = EStopped;
+	iEndRequestStatus = 0;
+	doingDfc = 0;
+	sampleRunning = 0;
+	iSyncOffset = 0;
+	iStartTime = 0;
+	InitialiseSamplerList();
+    }
+
+/*
+ *
+ *	This method has to be changed for each new sampler
+ *
+ */ 
+void DGeneralsDriver::InitialiseSamplerList()
+	{
+	// initialize all samplers to zero
+	for(TInt i(0);i<KSamplerAmount;i++)
+		{
+		iSamplers[i] = 0;
+		}
+
+	TInt i(0);
+	iSamplers[i] = &gppSampler;i++;
+#ifdef __SMP__
+	iSamplers[i] = &gppSampler2;i++;
+    iSamplers[i] = &gppSampler3;i++;
+    iSamplers[i] = &gppSampler4;i++;
+#endif
+	iSamplers[i] = &gfcSampler;i++;
+	iSamplers[i] = &ittSampler;i++;
+	iSamplers[i] = &memSampler;i++;
+	iSamplers[i] = &priSampler;i++;
+	
+#ifdef __SMP__
+    // get the number of cpus
+    iMaxCpus = NKern::NumberOfCpus();
+#else
+    iMaxCpus = 0;
+#endif
+    
+	// initialize synchronizing property
+	LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property");
+	TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
+    if (r!=KErrNone)
+        {
+        LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
+        }
+    LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
+    r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
+    if (r!=KErrNone)
+        {
+        LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
+        }	
+	}
+
+
+DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet)
+    {
+	for(TInt i(0);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerIdToGet)
+		    {
+			return iSamplers[i];
+		    }
+	    }
+	return (DProfilerSamplerBase*)0;
+    }
+
+TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
+    {
+    TUint8 err(KErrNone);
+    
+    if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
+	   	return KErrNotSupported;
+    
+    // just for testing 
+#ifndef __SMP__
+    LOGTEXT("Initializing the stack pointer");
+    stackTop=(TUint32*)IntStackPtr();
+    LOGSTRING2("Got stack pointer 0x%x",(TUint32)stackTop);
+#endif
+
+    iClient = &Kern::CurrentThread();
+    err = iClient->Open();
+	
+    DProcess* clientProcess(iClient->iOwningProcess);
+    if (clientProcess)
+        {
+        //Require Power Management and All Files to use this driver
+        // Not ideal, but better than nothing
+        if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
+            return KErrPermissionDenied;
+        if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
+            return KErrPermissionDenied;  
+        
+        SSecurityInfo secureInfo = clientProcess->iS;
+        if (secureInfo.iSecureId != KProfilerExeSecurUid)
+            {
+            return KErrPermissionDenied;
+            }
+        }
+    
+    // initiate sample stream ready for collecting the trace data
+	iSampleStream.InsertCurrentClient(iClient);
+	
+	iTimer.Cancel();
+	iNewDfc.Cancel();
+
+	Kern::SetThreadPriority(24);
+
+#ifdef SEPARATE_DFC_QUEUE
+	err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread ));
+	if (KErrNone == err)
+        {
+        SetDfcQ(iDfcQ);
+        iNewDfc.SetDfcQ(iDfcQ);
+        iMsgQ.Receive();
+        return err;
+        }
+#else
+	SetDfcQ(Kern::DfcQue0());
+	iNewDfc.SetDfcQ(iDfcQ);
+	iMsgQ.Receive();
+#endif
+	return err;
+    }
+
+DGeneralsDriver::~DGeneralsDriver()
+    {
+	if (iState!=EStopped)
+	    iTimer.Cancel();
+	iNewDfc.Cancel();
+	
+#ifdef SEPARATE_DFC_QUEUE
+	if(iDfcQ)
+	    iDfcQ->Destroy();
+#endif
+	
+	iSampleStartTimeProp.Close();
+	Kern::SafeClose((DObject*&)iClient,NULL);
+    }
+
+
+TInt DGeneralsDriver::GetSampleTime(TUint32* time)
+    {
+	LOGSTRING("DGeneralsDriver::GetSampleTime - entry");
+
+	Kern::ThreadRawWrite(	iClient,(TAny*)time, 
+							(TAny*)&gppSampler.GetExportData()->sampleNumber, 
+							4, iClient);
+
+	LOGSTRING("DGeneralsDriver::GetSampleTime - exit");
+
+	return KErrNone;
+    }
+
+
+TInt DGeneralsDriver::GetSamplerVersion(TDes* aDes)
+    {
+	LOGSTRING2("DGeneralsDriver::GetSamplerVersion - 0x%x",aDes);
+	
+	TBuf8<16> aBuf;
+	aBuf.Append(PROFILER_SAMPLER_VERSION);
+	Kern::ThreadDesWrite(iClient,aDes,aBuf,0,KChunkShiftBy0,iClient);
+	LOGSTRING("DGeneralsDriver::GetSamplerVersion - written client descriptor");
+	return KErrNone;
+    }
+
+TInt DGeneralsDriver::NewStart(TInt aDelay)
+    {	
+	LOGSTRING("DGeneralsDriver::NewStart");
+	iEndRequestStatus = 0;
+	
+	aDelay = Min(KMaxDelay, Max(KMinDelay, aDelay));
+
+	// always use this rate
+	iPeriod = aDelay;
+	
+#ifdef __SMP__
+    /*
+     * Bind and enable the sampling interupts associated with each core. 
+     */
+    TInt err(0);
+    
+    TUint32 flags = NKern::EIrqBind_Count;
+
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
+    err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0);
+    if(err < 0)
+        Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err );
+    
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
+    err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+    if(err < 0)
+        Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err );
+
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
+    err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+    if(err < 0)
+        Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err );
+
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
+    err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+    if(err < 0)
+        Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err );
+
+
+    err = NKern::InterruptEnable(KIntProfilerBase - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptEnable KIntProfilerBase - 32 ret = %d", err );
+    
+    err = NKern::InterruptEnable(KIntProfilerBase + 1 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptEnable KIntProfilerBase + 1 - 32 ret = %d", err );
+
+    err = NKern::InterruptEnable(KIntProfilerBase + 2 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptEnable KIntProfilerBase + 2 - 32 ret = %d", err );
+
+    err = NKern::InterruptEnable(KIntProfilerBase + 3 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptEnable KIntProfilerBase + 3 - 32 ret = %d", err );
+        
+#endif
+	
+	iTimer.OneShot(aDelay);
+	
+	iState = ERunning;
+
+	return KErrNone;
+    }
+
+/*
+ *	This function is run in each interrupt
+ */
+// EKA-2 implementation of the sampler method
+
+void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
+    {
+    LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
+    
+#ifdef __SMP__      
+    TInt currCpu(NKern::CurrentCpu());
+#endif
+    TInt8 postSampleNeeded(0);
+    DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
+
+	if (d.iState == ERunning && d.sampleRunning == 0)
+	    {
+        // start timer again
+		d.iTimer.Again(d.iPeriod);
+		d.sampleRunning++;
+        
+#ifdef __SMP__      
+        // print out the sample tick
+        if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0) 
+            {
+            Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
+            }
+        // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
+        Sample(aPtr);
+        
+        // post-sampling for NTimer interrupted CPU
+        postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+        
+        /* 
+        This is the master sampler from the watchdog timer, so 
+        send interrupts to the other CPUs
+        */
+        TScheduler *theSched = TScheduler::Ptr();
+        GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
+            
+        for( TInt nCpu(0); nCpu < d.iMaxCpus; nCpu++ )
+            {
+            if( nCpu != currCpu )
+                {
+                gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (KIntProfilerBase + nCpu);
+                }
+            // post-sampling for CPUs with specifically generated interrupts
+            postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
+            }
+        arm_dsb();
+#endif  
+        // then sample the rest of non-cpu samplers
+        for(TInt i(d.iMaxCpus);i<KSamplerAmount;i++)
+            {
+            if(d.iSamplers[i]->iEnabled)
+                {
+                d.iSamplers[i]->Sample();
+                postSampleNeeded += d.iSamplers[i]->PostSampleNeeded();
+                }
+            }
+			
+		if(postSampleNeeded > 0 && d.doingDfc == 0)
+		    {
+			d.doingDfc++;
+			d.iNewDfc.Add();
+
+			d.sampleRunning--;
+			return;
+            }
+		d.sampleRunning--;
+        }
+	else if (d.iState == EStopping && d.sampleRunning == 0)
+	    {
+		// add a dfc for this final time
+		d.iNewDfc.Add();
+        Kern::Printf("DGeneralsDriver::Sample - sampling added to dfc queue");
+        }
+	else
+	    {
+		// the previous sample has not finished,
+		Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
+        }
+        LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
+    }
+
+
+
+void DGeneralsDriver::Sample(TAny* aPtr)
+    {
+    LOGSTRING("DGeneralsDriver::Sample - entry");
+
+#ifdef __SMP__
+    DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
+
+//    TInt currCpu(NKern::CurrentCpu());
+
+    // sample the current cpu load
+//    if(d.iSamplers[currCpu]->iEnabled)
+//        {
+        d.iSamplers[NKern::CurrentCpu()]->Sample();
+//        postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+//        }
+#endif
+    LOGSTRING("DGeneralsDriver::Sample - exit");
+    }
+/*
+ *	This function is run when any of the samplers
+ *	requires post sampling
+ */
+void DGeneralsDriver::NewDoDfc(TAny* pointer)
+    {
+	DGeneralsDriver& d(*((DGeneralsDriver*)pointer));
+	
+	if(d.iState == ERunning)
+	    {
+		// for all enabled samplers, perform
+		// post sample if needed
+		for(TInt i(0);i<KSamplerAmount;i++)
+		    {
+			if(d.iSamplers[i]->iEnabled)
+			    {
+				if(d.iSamplers[i]->PostSampleNeeded())
+				    {
+					d.iSamplers[i]->PostSample();
+                    }
+                }
+            }
+		d.doingDfc--;
+        }
+
+	else if(d.iState == EStopping)
+	    {
+		// for all enabled samplers,
+		// perform end sampling
+		TBool releaseBuffer(false);
+		for(TInt i(0);i<KSamplerAmount;i++)
+		    {
+			if(d.iSamplers[i]->iEnabled)
+			    {
+				LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
+				// perform end sampling for all samplers
+				// stream mode samplers may be pending, if they
+				// are still waiting for another client buffer
+				if(d.iSamplers[i]->EndSampling() == KErrNotReady) 
+				    {
+					LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
+					releaseBuffer = true;
+                    }
+				else 
+				    {
+					LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
+					releaseBuffer = true;
+                    }		
+                }
+            }
+
+		// At the end, once all the samplers are gone through, the buffer should be released
+		if (true == releaseBuffer) 
+		    {
+			LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
+			d.iSampleStream.ReleaseIfPending();	
+            }
+		
+		d.iState = EStopped;
+		if(d.iEndRequestStatus != 0 && d.iClient != 0)
+		    {
+			// sampling has ended
+			Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
+            }
+        }
+    }
+
+
+/*
+ *	All controls are handled here
+ */
+ 
+void DGeneralsDriver::HandleMsg(TMessageBase* aMsg)
+    {
+	TInt r(KErrNone);
+	TThreadMessage& m(*(TThreadMessage*)aMsg);
+
+	LOGSTRING5("DGeneralsDriver::HandleMsg 0x%x 0x%x 0x%x 0x%x",m.Int0(),m.Int1(),m.Int2(),m.Int3());
+	
+	if(m.iValue == (TInt)ECloseMsg)
+	    {
+		LOGSTRING("DGeneralsDriver::HandleMsg - received close message");
+		iTimer.Cancel();
+		iNewDfc.Cancel();
+
+		m.Complete(KErrNone,EFalse);
+		iMsgQ.CompleteAll(KErrServerTerminated);
+		LOGSTRING("DGeneralsDriver::HandleMsg - cleaned up the driver!");
+		return;
+        }
+
+	if (m.Client()!=iClient)
+	    {
+		LOGSTRING("DGeneralsDriver::HandleMsg - ERROR, wrong client");
+		m.PanicClient(_L("GENERALSSAMPLER"),EAccessDenied);
+		return;
+        }
+
+	TInt id(m.iValue);
+	switch(id)
+	    {
+		 //Controls are handled here
+		case RPluginSampler::EMarkTraceActive:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceActive");
+			r = MarkTraceActive((TInt)m.Int0());
+			break;
+
+		case RPluginSampler::EOutputSettingsForTrace:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EOutputSettingsForTrace");
+			r = OutputSettingsForTrace((TInt)m.Int0(),(TInt)m.Int1());
+			break;
+
+		case RPluginSampler::EAdditionalTraceSettings:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings");
+			r = AdditionalTraceSettings((TInt)m.Int0(),(TInt)m.Int1());
+			break;
+
+		case RPluginSampler::EAdditionalTraceSettings2:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings2");
+			r = AdditionalTraceSettings2((TInt)m.Int0(),(TInt)m.Int1());
+			break;
+			
+		case RPluginSampler::ESetSamplingPeriod:
+		    LOGSTRING2("DGeneralsDriver::HandleMsg - ESetSamplingPeriod %d", (TInt)m.Int1());
+			r = SetSamplingPeriod((TInt)m.Int0(),(TInt)m.Int1());
+			break;
+			
+		case RPluginSampler::EMarkTraceInactive:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceInactive");
+			r = MarkTraceInactive((TInt)m.Int0());
+			break;
+
+		case RPluginSampler::ESample:
+			LOGSTRING("DGeneralsDriver::HandleMsg - ESample");
+			//r = Sample();  // hack. Original implementation of sample just returned 0
+			r = 0;
+			break;
+
+		case RPluginSampler::EStartSampling:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
+			r = StartSampling();
+			break;
+
+		case RPluginSampler::EGetSampleTime:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime");
+			r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0()));
+			break;
+
+		case RPluginSampler::EGetSamplerVersion:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSamplerVersion");
+			r = GetSamplerVersion(reinterpret_cast<TDes*>(m.Ptr0()));
+			break;
+		
+		case RPluginSampler::ECancelStreamRead:
+			LOGSTRING("DGeneralsDriver::HandleMsg - ECancelStreamRead");
+			iStreamReadCancelStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
+			r = ProcessStreamReadCancel();
+			break;
+
+
+		 //	Requests are handled here
+
+		case ~RPluginSampler::EStopAndWaitForEnd:
+			LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
+			iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
+			r = StopSampling();
+#ifdef __SMP__
+			UnbindInterrupts();
+#endif
+			break;
+
+		case ~RPluginSampler::ERequestFillThisStreamBuffer:
+			LOGSTRING("DGeneralsDriver::HandleMsg - ERequestFillThisStreamBuffer");			
+			r = ProcessStreamReadRequest(	reinterpret_cast<TBapBuf*>(m.Ptr1()),
+											reinterpret_cast<TRequestStatus*>(m.Ptr0()));
+			break;
+
+		default:
+			LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
+			r = KErrNotSupported;
+			break;
+        }
+
+	LOGSTRING("DGeneralsDriver::HandleMsg - Completed");
+	m.Complete(r,ETrue);
+    }
+
+#ifdef __SMP__
+inline void DGeneralsDriver::UnbindInterrupts()
+    {
+    TInt err(0);
+
+    // disable interrupts when sampling stops, enabled again on start
+    err = NKern::InterruptDisable(KIntProfilerBase - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err );
+    
+    err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err );
+
+    err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err );
+
+    err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err );
+    
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
+    err = NKern::InterruptUnbind( KIntProfilerBase - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err );
+    
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
+    err = NKern::InterruptUnbind( KIntProfilerBase + 1 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptUnbind KIntProfilerBase + 1 - 32 ret = %d", err );
+
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
+    err = NKern::InterruptUnbind(KIntProfilerBase + 2 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptUnbind KIntProfilerBase + 2 - 32 ret = %d", err );
+
+//    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
+    err = NKern::InterruptUnbind(KIntProfilerBase + 3 - 32);
+    if(err < 0)
+        Kern::Printf(" InterruptUnbind KIntProfilerBase + 3 - 32 ret = %d", err );
+
+    }
+#endif
+
+inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus)
+	{
+	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - entry");
+	
+	// a new sample buffer has been received from the client
+	iSampleStream.AddSampleBuffer(aBuf,aStatus);
+	
+	// check if we are waiting for the last data to be written to the client
+	if(iState == EStopped)
+	    {
+		LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest state = EStopped");
+	
+		// sampling has stopped and stream read cancel is pending
+		// try to perform the end sampling procedure again
+		TBool releaseBuffer(false);
+		for(TInt i(0);i<KSamplerAmount;i++)
+		    {
+			// only for all enabled samplers that have stream output mode
+			if(iSamplers[i]->iEnabled /*&& samplers[i]->outputMode == 2*/)
+			    {
+				//TInt pending = 0;
+				// stream mode samplers may be pending, if they
+				// are still waiting for another client buffer,
+				// in that case, the request should be completed already
+				if(iSamplers[i]->EndSampling() == KErrNotReady) 
+				    {
+					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
+					releaseBuffer = true;
+                    }
+				else 
+				    {
+					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
+					releaseBuffer = true;
+                    }
+                }
+            }
+		// At the end, once all the samplers are gone through, the buffer should be released
+		if (true == releaseBuffer) 
+		    {
+			LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
+			iSampleStream.ReleaseIfPending();
+		    }
+        }
+	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit");
+	
+	return KErrNone;
+	}
+
+
+/*
+ *	Mark traces active or inactive, this can be done
+ *	only if sampling is not running
+ */
+
+inline TInt DGeneralsDriver::MarkTraceActive(TInt samplerIdToActivate)
+	{
+	LOGSTRING2("DGeneralsDriver::MarkTraceActive %d",samplerIdToActivate);
+
+	TInt cpus(0);
+#ifdef __SMP__
+	cpus = NKern::NumberOfCpus();
+	if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
+	    {
+	    for(TInt cpu(0);cpu<cpus;cpu++)
+	         {
+	         Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
+	         iSamplers[cpu]->SetEnabledFlag(true);
+	         }
+	    return KErrNone;
+	    }
+#endif
+	for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerIdToActivate)
+		    {
+			iSamplers[i]->SetEnabledFlag(true);
+			return KErrNone;
+            }
+        }
+
+	LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
+	return KErrNotSupported;
+	}
+
+inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable)
+	{
+	LOGSTRING2("DGeneralsDriver::MarkTraceInactive %d",samplerIdToDisable);
+
+    TInt cpus(0);
+#ifdef __SMP__
+    cpus = NKern::NumberOfCpus();
+    if( samplerIdToDisable == PROFILER_GPP_SAMPLER_ID )
+        {
+        for(TInt cpu(0);cpu<cpus;cpu++)
+             {
+             iSamplers[cpu]->SetEnabledFlag(false);
+             }
+        return KErrNone;
+        }
+#endif
+    for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerIdToDisable)
+		    {
+			iSamplers[i]->SetEnabledFlag(false);
+			return KErrNone;
+            }
+        }
+
+	LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
+	return KErrNotSupported;
+	}
+
+/*
+ *	Set output settings for a trace
+ */
+ 
+inline TInt DGeneralsDriver::OutputSettingsForTrace(TInt samplerId,TInt settings)
+	{
+	LOGSTRING3("DGeneralsDriver::OutputSettingsForTrace id:%d set:%d",samplerId,settings);
+
+    TInt cpus(0);
+#ifdef __SMP__
+    cpus = NKern::NumberOfCpus();
+    if( samplerId == PROFILER_GPP_SAMPLER_ID )
+        {
+        for(TInt cpu(0);cpu<cpus;cpu++)
+             {
+             iSamplers[cpu]->SetOutputCombination(settings);
+             }
+        return KErrNone;
+        }
+#endif
+    for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerId)
+		    {
+			iSamplers[i]->SetOutputCombination(settings);
+			return KErrNone;
+		    }
+	    }
+
+	return KErrNotSupported;	
+	}
+
+/*
+ *	Set additional settings for a trace
+ */
+
+inline TInt DGeneralsDriver::AdditionalTraceSettings(TInt samplerId,TInt settings)
+	{
+	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
+
+    TInt cpus(0);
+#ifdef __SMP__
+    cpus = NKern::NumberOfCpus();
+    if( samplerId == PROFILER_GPP_SAMPLER_ID )
+        {
+        for(TInt cpu(0);cpu<cpus;cpu++)
+             {
+             iSamplers[cpu]->SetAdditionalSettings(settings);
+             }
+        return KErrNone;
+        }
+#endif
+    for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerId)
+		    {
+			iSamplers[i]->SetAdditionalSettings(settings);
+			return KErrNone;
+            }
+        }
+
+	return KErrNotSupported;	
+	}
+
+inline TInt DGeneralsDriver::AdditionalTraceSettings2(TInt samplerId,TInt settings)
+	{
+	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
+
+    TInt cpus(0);
+#ifdef __SMP__
+    cpus = NKern::NumberOfCpus();
+    if( samplerId == PROFILER_GPP_SAMPLER_ID )
+        {
+        for(TInt cpu(0);cpu<cpus;cpu++)
+             {
+             iSamplers[cpu]->SetAdditionalSettings2(settings);
+             }
+        return KErrNone;
+        }
+#endif
+    for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerId)
+		    {
+			iSamplers[i]->SetAdditionalSettings2(settings);
+			return KErrNone;
+		    }
+        }
+
+	return KErrNotSupported;	
+	}
+
+inline TInt DGeneralsDriver::SetSamplingPeriod(TInt samplerId,TInt settings)
+	{
+	LOGSTRING2("DGeneralsDriver::SetSamplingPeriod - set:%d",settings);
+
+	TInt cpus(0);
+#ifdef __SMP__
+    cpus = NKern::NumberOfCpus();
+    if( samplerId == PROFILER_GPP_SAMPLER_ID )
+        {
+        for(TInt cpu(0);cpu<cpus;cpu++)
+             {
+             iSamplers[cpu]->SetSamplingPeriod(settings);
+             }
+        return KErrNone;
+        }
+#endif
+    for(TInt i(cpus);i<KSamplerAmount;i++)
+	    {
+		if(iSamplers[i]->iSamplerId == samplerId)
+		    {
+			iSamplers[i]->SetSamplingPeriod(settings);
+			return KErrNone;
+		    }
+	    }
+
+	return KErrNotSupported;	
+	}
+
+/*
+ *	Mark traces active or inactive, this can be done
+ *	only if sampling is not running
+ */
+ 
+TInt DGeneralsDriver::StartSampling()
+	{
+	LOGSTRING("DGeneralsDriver::StartSampling");
+
+	if(iState == EStopped)
+		{
+		// reset iSampleStartTimeProp property value
+		iSampleStartTime = NKern::TickCount();	// get the system tick value for sync purposes 
+#ifdef __SMP__
+		iStartTime = (iSampleStartTime & 0xfffffff0);
+#endif
+		TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
+		
+		Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator
+		
+		// reset all enabled samplers
+		for(TInt i(0);i<KSamplerAmount;i++)
+			{
+			if(iSamplers[i]->iEnabled)
+				{
+				// reset with stream option
+#ifndef __SMP__
+                Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
+				iSamplers[i]->Reset(&iSampleStream, 0);
+#else
+                Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
+                iSamplers[i]->Reset(&iSampleStream, iStartTime);
+#endif
+				}
+			}
+
+		NewStart(gppSampler.GetPeriod());
+		return KErrNone;
+		}
+	else
+		{
+		return KErrGeneral;
+		}
+	}
+
+/*
+ *  Mark traces active or inactive, this can be done
+ *  only if sampling is not running
+ */
+ 
+TInt DGeneralsDriver::StopSampling()
+    {
+    LOGSTRING("DGeneralsDriver::StopSampling");
+
+    if(iState == ERunning)
+        {
+        this->iState = EStopping;
+        // reset all enabled samplers
+        for(TInt i(0);i<KSamplerAmount;i++)
+            {
+            // do the reset only for memory sampler
+            if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4)
+                {
+                // reset with stream option
+                LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers"));
+                iSamplers[i]->Reset(&iSampleStream, 999999);
+                }
+            }
+
+        return KErrNone;
+        }
+    else
+        {
+        return KErrGeneral;
+        }
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,577 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+ 
+#include "GeneralsPlugin.h"	
+//#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+
+const TInt KMaxSamplerAmount = 20;
+
+// LITERALS
+_LIT8(KSamplingPeriod, "sampling_period_ms");
+
+// CONSTANTS
+// GeneralsPlugin UID:
+const TUid KSamplerGeneralsPluginUid = { 0x2001E5B2 };
+
+// Gpp sub-sampler UID:
+const TUid KSamplerGppPluginUid = { 0x2001E570 };
+
+// Gfc sub-sampler UID:
+const TUid KSamplerGfcPluginUid = { 0x2001E571 };
+
+// Itt sub-sampler UID:
+const TUid KSamplerIttPluginUid = { 0x2001E572 };
+
+// Mem sub-sampler UID:
+const TUid KSamplerMemPluginUid = { 0x2001E573 };
+
+// Pri sub-sampler UID:
+const TUid KSamplerPriPluginUid = { 0x2001E574 };
+
+/*
+ *	
+ *	class CGeneralsPlugin implementation
+ * 
+ */
+ 
+CGeneralsPlugin* CGeneralsPlugin::NewL(const TUid aImplementationUid, TAny* /*aInitParams*/)
+    {
+	LOGTEXT(_L("CGeneralsPlugin::NewL() - entry"));
+    CGeneralsPlugin* self = new (ELeave) CGeneralsPlugin();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CGeneralsPlugin::NewL() - exit"));
+    return self;
+    }
+
+CGeneralsPlugin::CGeneralsPlugin() :
+	iVersionDescriptor(&(this->iVersion[1]),0,19)
+	{
+	iSamplerType = PROFILER_KERNEL_MODE_SAMPLER;
+	iSamplerId = PROFILER_GENERALS_SAMPLER_ID;
+	iBufferHandler = NULL;
+    iEnabled = EFalse;
+	LOGTEXT(_L("CGeneralsPlugin::CGeneralsPlugin() - constructor"));
+	}
+
+void CGeneralsPlugin::ConstructL() 
+    {
+	LOGTEXT(_L("CGeneralsPlugin::ConstructL() - entry"));
+	
+	// create attribute array
+	iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(KSubSamplerCount);
+	
+	TInt err = InitiateSamplerL();
+	if( err != KErrNone )
+		{
+			LOGTEXT(_L("CGeneralsPlugin::ConstructL - LEAVING, failed to load open sampler device"));
+			User::Leave(err);
+		}
+	
+	// initiate sampler attributes, i.e. settings for modification
+	InitiateSamplerAttributesL();
+	
+	LOGTEXT(_L("CGeneralsPlugin::ConstructL() - exit"));
+    }
+
+
+CGeneralsPlugin::~CGeneralsPlugin()
+	{
+	// clean all the members
+	CleanSampler();	// clean the created sampler
+	}
+
+TInt CGeneralsPlugin::InitiateSamplerL()
+	{
+	RThread me;
+	
+	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #1"));
+
+	me.SetPriority(EPriorityRealTime);
+
+	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #2"));
+	
+	// create 
+	User::FreeLogicalDevice(KPluginSamplerName);
+	TInt err(KErrGeneral);
+	
+	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #3"));
+
+    err = User::LoadLogicalDevice(KPluginSamplerName);
+    if(err != KErrNone)
+        {
+        User::Leave(err);
+        }
+
+	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #4"));
+	
+	err = KErrGeneral;
+
+    err = iGeneralsSampler.Open();
+    if(err != KErrNone)
+        {
+        LOGSTRING2("CGeneralsPlugin::InitiateSamplerL - Could not open sampler device - waiting and trying again: %d", err);
+        User::Leave(err);
+        }
+
+	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #5"));
+
+	return err;
+	}
+
+/* 
+ * 
+ * Default sampler attributes
+ * 
+ */
+void CGeneralsPlugin::InitiateSamplerAttributesL()
+    {
+
+    // 
+    for(TInt i(0);i<KMaxSamplerAmount;i++)
+        {
+        switch(i)
+            {
+// Usage:
+//            TSamplerAttributes(TUint32 aUid,
+//                    const TDesC8& aShortName,
+//                    const TDesC& aName,
+//                    const TDesC& aDescription,
+//                    TInt aSampleRate,
+//                    TBool aEnabled,
+//                    TBool aHidden,
+//                    TUint32 aItemCount);
+            case PROFILER_GPP_SAMPLER_ID:
+                {
+                TSamplerAttributes attr(KSamplerGppPluginUid.iUid,
+                        KGPPShortName(),
+                        KGPPLongName(),
+                        KGPPDescription(),
+                        1,
+                        ETrue,
+                        ETrue,
+                        0);
+                iSamplerAttributes->AppendL(attr);
+                break;
+                }
+            case PROFILER_GFC_SAMPLER_ID:
+                {
+                TSamplerAttributes attr2(KSamplerGfcPluginUid.iUid,
+                        KGFCShortName(),
+                        KGFCLongName(),
+                        KGFCDescription(),
+                        -1,
+                        EFalse,
+                        EFalse,
+                        0);
+                this->iSamplerAttributes->AppendL(attr2);
+                break;
+                }
+            case PROFILER_ITT_SAMPLER_ID:
+                {
+                TSamplerAttributes attr3(KSamplerIttPluginUid.iUid,
+                        KITTShortName(),
+                        KITTLongName(),
+                        KITTDescription(),
+                        -1,
+                        ETrue,
+                        EFalse,
+                        0);
+                this->iSamplerAttributes->AppendL(attr3);
+                break;
+                }
+            case PROFILER_MEM_SAMPLER_ID:
+                {
+                TSamplerAttributes attr4(KSamplerMemPluginUid.iUid,
+                        KMEMShortName(),
+                        KMEMLongName(),
+                        KMEMDescription(),
+                        -1,
+                        EFalse,
+                        EFalse,
+                        0);
+//                // select event or sampling based
+//                attr4.iSettingItem1.iSettingDescription.Copy(KMEM1Desc);
+//                attr4.iSettingItem1.iType = TSettingItem::ESettingItemTypeBool;
+//                attr4.iSettingItem1.iValue.AppendNum(0, EDecimal);
+//                attr4.iSettingItem1.iUIText.Copy(KMEM1UIText);
+//                attr4.iSettingItem1.iSettingText.Copy(KMemCounter1);
+                
+                this->iSamplerAttributes->AppendL(attr4);
+                break;
+                }
+            case PROFILER_PRI_SAMPLER_ID:
+                {
+                TSamplerAttributes attr5(KSamplerPriPluginUid.iUid,
+                        KPRIShortName(),
+                        KPRILongName(),
+                        KPRIDescription(),
+                        3000,
+                        EFalse,
+                        EFalse,
+                        0);
+                this->iSamplerAttributes->AppendL(attr5);
+                break;
+                }
+            }
+        }
+    }
+
+TInt CGeneralsPlugin::CleanSampler()
+	{
+    LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - deleting buffer handler"));
+    // release the buffer handler
+    if(iBufferHandler)
+        {
+        iBufferHandler->Cancel();
+        delete iBufferHandler;
+        iBufferHandler = NULL;
+        }
+    
+    LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - closing sampler"));
+	iGeneralsSampler.Close();
+	
+	LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - Freeing sampler device"));
+	User::FreeLogicalDevice(KPluginSamplerName);
+	
+	// release attribute array
+	if(iSamplerAttributes)
+	    {
+	    iSamplerAttributes->Reset();
+	    }
+    delete iSamplerAttributes;
+    iSamplerAttributes = NULL;
+
+	LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - exit"));
+
+	return KErrNone;
+	}
+
+// returns setting array
+void CGeneralsPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    TInt count(iSamplerAttributes->Count());
+    // append all sampler attributes to aAttributes array
+    for(TInt i(0);i<count;i++)
+        {
+        aAttributes->AppendL(iSamplerAttributes->At(i));
+        }
+    }
+
+TInt CGeneralsPlugin::SetAttributesL(TSamplerAttributes aAttributes)
+    {
+    TSamplerAttributes attr;
+
+    TInt count(iSamplerAttributes->Count());
+    // loop the sub sampler attributes (by UID)
+    for(TInt i(0);i<count;i++)
+        {
+        attr = iSamplerAttributes->At(i);
+        // if UIDs match replace the old 
+        if(attr.iUid == aAttributes.iUid)
+            {
+            // replace the old attribute container
+            iSamplerAttributes->Delete(i);
+            iSamplerAttributes->InsertL(i, aAttributes);
+            return KErrNone;
+            }
+        }
+    return KErrNotFound;
+    }
+
+/* 
+ * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
+ * called by CSamplerController class
+ * 
+ * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
+ */
+TInt CGeneralsPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
+    {
+    // local literals
+    _LIT8(KGPPShort, "gpp");
+    _LIT8(KGFCShort, "gfc");
+    _LIT8(KITTShort, "itt");
+    _LIT8(KMEMShort, "mem");
+    _LIT8(KPRIShort, "pri");
+
+    TInt err(KErrNone);
+    
+    TBuf8<16> samplerSearchName;
+    
+    // loop previous settings, update value if changed
+    for(TInt i(0);i<KSubSamplerCount;i++)
+        {
+        // go through all the sub samplers
+        switch (i)
+            {
+            case 0:
+                samplerSearchName.Copy(KGPPShort);
+                break;
+            case 1:
+                samplerSearchName.Copy(KGFCShort);
+                break;
+            case 2:
+                samplerSearchName.Copy(KITTShort);
+                break;
+            case 3:
+                samplerSearchName.Copy(KMEMShort);
+                break;
+            case 4:
+                samplerSearchName.Copy(KPRIShort);
+                break;
+            }
+
+        // get sampler specific settings  
+        err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, i);
+        }
+    
+    // returns KErrNone if settings found, otherwise KErrNotFound
+    return err;
+    }
+
+/**
+ * Method for searching sampler specific settings among all settings (raw setting lines read from settings file)
+ * 
+ * @param aAllSettings array of all settings from settings file
+ * @param aSamplerName short name of sampler to be searched among the settings
+ * @param aIndex index number of sampler specific sampler attributes (TSamplerAttributes)
+ * @return KErrNone if settings found ok else KErrNotFound
+ */
+TInt CGeneralsPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
+    {
+    // sampler name to be searched among the all settings
+    TBuf8<16> samplerSearch;
+    samplerSearch.Copy(KBracketOpen);
+    samplerSearch.Append(aSamplerName);
+    samplerSearch.Append(KBracketClose);
+    
+    // read a line from ALL settings array
+    for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
+        {
+        // check if this line has a setting block start, i.e. contains [xxx] in it
+        if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
+            {
+            // right settings block found, now loop until the next block is found
+            for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
+                {
+                // check if the next settings block was found
+                if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
+                    {
+                    // save found setting value directly to its owners attributes
+                    SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
+                    }
+                else
+                    {
+                    // next block found, return KErrNone
+                    return KErrNone;
+                    }
+                }
+            }
+        }
+    // no settings found for specific sampler
+    return KErrNotFound;
+    }
+
+/**
+ * Method for setting a specific descriptor (from settings file) to attribute structure
+ * 
+ * @param aSetting  
+ * @param aName  
+ */
+void CGeneralsPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
+    {
+    // local literals
+    _LIT8(KSettingItemSeparator, "=");
+    
+    // find the equal mark from the setting line
+    TInt sepPos = aSetting.Find(KSettingItemSeparator);
+    // check that '=' is found
+    if (sepPos > 0)
+        {
+        // check that the element matches
+        if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
+            {
+            TBool en;
+            CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
+            if(en != iSamplerAttributes->At(aIndex).iEnabled)
+                {
+                iSamplerAttributes->At(aIndex).iEnabled = en;
+                }
+            }
+        else if (aSetting.Left(sepPos).CompareF(KSamplingPeriod) == 0)
+            {
+            TInt sr;
+            CSamplerPluginInterface::Str2Int(aSetting.Right(aSetting.Length()-sepPos-1), sr);
+            if(sr != iSamplerAttributes->At(aIndex).iSampleRate)
+                {
+                iSamplerAttributes->At(aIndex).iSampleRate = sr;
+                }
+            }
+        }
+    }
+
+
+TUid CGeneralsPlugin::Id(TInt aSubId) const
+	{
+		if(aSubId == PROFILER_GPP_SAMPLER_ID)		
+			return KSamplerGppPluginUid;
+		else if (aSubId == PROFILER_GFC_SAMPLER_ID)		
+			return KSamplerGfcPluginUid;
+		else if (aSubId == PROFILER_ITT_SAMPLER_ID)		
+			return KSamplerIttPluginUid;
+		else if (aSubId == PROFILER_MEM_SAMPLER_ID)		
+			return KSamplerMemPluginUid;
+		else if (aSubId == PROFILER_PRI_SAMPLER_ID)		
+			return KSamplerPriPluginUid;
+		else
+			return KSamplerGeneralsPluginUid;
+	}
+
+TInt CGeneralsPlugin::SubId(TUid aId) const
+	{
+/* definitions from ProfilerConfig.h:
+ * 	#define		PROFILER_GPP_SAMPLER_ID			1
+	#define		PROFILER_GFC_SAMPLER_ID			2
+	#define		PROFILER_ITT_SAMPLER_ID			3
+	#define		PROFILER_MEM_SAMPLER_ID			4
+	#define		PROFILER_PRI_SAMPLER_ID			5
+ */
+	
+		if(aId == KSamplerGppPluginUid)		
+			return PROFILER_GPP_SAMPLER_ID;
+		else if (aId == KSamplerGfcPluginUid)		
+			return PROFILER_GFC_SAMPLER_ID;
+		else if (aId == KSamplerIttPluginUid)		
+			return PROFILER_ITT_SAMPLER_ID;
+		else if (aId == KSamplerMemPluginUid)		
+			return PROFILER_MEM_SAMPLER_ID;
+		else if (aId == KSamplerPriPluginUid)		
+			return PROFILER_PRI_SAMPLER_ID;
+		else
+			return KErrNotFound;
+	}
+
+TInt CGeneralsPlugin::GetSamplerType()
+	{
+	return iSamplerType;
+	}
+
+
+void CGeneralsPlugin::InstallStreamForActiveTraces(RGeneralsSampler& sampler, CProfilerSampleStream& aStream)
+	{
+	// output mode for this trace is stream
+	if(!iBufferHandler)
+		{
+		// stream object has not been created yet
+		LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces - creating stream for trace"));	
+		
+		// use a 32KB buffer to transfer data from sampler to client
+		// commonStream = new RProfilerSampleStream(sampler,totalPrefix,32768);
+		TRAPD(err, iBufferHandler = CProfilerBufferHandler::NewL(aStream, sampler));
+		if(err != KErrNone)
+		    {
+		    LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces() - No memory"));
+		    return;
+		    }
+		}
+
+	// initiate receiving of data from the sampler device driver
+	if(iBufferHandler)
+		{
+		iBufferHandler->StartReceivingData();
+		}
+}
+
+void CGeneralsPlugin::SetSettingsToSamplers()
+    {
+    TSamplerAttributes attr;
+    
+    // loop through the setting attributes
+    for(TInt i(0);i<iSamplerAttributes->Count();i++)
+        {
+        // get the attribute container
+        attr = iSamplerAttributes->At(i);
+        
+        // make changes according to right sampler, NOTE! The old IDs of sub samplers (i+1)!
+        if(attr.iEnabled)
+            {
+            iGeneralsSampler.MarkTraceActive(i+1);
+            
+            // set enabled
+            iEnabled = ETrue;
+            }
+        else
+            {
+            iGeneralsSampler.MarkTraceInactive(i+1);
+            }
+        // set sampling period if available
+        if(attr.iSampleRate != KErrNotFound)
+            {
+            iGeneralsSampler.SetSamplingPeriod(i+1, attr.iSampleRate);
+            }
+        }
+    }
+
+TInt CGeneralsPlugin::ResetAndActivateL(CProfilerSampleStream& aStream) 
+    {
+	// the sampler starting functionality
+	LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - entry"));
+
+    // now before starting the latest settings must be set to samplers itself
+	SetSettingsToSamplers();
+
+	if(Enabled())
+	    {
+        LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - starting sampling..."));
+        // start sampling process of enabled sub samplers
+        iGeneralsSampler.StartSampling();		
+        LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - installing stream for an active trace..."));
+    
+        // install the trace for enabled samplers
+        InstallStreamForActiveTraces(iGeneralsSampler, aStream);
+        LOGSTRING2("CGeneralsPlugin::ResetAndActivate() - stream installed: 0x%x", aStream);
+	    }
+	
+	LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - exit"));
+	return KErrNone;
+    }
+	
+TInt CGeneralsPlugin::StopSampling() 
+    {
+    // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Stopping sampler LDD"));
+	iGeneralsSampler.StopSampling();
+	// RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Sampler LDD stopped"));
+	
+	// check if bufferhandler has died
+	if(iBufferHandler)
+		{
+		// RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Canceling the buffer handler"));
+		iBufferHandler->Cancel();
+		delete iBufferHandler;
+		iBufferHandler = NULL;
+		}	
+	// set enabled
+    iEnabled = EFalse;
+    // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - exit"));
+	return KErrNone;
+    }
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsPluginImplementationTable.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "GeneralsPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+         IMPLEMENTATION_PROXY_ENTRY(0x2001E5B2,  CGeneralsPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsSampler.cia	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <platform.h>
+
+#include "GeneralsDriver.h"
+#include <kern_priv.h>		//temporary
+
+#ifdef __SMP__
+#include <e32cia.h>
+#include <arm.h>
+#include <arm_gic.h>
+#include <arm_tmr.h>
+#endif
+
+#if defined(__GCC32__)
+// CIA symbol macros for Gcc98r2
+#define CSM__ZN5NKern14CurrentContextEv " CurrentContext__5NKern"
+#elif defined(__ARMCC__)
+// CIA symbol macros for RVCT
+#define CSM__ZN5NKern14CurrentContextEv " __cpp(NKern::CurrentContext)"
+#else
+// CIA symbol macros for EABI assemblers
+#define CSM__ZN5NKern14CurrentContextEv " _ZN5NKern14CurrentContextEv"
+#endif
+
+#ifdef __WINS__
+__NAKED__ TUint* IntStackPtr()
+{
+	return 0;
+}
+
+__NAKED__ TUint32 SPSR()
+{
+	return 0;
+}
+__NAKED__ void UsrModLr(TUint32* a)
+{
+	*a = 0;
+}
+#else
+
+__NAKED__ TUint* IntStackPtr()
+{
+#ifdef __SMP__
+    asm("stmfd sp!, {r0-r12,lr} ");
+#endif
+	asm("mrs r1, cpsr ");           // copy current program status register (cpsr) to R1 
+	asm("bic r3, r1, #0x1f ");      // compare to 0x1f, i.e. make sure that spsr is available? 
+#ifdef __SMP__
+	__ASM_CLI_MODE(MODE_IRQ);       // disable all interrupts and set to irq mode (we are in NTimer interrupt)
+#else
+	asm("orr r3, r3, #0xd2 ");		// mode_irq, all interrupts off
+	asm("msr cpsr, r3 ");           // write result on R3 back to cpsr, irqs disabled 
+#endif
+	asm("mov r0, sp ");				// read stack pointer to R0, mode r0=sp_irq
+	asm("msr cpsr, r1 ");			// restore interrupts
+#ifdef __SMP__
+    asm("ldmfd sp!, {r0-r12,pc} ");
+#endif
+	__JUMP(,lr);
+}
+
+__NAKED__ TUint32 SPSR()
+{
+	asm("mrs r0, spsr ");
+	__JUMP(,lr);
+}
+__NAKED__ void UsrModLr(TUint32*)
+{
+	// r0 = address to store
+	asm ("stmia r0,{lr}^");
+	__JUMP(,lr);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GppSamplerImpl.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,572 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+#include <kern_priv.h>
+#include <arm.h>
+
+#include "GppSamplerImpl.h"
+
+extern TUint*		IntStackPtr();
+#define	TAG(obj)	(*(TUint32*)&(obj.iAsyncDeleteNext))
+
+// properties for ISA task parsing
+const TUid KIsaPropertyCat={0x2001E5AD};
+enum TIsaPropertyKeys
+	{
+	EIsaPropertyIsaTaskParserStatus = 1,
+	EIsaPropertyIsaTaskAddressStart,
+	EIsaPropertyIsaTaskAddressEnd,
+	EIsaPropertyIsaTaskAddress,
+	EIsaPropertyIsaOsTaskRunningAddress,
+	EIsaPropertyIsaTaskParsedName
+	};
+
+
+DGppSamplerImpl::DGppSamplerImpl()
+	{
+	LOGTEXT("GppSamplerImpl::GppSamplerImpl");
+	iInterruptStack = (TUint*)IntStackPtr();
+
+	LOGTEXT("GppSamplerImpl::GppSamplerImpl - attaching to properties");
+
+	TInt err = iIsaStartAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressStart);
+	if(err != KErrNone)
+		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressStart not available"); 
+	err = iIsaEndAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressEnd);
+	if(err != KErrNone)
+		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressEnd not available"); 
+	err = iIsaPluginStatus.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskParserStatus);
+	if(err != KErrNone)
+		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskParserStatus not available"); 
+	err = iIsaOsTaskRunning.Attach(KIsaPropertyCat, EIsaPropertyIsaOsTaskRunningAddress);
+	if(err != KErrNone)
+		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaOsTaskRunningAddress not available"); 
+	
+	PROFILER_ISA_TASK_NAMES
+	
+	Reset();
+	}
+
+DGppSamplerImpl::~DGppSamplerImpl() 
+	{
+	iIsaStartAddr.Close();
+	iIsaEndAddr.Close();
+	iIsaPluginStatus.Close();
+	iIsaOsTaskRunning.Close();
+	}
+
+void DGppSamplerImpl::Reset()
+	{
+	LOGTEXT("GppSamplerImpl::Reset");
+	iLastPc = 0;
+	iLastThread = 0;
+	iRepeat = 0;
+	iIsaStatus = 0;
+	iIsaStart = 0;
+	iIsaEnd = 0;
+//	isaOsTaskRunningAddr = 0;
+	
+	// in SMP start time common with all CPUs, provided by DGeneralsDriver class
+#ifndef __SMP__
+	iStartTime = ( NKern::TickCount() & 0xfffffffc );
+#endif
+	
+	TPropertyStatus status;
+	TInt osAddr = 0;
+	
+	LOGTEXT("GppSamplerImpl::Reset - getting status");
+	
+	// get status of ISA plug-in
+	if(iIsaPluginStatus.GetStatus(status))
+		{
+		iIsaPluginStatus.Get(iIsaStatus);
+		LOGSTRING2("GppSamplerImpl::Reset - ISA plug-in status %d", iIsaStatus);
+		}
+	
+	if(iIsaStatus > 0)
+		{
+		LOGTEXT("GppSamplerImpl::Reset - get isa start address");
+		iIsaStartAddr.Get(iIsaStart);
+		LOGTEXT("GppSamplerImpl::Reset - get isa end address");
+		iIsaEndAddr.Get(iIsaEnd);
+		LOGTEXT("GppSamplerImpl::Reset - get isa os_task_running address");
+		iIsaOsTaskRunning.Get(osAddr);
+		isaOsTaskRunningAddr = reinterpret_cast<TInt*>(osAddr);
+		LOGSTRING2("GppSamplerImpl::Reset - got isa os_task_running address 0x%X", osAddr);
+		}
+	
+	LOGTEXT("GppSamplerImpl::Reset - initializing isa task list");
+
+	iIsaSample = false;
+	
+	for(TInt i=0;i<256;i++)
+		knownIsaTasks[i] = -1;
+	
+	knownIsaTaskCount = 0;
+    
+	iCpuSelector = 0x3;
+#ifndef __SMP__
+    iMask =  0xfffffffc;
+#else
+    iMask =  0xfffffff0;
+    switch(iCpuNumber)
+        {
+        case 0:
+            iCpuSelector = 0x1;
+            break;
+        case 1:
+            iCpuSelector = 0x2;
+            break;
+        case 2:
+            iCpuSelector = 0x4;
+            break;
+        case 3:
+            iCpuSelector = 0x8;
+            break;
+        }
+#endif
+	}
+
+TUint8* DGppSamplerImpl::EncodeTag(TUint8* aPtr)
+//
+// Encode a tag and version to the trace data. This allows the offline analyser to 
+// identify the sample data.
+//
+{	
+	_LIT(KGppSamplerVersion,"Bappea_GPP_V");
+	_LIT(KProfilerVersion,"#Prof#");
+	_LIT(KSamplerVersion,"#Samp#");
+#ifdef __SMP__
+	_LIT(KCPUNumberText,"#CPU#");
+#endif
+	
+	TBuf<64> buf;
+	buf.Zero();
+	buf.Append(KGppSamplerVersion);
+	buf.Append(PROFILER_GPP_SAMPLER_VERSION);
+	buf.Append(KProfilerVersion);
+	buf.Append(PROFILER_VERSION_SHORT);	
+	buf.Append(KSamplerVersion);
+	buf.Append(PROFILER_SAMPLER_VERSION);
+#ifdef __SMP__
+	buf.Append(KCPUNumberText);
+	buf.AppendNum(iCpuNumber);
+#endif
+	aPtr = EncodeText(aPtr, buf);
+	return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeInt(TUint8* aPtr,TInt aValue)
+{
+	LOGSTRING2("Encoding int 0x%x",aPtr);
+
+	LOGSTRING2("TIint = 0x%x",aValue);
+
+	TUint byte;
+	for (;;)
+		{
+		byte = aValue & 0x7f;
+		if ((aValue >> 6) == (aValue >> 7))
+			break;
+		aValue >>= 7;
+		*aPtr++ = byte;
+		}
+	*aPtr++ = byte | 0x80;
+
+	LOGSTRING2("Encoded int 0x%x",aPtr);
+
+	return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeUint(TUint8* aPtr,TUint aValue)
+{
+	LOGSTRING2("Encoding Uint 0x%x",aPtr);
+
+	LOGSTRING2("TUint = 0x%x",aValue);
+
+
+	TUint byte;
+	for (;;)
+		{
+		byte = aValue & 0x7f;
+		aValue >>= 7;
+		if (aValue == 0)
+			break;
+		*aPtr++ = byte;
+		}
+	*aPtr++ = byte | 0x80;
+
+	LOGSTRING2("Encoded Uint 0x%x",aPtr);
+
+	return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeText(TUint8* aPtr, const TDesC& aDes)
+//
+// Encode a descriptor into the data stream
+// This is currently limited to a descriptor that is up to 255 characters in length,
+// and Unicode characters are truncated to 8 bits
+//
+{
+	LOGSTRING2("Encoding text 0x%x",aPtr);
+	TInt len=aDes.Length();
+	*aPtr++ = TUint8(len);
+	const TText* p = aDes.Ptr();
+	while (--len >= 0)
+		{
+		*aPtr++ = TUint8(*p++);
+		}
+
+	LOGSTRING2("Encoded text 0x%x",aPtr);
+	return aPtr;
+}
+
+
+TUint8* DGppSamplerImpl::EncodeName(TUint8* aPtr, DObject& aObject,TUint32 id)
+//
+// Encode the name of a kernel object
+//
+{
+	LOGSTRING2("Encoding name 0x%x",aPtr);
+	TBuf8<0x5f> name;
+	aObject.TraceAppendName(name,false);
+
+	if(id != 0xffffffff)
+	{
+		name.Append('[');
+		name.AppendNum(id,EHex);
+		name.Append(']');
+	}
+	else
+	{
+		name.Append('[');
+		name.AppendNum((TUint32)((void*)&(((DThread*)&aObject)->iNThread)),EHex);
+		name.Append(']');
+	}
+
+	aPtr = EncodeText(aPtr,name);
+	LOGSTRING2("Encoded name 0x%x",aPtr);
+	return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeThread(TUint8* aPtr, DThread& aThread)
+//
+// Encode a thread name in the data stream.
+// The thread is identified by its name, and the identity of its owning process.
+// If the process has not been identified in the data stream already, it's name is
+// also encoded.
+//
+{
+	LOGSTRING2("Encoding thread 0x%x",aPtr);	
+
+	DProcess& p = *aThread.iOwningProcess;
+	
+	aPtr = EncodeUint(aPtr, p.iId);
+
+#ifdef __SMP__
+    // check if first time founding
+    if ((TAG(p) & iMask) != iStartTime)
+        {
+        // mark tagged for this CPU
+        TAG(p) = (iStartTime | iCpuSelector);
+
+        // The thread is 'unknown' to this sample, so encode the thread name
+        aPtr = EncodeName(aPtr, p, p.iId);     
+        }
+    // check if thread appeared already on this CPU
+    else if((TAG(p) & iCpuSelector) != iCpuSelector)
+        {
+        TAG(p) = (TAG(p) | iCpuSelector);
+        // The thread is 'unknown' to this sample, so encode the thread name
+        aPtr = EncodeName(aPtr, p, p.iId);     
+        }
+#else
+	if (TAG(p) != iStartTime)
+	    {
+		TAG(p) = iStartTime;
+		// Provide the name matching this process ID
+		aPtr = EncodeName(aPtr, p, p.iId);
+	    }
+#endif	    
+	aPtr = EncodeName(aPtr, aThread,0xffffffff);
+	
+	LOGSTRING2("Encoded thread 0x%x",aPtr);	
+
+	return aPtr;
+    }
+
+TUint8* DGppSamplerImpl::EncodeRepeat(TUint8* aPtr)
+//
+// Encode a repeated sequence of samples
+//
+{
+	LOGSTRING2("Encoding repeat, 0x%x",iRepeat);	
+
+	aPtr = EncodeInt(aPtr, 0);
+	aPtr = EncodeUint(aPtr, iRepeat);
+	iRepeat = 0;
+
+	LOGSTRING2("Encoded repeat, 0x%x",iRepeat);	
+
+	return aPtr;
+}
+
+TInt DGppSamplerImpl::CreateFirstSample()
+{
+	LOGTEXT("GppSamplerImpl::CreateFirstSample");
+	Reset();
+
+	TUint8* w = this->tempBuf;
+	w = EncodeTag(w);
+
+	TInt length = w-tempBuf;
+
+	LOGSTRING2("TAG encoded, length %d",length);
+	return length;
+}
+
+TBool DGppSamplerImpl::IsaTaskKnown(TUint8 task)
+{
+	for(TInt i=0;i<256;i++)
+	{
+		if(knownIsaTasks[i] == -1)
+		{
+			knownIsaTasks[i] = task;
+			knownIsaTaskCount++;
+			return false;
+		}
+		else if(knownIsaTasks[i] == task)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+TUint8* DGppSamplerImpl::EncodeIsaTask(TUint8* aPtr, TUint task)
+
+{
+	LOGSTRING2("Encoding ISA task 0x%x",aPtr);	
+
+	aPtr = EncodeUint(aPtr,task);
+	// use the task name as the process name
+	aPtr = EncodeIsaName(aPtr,task,true);
+	// then encode the task name
+	aPtr = EncodeIsaName(aPtr,task,false);
+	
+	LOGSTRING2("Encoded ISA task 0x%x",aPtr);	
+
+	return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeIsaName(TUint8* aPtr, TUint task,TBool process)
+//
+// Encode a descriptor into the data stream
+// This is currently limited to a descriptor that is up to 255 characters in length,
+// and Unicode characters are truncated to 8 bits
+//
+{
+	TBuf8<256> aDes;
+	
+//	#ifdef NCP_COMMON_PROFILER_ISA_TASKS 
+	if(iIsaStatus > 0)
+		{
+		// resolve the isa task name from the task name array
+		if((task-100000) < PROFILER_ISA_OS_TASK_AMOUNT && process == false)
+			{
+			aDes.Append(isaTaskNames[(task-100000)]);
+			}
+		else
+			{
+			aDes.Append(_L8("NativeOS_Task"));
+			}
+		}
+	else
+		{
+		aDes.Append(_L8("NativeOS_Task"));
+		}
+	
+	aDes.Append('[');
+	aDes.AppendNum((task-100000),EHex);
+	aDes.Append(']');
+
+	LOGSTRING2("Encoding ISA name 0x%x",aPtr);
+	TInt len=aDes.Length();
+	*aPtr++ = TUint8(len);
+	const TText* p = aDes.Ptr();
+	while (--len >= 0)
+		{
+		*aPtr++ = TUint8(*p++);
+		}
+
+	LOGSTRING2("Encoded ISA name 0x%x",aPtr);
+	return aPtr;
+}
+
+
+TInt DGppSamplerImpl::SampleImpl()
+//
+// ISR for the profile timer
+// This extracts the thread and PC that was current when the interrupt went off and
+// encodes it into the sample data buffer. If enough data has been generated, the
+// DFC is triggered to complete a read request
+//
+    {
+	TUint8* w(this->tempBuf);
+	
+//    Kern::Printf(("Got thread 0x%08x"), &t);
+#ifdef __SMP__
+    // get the program counter of irq mode
+    TUint32 pc = (TUint32)Arm::IrqReturnAddress();
+#else
+    // get program counter of irq mode
+    TUint32 pc = iInterruptStack[-1];
+#endif
+    //LOGSTRING3("pc value 0x%x sp 0x%x",pc,iInterruptStack);
+
+	// ignore the low bit being set for THUMB mode - we use for something else
+	pc &= ~1;			
+	TInt diff = pc - iLastPc;
+	iLastPc = pc;
+
+	if(iIsaStatus > 0)
+		{
+		if((TUint32)pc > (TUint32)iIsaStart && (TUint32)pc < (TUint32)iIsaEnd)
+			{
+			LOGSTRING2("Identified ISA execution at 0x%x",pc);
+			iIsaSample = true;
+			}
+		else
+			{
+			LOGSTRING2("Normal sample at 0x%x",pc);
+			iIsaSample = false;
+			}
+		}
+
+	// request for current thread from kernel
+	DThread& t = ((DThread&)*Kern::NThreadToDThread(NKern::CurrentThread()));
+	
+	TUint tid;
+	TUint8 isaTask = 0;
+	if(iIsaSample)
+	{
+		LOGSTRING2("Reading ISA task number from 0x%x",isaOsTaskRunningAddr);
+
+		// if we don't get reasonable ISA address to read, skip ISA task handling
+		if(isaOsTaskRunningAddr == 0)
+			{
+			tid = 100000; // to tell the difference from SOS threads
+			iIsaSample = false;
+			}
+		else	// normal ISA task parsing process
+			{
+			isaTask = *isaOsTaskRunningAddr;
+			LOGSTRING2("ISA task = %d",isaTask);
+			tid = isaTask;
+			// this will make sure we don't mix ISA tasks and normal tasks
+			tid += 100000;
+			}
+
+	}
+	else
+	{
+		tid = t.iId;
+	}
+
+	if (tid != iLastThread)
+	{
+		// Change of thread is marked in the low bit of the PC difference
+		diff |= 1;
+	}
+	TUint rp = iRepeat;
+	if (diff == 0)
+	{
+		// Identical sample, bump up the repeat count
+		iRepeat = rp + 1;
+	}
+	else
+	{
+		if (rp)
+		{
+			// Encode the repeat data
+			w = EncodeRepeat(w);
+		}
+		// Encode the PC difference
+		w = EncodeInt(w, diff);
+		if (diff & 1)
+		{
+			// Encode the new thread ID
+			if(iIsaSample)
+			{
+				iLastThread = tid;
+				w = EncodeUint(w,tid);
+
+				if(!this->IsaTaskKnown(isaTask))
+				{
+					w = EncodeIsaTask(w,iLastThread);
+				}
+				//LOGSTRING2("Sample total length: %d",w-tempBuf);
+				TInt length = w-tempBuf;
+				// encoded isa task, return here
+				return length;
+			}
+		
+			iLastThread = tid;
+			w = EncodeUint(w, tid);
+
+#ifdef __SMP__
+			// iStartTime format: 0xXXXXXXX0, the last byte set to zero
+			// iMask =  0xfffffff0(0b111....1110000)
+			// iCpuSelector = 0x1(0b0001), 0x2(0b0010), 0x4(0b0100) or 0x8(0b1000) 
+			
+			// check first time founding
+			if ((TAG(t) & iMask) != iStartTime)
+			    {
+			    // mark tagged for this CPU
+				TAG(t) = (iStartTime | iCpuSelector);
+				
+				// The thread is 'unknown' to this sample, so encode the thread name
+				w = EncodeThread(w, t);		
+			    }
+			// check if thread appeared on this CPU
+			else if((TAG(t) & iCpuSelector) != iCpuSelector)
+			    {
+                TAG(t) = (TAG(t) | iCpuSelector);
+                // The thread is 'unknown' to this sample, so encode the thread name
+                w = EncodeThread(w, t);     
+			    }
+#else
+			// check if tag has not been set, neither original nor 
+            if ((TAG(t) & 0xfffffffc) != iStartTime)
+                {
+                TAG(t) = ((TAG(t) & 0x3) | iStartTime);
+                // The thread is 'unknown' to this sample, so encode the thread name
+                w = EncodeThread(w, t);     
+                }
+#endif
+		    }
+	    }
+	LOGSTRING2("Sample total length: %d",w-tempBuf);
+	TInt length = w-tempBuf;
+
+	return length;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/IttEventHandler.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Event based ITT sampler skeleton copypasted from MemoryEventHandler.cpp
+*
+*/
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <arm.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <nk_trace.h>
+
+#include "IttEventHandler.h"
+
+/*
+ * Constructor
+ * 
+ * @param DProfilerSampleBuffer*    pointer to sample buffer
+ */
+DIttEventHandler::DIttEventHandler(DProfilerSampleBuffer* aSampleBuffer, TProfilerGppSamplerData* aGppSamplerDataIn)
+    :   DKernelEventHandler(EventHandler, this),
+        iSampleBuffer(aSampleBuffer),
+        iSampleDescriptor(&(this->iSample[1]),0,KITTBufferSize),
+        gppSamplerData(aGppSamplerDataIn)
+    {
+    //Kern::Printf("DIttEventHandler::DIttEventHandler()");
+
+    }
+
+/*
+ * DIttEventHandler::Create()
+ */
+TInt DIttEventHandler::Create()
+    {
+    Kern::Printf("DIttEventHandler::Create()");
+
+    TInt err(Kern::MutexCreate(iLock, _L("IttEventHandlerLock"), KMutexOrdDebug));
+    if (err != KErrNone)
+        return err;
+    
+    return Add();
+    }
+
+/*
+ * Destructor
+ */
+DIttEventHandler::~DIttEventHandler()
+    {
+    //Kern::Printf("DIttEventHandler::~DIttEventHandler()");
+
+    if (iLock)
+        iLock->Close(NULL);
+    }
+
+
+TInt DIttEventHandler::Start()
+    {
+    //Kern::Printf("DIttEventHandler::Start()");
+
+    iTracking = ETrue;
+    return KErrNone;
+    }
+
+
+TInt DIttEventHandler::Stop()
+    {
+    //Kern::Printf("DIttEventHandler::Stop()");
+
+    iTracking = EFalse;
+    return KErrNone;
+    }
+
+TBool DIttEventHandler::SampleNeeded()
+    {
+    LOGTEXT("DIttEventHandler::SampleNeeded()");
+    
+    // increase the counter by one on each round
+    iCount++;
+    
+    // check if event handler was not running
+    if(!iTracking)
+       return false;
+    
+    return true;
+    }
+
+
+TUint DIttEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis)
+    {
+    //Kern::Printf("DIttEventHandler::EventHandler()");
+    return ((DIttEventHandler*)aThis)->HandleEvent(aType, a1, a2);
+    }
+
+
+
+TUint DIttEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
+    {
+    //Kern::Printf("DIttEventHandler::HandleEvent()");
+    //Kern::Printf("New kernel event received, %d", aType);
+    
+    if (iTracking/* && iCount != iPreviousCount*/)
+        {
+        switch (aType)
+            {
+            
+            case EEventAddCodeSeg:
+                //Kern::Printf("DCodeSeg added: 0x%08x", (DCodeSeg*)a1);
+                HandleAddCodeSeg((DCodeSeg*)a1);
+                break;
+                
+            case EEventRemoveCodeSeg:
+                //Kern::Printf("DCodeSeg deleted: 0x%08x", (DCodeSeg*)a1);
+                HandleRemoveCodeSeg((DCodeSeg*)a1);
+                break;
+   
+            default:
+                break;
+            }
+        }
+//    else if(iTracking && iCount == iPreviousCount)
+//        {
+//        // if time stamp is not updated profiling has stopped
+//        Stop();
+//        }
+    return DKernelEventHandler::ERunNext;
+    }
+
+/*
+ * 
+ */
+TBool DIttEventHandler::HandleAddCodeSeg(DCodeSeg* aSeg)
+    {    
+    iSampleDescriptor.Zero();
+    //Kern::Printf("DLL ADD: NM %S : RA:0x%x SZ:0x%x SN:0x%x",aSeg->iFileName,aSeg->iRunAddress,aSeg->iSize, this->gppSamplerData->sampleNumber);
+
+    iSample[0] = aSeg->iFileName->Length();
+    iSampleDescriptor.Append(*aSeg->iFileName);
+    iSampleDescriptor.Append((TUint8*)&(aSeg->iRunAddress),4);
+    iSampleDescriptor.Append((TUint8*)&(aSeg->iSize),4);
+    iSampleDescriptor.Append((TUint8*)&(this->gppSamplerData->sampleNumber),4);
+    iSample[0] = iSampleDescriptor.Size();
+    
+    iSampleBuffer->AddSample(iSample,iSampleDescriptor.Size()+1);
+    return ETrue;
+    }
+
+TBool DIttEventHandler::HandleRemoveCodeSeg(DCodeSeg* aSeg)
+    {
+    iSampleDescriptor.Zero();
+    //Kern::Printf("DLL REM: NM %S : RA:0x%x SZ:0x%x SN:0x%x",aSeg->iFileName,aSeg->iRunAddress,aSeg->iSize, this->gppSamplerData->sampleNumber);
+
+    iSample[0] = aSeg->iFileName->Length();
+    iSampleDescriptor.Append(*aSeg->iFileName);
+    iSampleDescriptor.Append((TUint8*)&(aSeg->iRunAddress),4);
+    iSampleDescriptor.Append((TUint8*)&(aSeg->iSize),4);
+    iSampleDescriptor.Append((TUint8*)&(this->gppSamplerData->sampleNumber),4);
+    iSample[0] = iSampleDescriptor.Size();
+    
+    iSampleBuffer->AddSample(iSample,iSampleDescriptor.Size()+1);
+    return ETrue;
+    }
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,244 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "IttSamplerImpl.h"
+
+#ifdef ITT_EVENT_HANDLER
+_LIT8(KIttVersion, "2.00");
+#else
+_LIT8(KIttVersion, "1.22");
+#endif
+
+/*
+ *	ITT sampler definition
+ *  	
+ */
+IttSamplerImpl::IttSamplerImpl():
+        sampleDescriptor(&(this->sample[1]),0,KITTSampleBufferSize)
+{
+	this->currentLibCount = 0;
+	iTimeToSample = EFalse;
+	this->Reset();
+}
+
+/*
+ * destructor
+ */
+IttSamplerImpl::~IttSamplerImpl()
+{
+
+}
+
+/*
+ * IttSamplerImpl::CreateFirstSample()
+ * 
+ * Function for creating the first sample to the log file
+ */
+TInt IttSamplerImpl::CreateFirstSample() 
+{	
+    Kern::Printf("ittSamplerImpl::createFirstSample\n");
+	this->iVersionData.Zero();
+	this->iVersionData.Append(_L8("Bappea_ITT_V"));
+	this->iVersionData.Append(KIttVersion);
+	this->itt_sample = (TUint8*)iVersionData.Ptr();
+	return iVersionData.Length();
+}
+
+/*
+ * IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
+ * 
+ * @param TUint32 Sample number
+ * 
+ */
+TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
+{
+#ifdef ITT_EVENT_HANDLER
+    iCount++;
+    if (iCount <= iIttSamplingPeriod && ((iCount % iIttSamplingPeriod) == 0 || (iCount % iIttSamplingPeriodDiv2) == 0))
+    {
+        LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount);
+        iTimeToSample = true;
+#else
+    // no need to do anything, always a good time to sample.
+    // Sample time filtering is done in IttSamplerImpl:SampleImpl() function
+#endif
+        return true;
+#ifdef ITT_EVENT_HANDLER    
+    }
+    else 
+    {
+        return false;
+    }
+#endif
+}
+
+/*
+ * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum)
+ * 
+ * @param TUint32 program counter
+ * @param TUint32 sample number
+ */
+TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum)
+{	
+    // in order to avoid overloading the interrupt
+	// only one dynamic file in each 50ms is added to the stream
+	// with the application of the tool in mind, this is
+	// a reasonable measure
+
+    // encode a process binary
+    sampleDescriptor.Zero();
+	// original 
+	if((sampleNum % 20) != 0) return 0;
+	if((sampleNum % 40) == 0)
+	{
+		// encode a library binary
+		sampleDescriptor.Zero();
+		DObjectCon* libs = Kern::Containers()[ELibrary];
+		TInt libCount = libs->Count();
+		
+		// go 20 binaries through at a time
+		for(TInt i=0;i<20;i++)
+		{
+			if(currentLibCount >= libCount)
+			{
+				currentLibCount = 0;
+			}
+			
+			DLibrary* lib = (DLibrary*)(*libs)[currentLibCount];
+			currentLibCount++;
+			
+			DCodeSeg* seg = lib->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->sample[0] = seg->iFileName->Length();
+					sampleDescriptor.Append(*(seg->iFileName));
+					sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
+					sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
+#ifdef ITT_EVENT_HANDLER
+					sampleDescriptor.Append((TUint8*)&(sampleNum),4);
+					//Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+					this->iFirstSampleTaken = ETrue;
+#else
+		            //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+#endif
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->sample[0] = sampleDescriptor.Size();
+					return sampleDescriptor.Size()+1;
+				}
+			}
+		}
+	} else
+	{
+		SDblQue* codeSegList = Kern::CodeSegList();
+		//Kern::Printf("PI");
+		//TUint c = 0;
+		// the global list
+		for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+		{				
+			DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink);
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->sample[0] = seg->iFileName->Length();
+					sampleDescriptor.Append(*(seg->iFileName));
+					sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
+					sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
+#ifdef ITT_EVENT_HANDLER
+                    sampleDescriptor.Append((TUint8*)&(sampleNum),4);
+                    //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+                    this->iFirstSampleTaken = ETrue;                    
+#else
+					//Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+#endif					
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->sample[0] = sampleDescriptor.Size();
+					return sampleDescriptor.Size()+1;
+				}
+			}
+		}	
+	}
+	return 0;
+}
+
+/*
+ * IttSamplerImpl::Reset()
+ */
+void IttSamplerImpl::Reset()
+{
+    iTimeToSample = EFalse;
+#ifdef ITT_EVENT_HANDLER
+    iFirstSampleTaken = EFalse;
+#endif
+	this->currentLibCount = 0;
+	this->itt_sample = (TUint8*)&(this->sample[0]);
+	sampleDescriptor.Zero();
+
+//	#ifdef ITT_TEST	
+	SDblQue* codeSegList = Kern::CodeSegList();
+	// the global list
+	for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+	{				
+		DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink);
+		//if(seg != 0)
+		{
+			if( (seg->iMark & 0x80) > 0)
+			{
+				seg->iMark = (seg->iMark & ~0x80);
+			}
+		}
+	}	
+	// the garbage list
+	DObjectCon* libs = Kern::Containers()[ELibrary];
+	TInt libCount = libs->Count();
+	for(TInt i=0;i<libCount;i++)
+	{
+		DLibrary* lib = (DLibrary*)(*libs)[i];
+		DCodeSeg* seg = lib->iCodeSeg;
+		if( (seg->iMark & 0x80) > 0)
+		{
+			seg->iMark = (seg->iMark & ~0x80);
+		}
+	}
+	
+	DObjectCon* procs = Kern::Containers()[EProcess];
+	TInt procCount = procs->Count();
+	for(TInt i=0;i<procCount;i++)
+	{
+		DProcess* pro = (DProcess*)(*procs)[i];
+		DCodeSeg* seg = pro->iCodeSeg;
+		if(seg != 0)
+		{
+			if( (seg->iMark & 0x80) > 0)
+			{
+				seg->iMark = (seg->iMark & ~0x80);
+			}
+		}
+	}
+	//#endif   //ITT_TEST
+}
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,976 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "MemSamplerImpl.h"
+
+// for testing precise stack utilization tracing...
+// crashes at the moment
+
+#include <nk_cpu.h>
+
+#if !defined(__NKERN_H__)
+#include <nkern.h>
+#endif 
+
+#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext))
+#define PROFILER_CHUNK_MARK		((TUint32)0x00001000)
+#define PROFILER_MEM_THREAD_MARK	((TUint32)0x00000001)
+#define PROFILER_LIBRARY_MARK    ((TUint32)0x10000000)
+#define PROFILER_MEM_THREAD_UNMARK  ~PROFILER_MEM_THREAD_MARK
+
+#ifdef MEM_EVENT_HANDLER
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+_LIT8(KMemVersion,"2.03");
+#else
+_LIT8(KMemVersion, "2.02");
+#endif
+#else
+_LIT8(KMemVersion, "1.56");
+#endif
+
+DMemSamplerImpl::DMemSamplerImpl() :
+	sampleDescriptor(&(this->sample[1]),0,256)
+    {
+    LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori");
+
+	iCount = 0;
+		
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	iSampleType = ESampleThreads;
+#else
+	iSampleThreads = true;
+#endif
+	iTimeToSample = false;
+	
+	iTotalMemoryOk = false;
+	iTotalMemoryNameOk = false;
+	
+	iNewChunkCount = 0;
+	iChunkCount = 0;
+	iChunksProcessing = ENothingToProcess;
+    iThreadsProcessing = ENothingToProcess;
+	
+	iNewThreadCount = 0;
+	iThreadCount = 0;
+	
+	// reset data structures
+    for(TInt i(0);i<KProfilerMaxChunksAmount;i++)
+        {
+        // heap chunks
+        this->heapChunksToSample[i] = 0;
+        this->heapChunkNamesToReport[i] = 0;
+        }
+    
+    for(TInt i(0);i<KProfilerMaxThreadsAmount;i++)
+        {
+        // threads
+        this->threadsToSample[i] = 0;
+        this->threadNamesToReport[i] = 0;
+        }
+    
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+    iLibrariesProcessing = ENothingToProcess;
+    iNewLibraryCount = 0;
+    iLibraryCount = 0;
+    
+    for(TInt i(0); i<KProfilerMaxLibrariesAmount; i++)
+        {
+        // libraries
+        this->librariesToSample[i] = 0;
+        this->libraryNamesToReport[i] = 0;
+        }
+#endif
+
+    }
+
+DMemSamplerImpl::~DMemSamplerImpl()
+    {
+
+    }
+
+TInt DMemSamplerImpl::CreateFirstSample()
+    {
+    LOGSTRING("MemSamplerImpl::CreateFirstSample - entry");
+	
+	this->sampleDescriptor.Zero();
+	this->sampleDescriptor.Append(_L8("Bappea_V"));
+	this->sampleDescriptor.Append(KMemVersion);
+	this->sampleDescriptor.Append(_L8("_MEM"));
+	
+	sample[0] = this->sampleDescriptor.Size();
+
+	LOGSTRING("MemSamplerImpl::CreateFirstSample - exit");
+
+	return (TInt)(sample[0]+1);
+    }
+
+TBool DMemSamplerImpl::SampleNeeded()
+    {
+	iCount++;
+#ifdef MEM_EVENT_HANDLER
+    // make the collection of chunks/threads only once, rest will be collected with mem event handler
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0))
+#else
+    if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0))
+#endif
+#else
+	if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)
+#endif
+	    {
+        LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount);
+		iTimeToSample = true;
+		return true;
+        }
+	else 
+	    {
+		return false;
+        }
+
+    }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+TInt DMemSamplerImpl::SampleImpl()
+    {    
+    // Sample threads:
+    if( iSampleType == ESampleThreads )
+        {    
+        if(this->iThreadsProcessing == ENothingToProcess )
+            {     
+            if(!iTimeToSample)
+                {
+                return 0;
+                }
+            else
+                {
+                iTimeToSample = false;
+                // gather first all thread stacks
+                return GatherThreads();
+                }
+            }
+        else
+            {
+            // process now thread stack list
+            TInt length = this->ProcessThreads();
+
+            if(length == 0)
+                {
+                this->iThreadsProcessing = ENothingToProcess;
+                // switch to collect chunk data
+                iSampleType = ESampleChunks;
+                }
+            return length;
+            }
+        }
+
+    // Sample chunks:
+    if( iSampleType == ESampleChunks )
+        {
+        if(this->iChunksProcessing == ENothingToProcess)
+            {
+            if(!iTimeToSample)
+                {
+                return 0;
+                }
+            else
+                {
+                iTimeToSample = false;
+                // gather first all chunks
+                return GatherChunks();
+                }
+            }
+        else
+            {
+            // still something to go through in lists
+            TInt length = this->ProcessChunks();
+        
+            if(length == 0) 
+            {
+                this->iChunksProcessing = ENothingToProcess;
+                // switch to collect library data
+                iSampleType = ESampleLibraries;
+                //iSampleThreads = true;
+            }
+            return length;
+            }
+        }
+        
+    // Sample libraries:
+    if( iSampleType == ESampleLibraries )
+        {
+        if(this->iLibrariesProcessing == ENothingToProcess )
+            {        
+            if(!iTimeToSample)
+                {             
+                return 0;
+                }
+            else
+                {
+                iTimeToSample = false;
+                // gather libraries
+                return GatherLibraries();
+                }
+            }
+        else
+            {
+            // process now thread stack list
+            TInt length = this->ProcessLibraries();
+            if(length == 0)
+                {
+                this->iLibrariesProcessing = ENothingToProcess;
+                // switch to collect chunk data
+                iSampleType = ESampleThreads;
+                }
+            return length;
+            }
+        }
+
+    // should not reach this point...
+    return 0;
+    }
+#else
+TInt DMemSamplerImpl::SampleImpl()
+    {
+    // check if either chunk or thread lists have unprocessed items
+    if(this->iChunksProcessing == ENothingToProcess && !iSampleThreads)
+        {
+        if(!iTimeToSample)
+            {
+            return 0;
+            }
+        else
+            {
+            iTimeToSample = false;
+            // gather first all chunks
+            return GatherChunks();
+            }
+        }
+    else if(!iSampleThreads)
+        {
+        // still something to go through in lists
+        TInt length = this->ProcessChunks();
+        
+        if(length == 0) 
+            {
+            this->iChunksProcessing = ENothingToProcess;
+            // switch to collect thread data
+            iSampleThreads = true;
+            }
+        return length;
+        }
+    
+    if(this->iThreadsProcessing == ENothingToProcess && iSampleThreads)
+        {
+        if(!iTimeToSample)
+            {
+            return 0;
+            }
+        else
+            {
+            iTimeToSample = false;
+            // gather first all thread stacks
+            return GatherThreads();
+            }
+        }
+    
+    else if(iSampleThreads)
+        {
+        // process now thread stack list
+        TInt length = this->ProcessThreads();
+
+        if(length == 0)
+            {
+            this->iThreadsProcessing = ENothingToProcess;
+            // switch to collect chunk data
+            iSampleThreads = false;
+            }
+        return length;
+        }
+
+    // should not reach this point...
+    return 0;
+    }
+#endif
+
+inline TInt DMemSamplerImpl::GatherChunks()
+    {
+    // encode a process binary
+    name.Zero();
+    
+    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+    DObjectCon& chunks = *Kern::Containers()[EChunk];
+    chunks.Wait();  // Obtain the container mutex so the list does get changed under us
+    
+    this->iChunkCount = 0; 
+    this->iNewChunkCount = 0;
+    this->iTotalMemoryOk = false;
+    TInt totalChunkCount(chunks.Count());
+    DChunk* c; 
+    
+    for(TInt i(0);i<totalChunkCount;i++)
+        {
+        c = (DChunk*)(chunks)[i];
+
+        LOGSTRING3("Processing chunk %d, tag: 0x%x",i,TAG(c));
+        
+        if( (TAG(c) & 0x0000ffff) != PROFILER_CHUNK_MARK)
+            {
+            LOGSTRING4("Marking chunk %d/%d, old tag 0x%x",i,(totalChunkCount-1), TAG(c));
+            // this chunk has not been tagged yet
+            name.Zero();
+            c->TraceAppendName(name,false);
+            const TUint8* ptr = name.Ptr();
+            
+            TAG(c) = (PROFILER_CHUNK_MARK);
+            this->heapChunkNamesToReport[iNewChunkCount] = c;
+            iNewChunkCount++;
+            }
+
+        // the chunk has been tagged, add heap chunks to the list
+        this->heapChunksToSample[this->iChunkCount] = c;
+        this->iChunkCount++;
+        LOGSTRING2("Added chunk %d to Chunks",i);
+        }
+
+    if(this->iChunkCount > 0 || this->iNewChunkCount > 0)
+        {
+        this->iChunksProcessing = EStartingToProcess;
+        
+        // process the first sample
+        TInt length = this->ProcessChunks();
+        
+        if(length == 0)
+            {
+            this->iChunksProcessing = ENothingToProcess;
+            }
+    
+        chunks.Signal();  // Release the container mutex
+        NKern::ThreadLeaveCS();  // End of critical section
+        return length;
+        }
+
+    LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); 
+    chunks.Signal();  // Release the container mutex
+    NKern::ThreadLeaveCS();  // End of critical section
+    return 0;
+    }
+
+inline TInt DMemSamplerImpl::GatherThreads()
+    {
+    // The thread memory consumption
+    
+    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+    DObjectCon& threads = *Kern::Containers()[EThread];
+    threads.Wait(); // Obtain the container mutex so the list does get changed under us
+    
+    this->iThreadCount = 0; 
+    this->iNewThreadCount = 0;
+    this->iTotalMemoryOk = false;           
+
+    TInt totalThreadCount = threads.Count();
+
+    for(TInt i(0);i<totalThreadCount;i++)
+        {
+        DThread* t = (DThread*)(threads)[i];
+
+        LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
+
+        if( (TAG(t) & PROFILER_MEM_THREAD_MARK) == 0)
+            {
+            LOGSTRING4("Marking thread %d/%d, old tag 0x%x",i,(totalThreadCount-1), TAG(t));
+            // this thread's chunk has not been reported yet
+            this->threadNamesToReport[iNewThreadCount] = t;
+            iNewThreadCount++;
+            // tag the thread
+            TAG(t) |= PROFILER_MEM_THREAD_MARK;
+            }
+
+        // the chunk has been tagged, add heap chunks to the list
+        this->threadsToSample[this->iThreadCount] = t;
+        this->iThreadCount++;
+        LOGSTRING2("Added thread %d to threads to sample",i);
+        }
+    
+    if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
+        {
+        this->iThreadsProcessing = EStartingToProcess;
+        
+        // process the first sample
+        TInt length = this->ProcessThreads();
+        
+        if(length == 0)
+            {
+            this->iThreadsProcessing = ENothingToProcess;
+            }
+        threads.Signal();  // Release the container mutex
+        NKern::ThreadLeaveCS();  // End of critical section
+        return length;
+        }
+    
+    LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); 
+    threads.Signal();  // Release the container mutex
+    NKern::ThreadLeaveCS();  // End of critical section
+    return 0;
+    }
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+
+inline TInt DMemSamplerImpl::GatherLibraries()
+    {
+    LOGTEXT("MemSamplerImpl::GatherLibraries() - entry");
+    // encode a process binary
+    name.Zero();
+    
+    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+    DObjectCon& libs = *Kern::Containers()[ELibrary];
+    libs.Wait();  // Obtain the container mutex so the list does get changed under us
+    
+    this->iLibraryCount = 0; 
+    this->iNewLibraryCount = 0;
+    this->iTotalMemoryOk = false;
+    TInt totalLibCount(libs.Count());
+    DLibrary* l; 
+    
+    for(TInt i(0);i<totalLibCount;i++)
+        {
+        l = (DLibrary*)(libs)[i];
+
+        LOGSTRING3("Processing library %d, tag: 0x%x",i,TAG(l));
+        
+        if( (TAG(l) & 0xffffffff) != PROFILER_LIBRARY_MARK)
+            {
+            LOGSTRING4("Marking library %d/%d, old tag 0x%x",i,(totalLibCount-1), TAG(l));
+            // this library has not been tagged yet
+            name.Zero();
+            l->TraceAppendName(name,false);
+            const TUint8* ptr = name.Ptr();
+            
+            TAG(l) = (PROFILER_LIBRARY_MARK);
+            this->libraryNamesToReport[iNewLibraryCount] = l;
+            iNewLibraryCount++;
+            }
+
+        // the library has been tagged, add library to the list
+        this->librariesToSample[this->iLibraryCount] = l;
+        this->iLibraryCount++;
+        LOGSTRING2("Added library %d to Libraries",i);
+        }
+
+    if(this->iLibraryCount > 0 || this->iNewLibraryCount > 0)
+        {
+        this->iLibrariesProcessing = EStartingToProcess;
+        
+        // process the first sample
+        TInt length = this->ProcessLibraries();
+        
+        if(length == 0)
+            {
+            this->iLibrariesProcessing = ENothingToProcess;
+            }
+    
+        libs.Signal();  // Release the container mutex
+        NKern::ThreadLeaveCS();  // End of critical section
+        return length;
+        }
+
+    LOGTEXT("MemSamplerImpl::SampleImpl - Error, no libraries"); 
+    libs.Signal();  // Release the container mutex
+    NKern::ThreadLeaveCS();  // End of critical section
+    return 0;
+    }
+#endif
+
+inline TInt DMemSamplerImpl::ProcessChunks()
+    {
+    if(iNewChunkCount > 0)
+        {
+        if(this->iChunksProcessing == EStartingToProcess)
+            {
+            // this is the first sample, encode a code for names
+            this->iChunksProcessing = EProcessingNames;
+            return EncodeNameCode();
+            }
+
+        if(iTotalMemoryNameOk == false)
+            {
+            return EncodeTotalMemoryName();
+            }
+        
+        // there are new chunk names to report
+        iNewChunkCount--;
+        DChunk* c = this->heapChunkNamesToReport[iNewChunkCount];
+        return EncodeChunkName(*c);
+        
+        }
+    else if(iChunkCount > 0)
+        {
+        if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess)
+            {
+            // this is the first data sample, encode a code for data
+            this->iChunksProcessing = EProcessingData;
+            return EncodeDataCode();
+            }
+        
+        if(this->iTotalMemoryOk == false)
+            {
+            return EncodeTotalMemory();	
+            }
+
+        // there are no new chunks to report
+        // thus generate the real report
+        iChunkCount--;
+        DChunk* c = this->heapChunksToSample[iChunkCount];
+        return EncodeChunkData(*c);
+        }
+    else
+        {
+        // everything is processed
+        LOGSTRING2(" Chunks processed! Chunk count = %d", iChunkCount);
+#ifdef MEM_EVENT_HANDLER
+        this->iChunksGathered = true;
+        Kern::Printf("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount);
+#endif
+        return 0;
+        }
+    }
+
+inline TInt DMemSamplerImpl::ProcessThreads()
+    {
+
+    if(iNewThreadCount > 0)
+        {
+        if(this->iThreadsProcessing == EStartingToProcess)
+            {
+            // this is the first sample, encode a code for names
+            this->iThreadsProcessing = EProcessingNames;
+            return EncodeNameCode();
+            }
+        
+        if(iTotalMemoryNameOk == false)
+            {
+            return EncodeTotalMemoryName();
+            }
+
+        iNewThreadCount--;
+        DThread* t = this->threadNamesToReport[iNewThreadCount];
+        return EncodeChunkName(*t);
+        }
+    else if(iThreadCount > 0)
+        {
+        if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess)
+            {
+            // this is the first data sample, encode a code for data
+            this->iThreadsProcessing = EProcessingData;
+            return EncodeDataCode();
+            }
+
+        if(this->iTotalMemoryOk == false)
+            {
+            return EncodeTotalMemory(); 
+            }
+
+        // there are no new threads to report
+        // thus generate the real report
+        iThreadCount--;
+        DThread* t = this->threadsToSample[iThreadCount];
+        return EncodeChunkData(*t);
+        }
+    else
+        {   
+        // everything is processed
+        LOGSTRING2(" Threads processed! Thread count = %d", iThreadCount);
+#ifdef MEM_EVENT_HANDLER
+        this->iThreadsGathered = true;
+        Kern::Printf("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount);
+#endif
+        return 0;
+        }
+    }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::ProcessLibraries()
+    {
+    LOGTEXT("ProcessLibraries - entry");
+    if(iNewLibraryCount > 0)
+        {
+        if(this->iLibrariesProcessing == EStartingToProcess)
+            {
+            // this is the first sample, encode a code for names
+            this->iLibrariesProcessing = EProcessingNames;
+            return EncodeNameCode();
+            }
+
+        if(iTotalMemoryNameOk == false)
+            {
+            return EncodeTotalMemoryName();
+            }
+        
+        // there are new library names to report
+        iNewLibraryCount--;
+        DLibrary* l = this->libraryNamesToReport[iNewLibraryCount];
+        return EncodeChunkName(*l);
+        
+        }
+    else if(iLibraryCount > 0)
+        {
+        if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess)
+            {
+            // this is the first data sample, encode a code for data
+            this->iLibrariesProcessing = EProcessingData;
+            return EncodeDataCode();
+            }
+        
+        if(this->iTotalMemoryOk == false)
+            {
+            return EncodeTotalMemory(); 
+            }
+
+        // there are no new libraries to report
+        // thus generate the real report
+        iLibraryCount--;
+        DLibrary* l = this->librariesToSample[iLibraryCount];
+        return EncodeChunkData(*l);
+        }
+    else
+        {
+        // everything is processed
+        LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount);
+
+        this->iLibrariesGathered = true;
+        Kern::Printf("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount);
+
+        return 0;
+        }
+    }
+#endif
+inline TInt DMemSamplerImpl::EncodeNameCode()
+    {
+	sample[0] = 1;
+	sample[1] = 0xaa;
+	return 2;
+    }
+
+inline TInt DMemSamplerImpl::EncodeDataCode()
+    {
+	sample[0] = 1;
+	sample[1] = 0xdd;
+	return 2;
+    }
+
+inline TInt DMemSamplerImpl::EncodeTotalMemoryName()
+    {
+	this->iTotalMemoryNameOk = true;
+	
+	TUint8* size = &sample[0];
+	*size = 0;
+		
+	// encode name
+	this->sampleDescriptor.Zero();
+	this->sampleDescriptor.Append(_L("TOTAL_MEMORY"));
+	*size += this->sampleDescriptor.Size();
+		
+	// add id here
+	TUint32 id(0xbabbeaaa);
+	this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+	*size += sizeof(TUint32);
+	
+	// the size is the descriptor length + the size field
+	return ((TInt)(*size))+1;	
+    }
+
+inline TInt DMemSamplerImpl::EncodeTotalMemory()
+    {	
+	
+	TUint8* size = &sample[0];
+	*size = 0;
+
+	NKern::LockSystem();
+	TInt freeRam = Kern::FreeRamInBytes();
+	TInt totalRam = Kern::SuperPage().iTotalRamSize;
+	NKern::UnlockSystem();
+
+	this->sampleDescriptor.Zero();
+	
+	TUint32 id(0xbabbeaaa);
+	TInt zero(0);
+		
+	this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+	*size += sizeof(TUint);
+	
+	this->sampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
+	*size += sizeof(TInt);
+		
+	// append the cell amount allocated
+	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+	*size += sizeof(TInt);
+	
+	// append the chunk size
+	this->sampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
+	*size += sizeof(TInt);
+		
+	// append the thread user stack size
+	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+	*size += sizeof(TInt);
+
+	this->iTotalMemoryOk = true;
+
+	return ((TInt)(*size))+1;
+    }
+
+inline TInt DMemSamplerImpl::EncodeChunkName(DChunk& c)
+    {	
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+		
+	// encode chunk name
+	this->sampleDescriptor.Zero();
+	this->sampleDescriptor.Append(_L("C_"));
+	c.TraceAppendFullName(this->sampleDescriptor,false);
+	*size += this->sampleDescriptor.Size();
+		
+	// add chunk object address here
+	TUint32 chunkAddr((TUint32)&c);
+	this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
+	*size += sizeof(TUint32);
+
+	// the size is the descriptor length + the size field
+	LOGSTRING2("Non-Heap Chunk Name - %d",*size);
+	return ((TInt)(*size))+1;			
+    }
+
+inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t)
+    {		
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+	this->sampleDescriptor.Zero();
+	
+	this->sampleDescriptor.Append(_L("T_"));
+	t.TraceAppendFullName(this->sampleDescriptor,false);
+	*size += this->sampleDescriptor.Size();
+	
+	// copy the 4 bytes from the thread id field
+	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+	*size += sizeof(TUint);
+
+	// the size is the descriptor length + the size field
+	LOGSTRING2("Name - %d",*size);
+	return ((TInt)(*size))+1;
+    }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::EncodeChunkName(DLibrary& l)
+    {   
+    // the size of the following name is in the first byte
+    TUint8* size = &sample[0];
+    *size = 0;
+        
+    // encode library name
+    this->sampleDescriptor.Zero();
+    this->sampleDescriptor.Append(_L("L_"));
+    l.TraceAppendFullName(this->sampleDescriptor,false);
+    *size += this->sampleDescriptor.Size();
+        
+    // add chunk object address here
+    TUint32 libAddr((TUint32)&l);
+    this->sampleDescriptor.Append((TUint8*)&(libAddr),sizeof(TUint32));
+    *size += sizeof(TUint32);
+
+    // the size is the descriptor length + the size field
+    LOGSTRING2("Name - %d",*size);
+    return ((TInt)(*size))+1;           
+    }
+#endif
+inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c)
+    {
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+	this->sampleDescriptor.Zero();
+	TInt zero(0);
+
+	TUint32 address((TUint32)&c);
+		
+	this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+	*size += sizeof(TUint);
+	
+	// copy the total amount of memory allocated
+	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
+	*size += sizeof(TInt);
+		
+	// append the cell amount allocated
+	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+	*size += sizeof(TInt);
+	
+	// append the chunk size
+	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
+	*size += sizeof(TUint);
+		
+	// append the thread user stack size
+	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+	*size += sizeof(TInt);
+
+	LOGSTRING2("Data - %d",*size);
+	return ((TInt)(*size))+1;
+
+    }
+
+inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t)
+    {
+	LOGTEXT("MemSamplerImpl::EncodeChunkData - entry");
+	//LOGSTRING2("MemSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t);
+		
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+	this->sampleDescriptor.Zero();
+
+	LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared");
+
+	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+	*size += sizeof(TUint);
+		
+	// copy the total amount of memory allocated for user side stack
+	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+	*size += sizeof(TInt);
+
+	TInt zero(0);		
+	// append the cell amount allocated (zero, not in use here)
+	this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
+	*size += sizeof(TInt);
+	
+	// append the chunk size (this is not a chunk)
+	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
+	*size += sizeof(TUint);
+
+	// append user stack (max) size
+	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+	*size += sizeof(TInt);
+
+	LOGSTRING2("Data -> %d",*size);
+	return ((TInt)(*size))+1;
+    }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::EncodeChunkData(DLibrary& l)
+    {
+    LOGTEXT("MemSamplerImpl::EncodeChunkData (Library) - entry");
+    // the size of the following name is in the first byte
+    TUint8* size = &sample[0];
+    *size = 0;
+    this->sampleDescriptor.Zero();
+    
+    TUint32 address((TUint32)&l);
+        
+    this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+    *size += sizeof(TUint);
+             
+	this->sampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
+    *size += sizeof(TInt); 
+             
+    this->sampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
+    *size += sizeof(TInt);  
+        
+    TInt zero(0);   
+    this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);   
+        
+    this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);   
+
+    LOGSTRING2("LData - %d",*size);
+    return ((TInt)(*size))+1;
+
+    }
+#endif
+void DMemSamplerImpl::Reset()
+    {
+	Kern::Printf("MemSamplerImpl::Reset");
+	iCount = 0; // sample threads 1 cycle after actual MEM sample time...
+    this->iTimeToSample = false;
+    this->iChunkCount = 0;
+	this->iNewChunkCount = 0;
+	
+	this->iTotalMemoryOk = false;
+	this->iTotalMemoryNameOk = false;
+
+	this->iChunksProcessing = ENothingToProcess;
+    this->iThreadsProcessing = ENothingToProcess;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+    this->iLibrariesProcessing = ENothingToProcess;
+    this->iSampleType = ESampleThreads;
+#else
+    this->iSampleThreads = true;
+#endif
+    
+	this->sampleDescriptor.Zero();
+	
+	// clear all chunk tags
+    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+	DObjectCon* chunks = Kern::Containers()[EChunk];
+    chunks->Wait(); // Obtain the container mutex so the list does get changed under us
+
+	TInt totalChunkCount = chunks->Count();
+	for(TInt i=0;i<totalChunkCount;i++)
+	    {
+		DChunk* c = (DChunk*)(*chunks)[i];
+		TAG(c) = 0;
+	    }
+	chunks->Signal();  // Release the container mutex
+
+	Kern::Printf("MemSamplerImpl::Reset");
+	this->iThreadCount = 0;
+	this->iNewThreadCount = 0;
+	this->sampleDescriptor.Zero();
+
+	// clear all chunk tags
+	DObjectCon* threads = Kern::Containers()[EThread];
+    threads->Wait(); // Obtain the container mutex so the list does get changed under us
+
+	TInt totalThreadCount = threads->Count();
+	for(TInt i=0;i<totalThreadCount;i++)
+	    {
+		DThread* t = (DThread*)(*threads)[i];
+		TAG(t) = (TAG(t) & 0xfffffffe);
+	    }
+	threads->Signal();  // Release the container mutex
+	
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+	this->iLibraryCount = 0;
+	this->iNewLibraryCount = 0;
+	this->sampleDescriptor.Zero();
+
+	// clear all library tags
+	DObjectCon* libs = Kern::Containers()[ELibrary];
+	libs->Wait(); // Obtain the container mutex so the list does get changed under us
+
+	TInt totalLibraryCount = libs->Count();
+	for(TInt i=0; i<totalLibraryCount; i++)
+	    {
+        DLibrary* l = (DLibrary*)(*libs)[i];
+        TAG(l) = (TAG(l) & 0xefffffff);
+	    }
+	libs->Signal();  // Release the container mutex
+#endif
+
+    NKern::ThreadLeaveCS();  // End of critical section
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/MemoryEventHandler.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,724 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <arm.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <nk_trace.h>
+
+#include "MemoryEventHandler.h"
+
+
+DMemoryEventHandler::DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer)
+    :   DKernelEventHandler(EventHandler, this), 
+        iSampleBuffer(aSampleBuffer), 
+        iSampleDescriptor(&(this->iSample[1]),0,256)
+    {
+//    Kern::Printf("DMemoryEventHandler::DMemoryEventHandler()");
+    iCount = 0;
+    iPreviousCount = 0;
+    }
+
+
+TInt DMemoryEventHandler::Create()
+    {
+//    Kern::Printf("DMemoryEventHandler::Create()");
+
+    TInt err(Kern::MutexCreate(iLock, _L("MemoryEventHandlerLock"), KMutexOrdGeneral0));
+    if (err != KErrNone)
+        return err;
+    
+    return Add();
+    }
+
+
+DMemoryEventHandler::~DMemoryEventHandler()
+    {
+//    Kern::Printf("DMemoryEventHandler::~DMemoryEventHandler()");
+
+    if (iLock)
+        iLock->Close(NULL);
+       
+    }
+
+
+TInt DMemoryEventHandler::Start()
+    {
+//    Kern::Printf("DMemoryEventHandler::Start()");
+
+    iTracking = ETrue;
+    return KErrNone;
+    }
+
+
+TInt DMemoryEventHandler::Stop()
+    {
+//    Kern::Printf("DMemoryEventHandler::Stop()");
+
+    iTracking = EFalse;
+    return KErrNone;
+    }
+
+TBool DMemoryEventHandler::SampleNeeded()
+    {
+    LOGTEXT("DMemoryEventHandler::SampleNeeded()");
+    
+    // increase the coutner by one on each round
+    iCount++;
+    
+    // check if event handler was not running
+//    if(!iTracking)
+//        return false; // return false
+    
+    return true;
+    }
+
+
+TUint DMemoryEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis)
+    {
+    return ((DMemoryEventHandler*)aThis)->HandleEvent(aType, a1, a2);
+    }
+
+
+
+TUint DMemoryEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
+    {
+    // debug
+//    Kern::Printf("New kernel event received, %d", aType);
+    
+    if (iTracking/* && iCount != iPreviousCount*/)
+        {
+//        iPreviousCount = iCount;
+        iCounters[aType]++;
+        switch (aType)
+            {
+            // capture only chunk creation, updates and destroyal
+            case EEventNewChunk:
+                {
+                DChunk* chunk = (DChunk*)a1;
+                HandleAddChunk(chunk);
+                break;
+                }
+            case EEventUpdateChunk:   
+                HandleUpdateChunk((DChunk*)a1);
+                break;
+            case EEventDeleteChunk:      
+                HandleDeleteChunk((DChunk*)a1);
+                break;
+//            case EEventAddProcess:
+//                Kern::Printf("Process added: 0x%08x", (DProcess*)a1);
+//                break;
+//            case EEventUpdateProcess:
+//                Kern::Printf("DProcess updated: 0x%08x", (DProcess*)a1);
+//                break;
+//            case EEventRemoveProcess:
+//                Kern::Printf("DProcess removed: 0x%08x", (DProcess*)a1);
+//                break;
+//            case EEventAddCodeSeg:
+//                Kern::Printf("DCodeSeg added: 0x%08x", (DCodeSeg*)a1);
+//                break;
+//            case EEventRemoveCodeSeg:
+//                Kern::Printf("DCodeSeg deleted: 0x%08x", (DCodeSeg*)a1);
+//                break;
+            case EEventAddThread:
+                HandleAddThread((DThread*)a1);
+                break;
+            case EEventUpdateThread:    // thread renaming
+                HandleUpdateThread((DThread*)a1);
+                break;
+//            case EEventKillThread:
+            case EEventRemoveThread:
+                HandleDeleteThread((DThread*)a1);
+                break;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+            case EEventAddLibrary:
+                HandleAddLibrary((DLibrary*)a1, (DThread*)a2);
+                break;
+            case EEventRemoveLibrary:
+                HandleDeleteLibrary((DLibrary*)a1);
+                break;
+#endif
+            
+            // ignore exception events
+            case EEventSwExc:
+            case EEventHwExc:
+         
+            default:
+                break;
+            }
+        }
+//    else if(iTracking && iCount == iPreviousCount)
+//        {
+//        // if time stamp is not updated profiling has stopped
+//        Stop();
+//        }
+    return DKernelEventHandler::ERunNext;
+    }
+
+TInt DMemoryEventHandler::EncodeNameCode()
+    {
+    iSample[0] = 1;
+    iSample[1] = 0xaa;
+    return 2;
+    }
+
+// encode mark for new chunk or thread
+TInt DMemoryEventHandler::EncodeNewCode()
+    {
+    iSample[0] = 1;
+    iSample[1] = 0xda;
+    return 2;
+    }
+
+// encode mark for update of chunk or thread
+TInt DMemoryEventHandler::EncodeUpdateCode()
+    {
+    iSample[0] = 1;
+    iSample[1] = 0xdb;
+    return 2;
+    }
+
+// encode mark for removal of chunk or thread
+TInt DMemoryEventHandler::EncodeRemoveCode()
+    {
+    iSample[0] = 1;
+    iSample[1] = 0xdc;
+    return 2;
+    }
+
+// encode the memory sample header in all memory changes
+TInt DMemoryEventHandler::AddHeader()
+    {
+    TInt err(KErrNone);
+    
+    TUint8 number(4);    // mem sampler id
+
+    // check if iCount bigger than previous, i.e. at least 1 ms has passed from the previous sample
+    if(iCount > iPreviousCount)
+        {
+        err = this->iSampleBuffer->AddSample(&number,1);
+        err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
+    
+        // add data chunk header
+        TInt length(EncodeUpdateCode());
+        err = iSampleBuffer->AddSample(iSample, length);
+        
+        // add total memory sample in the beginning of each sample
+        length = EncodeTotalMemory();
+        err = iSampleBuffer->AddSample(iSample, length);
+        AddFooter();    // end mark for total memory sample
+        }
+    iPreviousCount = iCount;
+    
+    // add actual sample
+    err = this->iSampleBuffer->AddSample(&number,1);
+    err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
+
+    return err;
+    }
+
+// encode the memory sample header in all memory changes
+TInt DMemoryEventHandler::AddFooter()
+    {
+    TInt err(KErrNone);
+    
+    TUint8 number(0);    // end mark
+    err = this->iSampleBuffer->AddSample(&number,1);
+    
+    return err;
+    }
+
+TInt DMemoryEventHandler::EncodeTotalMemory()
+    {   
+    
+    TUint8* size(&iSample[0]);
+    *size = 0;
+
+    NKern::LockSystem();
+    TInt freeRam(Kern::FreeRamInBytes());
+    TInt totalRam(Kern::SuperPage().iTotalRamSize);
+    NKern::UnlockSystem();
+
+    iSampleDescriptor.Zero();
+    
+    TUint32 id(0xbabbeaaa);
+    TInt zero(0);
+        
+    iSampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+    *size += sizeof(TUint);
+    
+    iSampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
+    *size += sizeof(TInt);
+        
+    // append the cell amount allocated
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);
+    
+    // append the chunk size
+    iSampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
+    *size += sizeof(TInt);
+        
+    // append the thread user stack size
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);
+
+    return ((TInt)(*size))+1;
+    }
+
+// handle chunk activity
+TBool DMemoryEventHandler::HandleAddChunk(DChunk* aChunk)
+    {    
+//    Kern::Printf("New DChunk created: 0x%08x, time: %d", aChunk, iCount);
+    
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // new chunk, add name of it
+    TInt length(EncodeNameCode());
+    iSampleBuffer->AddSample(iSample, length);
+
+    // new chunk, add name of it
+    length = EncodeChunkName(*aChunk);
+    iSampleBuffer->AddSample(iSample, length);
+    
+    // add new chunk tag
+    length = EncodeNewCode();
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aChunk);
+    iSampleBuffer->AddSample(iSample, length);
+    
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleUpdateChunk(DChunk* aChunk)
+    {
+//    Kern::Printf("DChunk updated: 0x%08x, time: %d", aChunk, iCount);
+    
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // add new chunk tag
+    TInt length(EncodeUpdateCode());
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aChunk);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleDeleteChunk(DChunk* aChunk)
+    {
+//    Kern::Printf("DChunk deleted: 0x%08x, time: %d", aChunk, iCount);
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // add new chunk tag
+    TInt length(EncodeRemoveCode());
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aChunk);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();
+    return ETrue;
+    }
+
+// handle process activity
+TBool DMemoryEventHandler::HandleAddProcess(DProcess *aProcess)
+    {
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleUpdateProcess(DProcess *aProcess)
+    {
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleDeleteProcess(DProcess *aProcess)
+    {
+    return ETrue;
+    }
+
+// handle thread activity
+TBool DMemoryEventHandler::HandleAddThread(DThread* aThread)
+    {
+//    Kern::Printf("DThread added: 0x%08x, time: %d", aThread->iId, iCount);
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // new thread, add name of it
+    TInt length(EncodeNameCode());
+    iSampleBuffer->AddSample(iSample, length);
+    
+    // new chunk, add name of it
+    length = EncodeChunkName(*aThread);
+    iSampleBuffer->AddSample(iSample, length);
+    
+    // add new chunk tag
+    length = EncodeNewCode();
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aThread);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleUpdateThread(DThread* aThread)
+    {
+//    Kern::Printf("DThread updated: 0x%08x, time: %d", aThread->iId, iCount);
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // add new chunk tag
+    TInt length(EncodeUpdateCode());
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aThread);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();    
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleDeleteThread(DThread* aThread)
+    {
+//    Kern::Printf("DThread deleted: 0x%08x, time: %d", aThread->iId, iCount);
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+    
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // add new chunk tag
+    TInt length(EncodeRemoveCode());
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aThread);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();  
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleAddLibrary(DLibrary* aLibrary, DThread* aThread)
+    {
+    LOGTEXT("DMemoryEventHandler::HandleAddLibrary");
+    Kern::Printf("DLibrary added: 0x%08x, time: %d", aLibrary, iCount);
+    // add header first
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    TInt err(AddHeader());
+        
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+    
+    // new library, add name of it
+    TInt length(EncodeNameCode());
+    iSampleBuffer->AddSample(iSample, length);
+        
+    // new chunk, add name of it
+    length = EncodeChunkName(*aLibrary);
+    iSampleBuffer->AddSample(iSample, length);
+        
+    // add new chunk tag
+    length = EncodeNewCode();
+    iSampleBuffer->AddSample(iSample, length);
+
+    length = EncodeChunkData(*aLibrary, *aThread);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();      
+    return ETrue;
+    }
+
+TBool DMemoryEventHandler::HandleDeleteLibrary(DLibrary* aLibrary)
+    {
+    Kern::Printf("DLibrary deleted: 0x%08x, time: %d", aLibrary, iCount);
+    NKern::ThreadEnterCS();
+    Kern::MutexWait(*iLock);
+    // add header first
+    TInt err(AddHeader());
+        
+    if(err != KErrNone)
+        {
+        return EFalse;
+        }
+        
+    // add new chunk tag
+    TInt length(EncodeRemoveCode());
+    iSampleBuffer->AddSample(iSample, length);
+    
+    DThread* nullPointer = NULL;
+    length = EncodeChunkData(*aLibrary, *nullPointer);
+    iSampleBuffer->AddSample(iSample, length);
+
+    // add end mark
+    AddFooter();
+    Kern::MutexSignal(*iLock);
+    NKern::ThreadLeaveCS();        
+    return ETrue;
+    }
+
+// encode chunk name 
+TInt DMemoryEventHandler::EncodeChunkName(DChunk& c)
+    {   
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+        
+    // encode chunk name
+    iSampleDescriptor.Zero();
+    iSampleDescriptor.Append(_L("C_"));
+    c.TraceAppendFullName(iSampleDescriptor,false);
+    *size += iSampleDescriptor.Size();
+        
+    // add chunk object address here
+    TUint32 chunkAddr((TUint32)&c);
+    iSampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
+    *size += sizeof(TUint32);
+
+    // the size is the descriptor length + the size field
+    LOGSTRING2("Non-Heap Chunk Name - %d",*size);
+    return ((TInt)(*size))+1;           
+    }
+
+// encode chunk name 
+TInt DMemoryEventHandler::EncodeChunkName(DThread& t)
+    {       
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+    iSampleDescriptor.Zero();
+    
+    iSampleDescriptor.Append(_L("T_"));
+    t.TraceAppendFullName(iSampleDescriptor,false);
+    *size += iSampleDescriptor.Size();
+    
+    // copy the 4 bytes from the thread id field
+    iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+    *size += sizeof(TUint);
+
+    // the size is the descriptor length + the size field
+    LOGSTRING2("Name - %d",*size);
+    return ((TInt)(*size))+1;
+    }
+
+// encode chunk name 
+TInt DMemoryEventHandler::EncodeChunkName(DLibrary& l)
+    {       
+    LOGTEXT("DMemoryEventHandler::EncodeChunkName (LIBRARY)");
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+    iSampleDescriptor.Zero();
+    
+    iSampleDescriptor.Append(_L("L_"));
+    l.TraceAppendFullName(iSampleDescriptor,false);
+    *size += iSampleDescriptor.Size();
+    
+    // copy the library address here
+    TUint32 libAddr((TUint32)&l);
+    iSampleDescriptor.Append((TUint8*) &libAddr,sizeof(TUint32));
+    *size += sizeof(TUint32);
+
+    // the size is the descriptor length + the size field
+    LOGSTRING2("Name - %d",*size);
+    return ((TInt)(*size))+1;
+    }
+
+// record thread stack changes
+TInt DMemoryEventHandler::EncodeChunkData(DThread& t)
+    {
+    LOGSTRING("DMemoryEventHandler::EncodeChunkDataT - entry");
+        
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+    iSampleDescriptor.Zero();
+
+    iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+    *size += sizeof(TUint);
+        
+    // copy the total amount of memory allocated for user side stack
+    iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+    *size += sizeof(TInt);
+
+    TInt zero(0);      
+    // append the cell amount allocated (zero, not in use here)
+    iSampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
+    *size += sizeof(TInt);
+    
+    // append the chunk size (this is not a chunk)
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
+    *size += sizeof(TUint);
+
+    // append user stack (max) size
+    iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+    *size += sizeof(TInt);
+
+//    Kern::Printf("TData -> %d",*size);
+    return ((TInt)(*size))+1;
+    }
+
+// record chunk changes
+TInt DMemoryEventHandler::EncodeChunkData(DChunk& c)
+    {
+    LOGSTRING("DMemoryEventHandler::EncodeChunkDataC - entry");
+    
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+    iSampleDescriptor.Zero();
+    TInt zero(0);
+
+    TUint32 address((TUint32)&c);
+        
+    iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+    *size += sizeof(TUint);
+    
+    // copy the total amount of memory allocated
+    iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
+    *size += sizeof(TInt);
+        
+    // append the cell amount allocated
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);
+    
+    // append the chunk size
+    iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
+    *size += sizeof(TUint);
+        
+    // append the thread user stack size
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);
+
+//    Kern::Printf("CData - %d",*size);
+    return ((TInt)(*size))+1;
+    }
+
+// record loaded libraries changes
+TInt DMemoryEventHandler::EncodeChunkData(DLibrary& l, DThread& t)
+    {    
+    LOGSTRING("DMemoryEventHandler::EncodeChunkDataL - entry");
+    
+    // the size of the following name is in the first byte
+    TUint8* size(&iSample[0]);
+    *size = 0;
+    iSampleDescriptor.Zero();
+    TInt zero(0);
+
+    TUint32 address((TUint32)&l);
+    
+    iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+    *size += sizeof(TUint);
+    
+    // append amount of memory that library is allocated
+    iSampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
+    *size += sizeof(TInt);
+            
+    // append count of how many times librarys is allocated
+    iSampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
+    *size += sizeof(TInt);
+    
+    if(&t != NULL)
+        {
+        // created by thread
+        iSampleDescriptor.Append((TUint8*)&(t),sizeof(TUint32));
+        }
+    else
+        {
+        // removed
+        iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint32));
+        }
+    *size += sizeof(TUint);
+            
+    // append the thread user stack size
+    iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+    *size += sizeof(TInt);
+    return ((TInt)(*size))+1;
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/PriSamplerImpl.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,312 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "PriSamplerImpl.h"
+
+#if !defined(__NKERN_H__)
+#include <nkern.h>
+#endif 
+
+#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext))
+#define PROFILER_THREAD_MARK		((TUint32)0x00000002)
+
+
+DPriSamplerImpl::DPriSamplerImpl() :
+	sampleDescriptor(&(this->sample[1]),0,256)
+    {
+	LOGTEXT("PriSamplerImpl::PriSamplerImpl() - konstruktori");
+
+	iCountti = 50;	// sample threads 16 cycles before actual MEM and PRI sample time...
+	iNewThreadCount = 0;
+	iThreadCount = 0;
+	iProcessing = ENothingToProcess;
+	
+	for(TInt i=0;i<KProfilerMaxThreadAmount;i++)
+	    {
+		this->threadsToSample[i] = 0;
+		this->threadNamesToReport[i] = 0;
+        }
+
+    }
+
+DPriSamplerImpl::~DPriSamplerImpl()
+    {
+	
+    }
+
+TInt DPriSamplerImpl::CreateFirstSample()
+    {
+	LOGTEXT("PriSamplerImpl::CreateFirstSample - entry");
+	
+	this->sampleDescriptor.Zero();
+	this->sampleDescriptor.Append(_L8("Bappea_V"));
+	this->sampleDescriptor.Append(PROFILER_PRI_SAMPLER_VERSION);
+	this->sampleDescriptor.Append(_L8("_PRI"));
+
+	sample[0] = this->sampleDescriptor.Size();
+
+	LOGTEXT("PriSamplerImpl::CreateFirstSample - exit");
+
+	return (TInt)(sample[0]+1);
+    }
+
+TBool DPriSamplerImpl::SampleNeeded()
+    {
+	iCountti++;
+	if(iCountti % (iPriSamplingPeriod) == 0) 
+	    {
+		LOGTEXT("PriSamplerImpl::SampleNeeded - true");
+		return true;
+        }
+	else 
+	    {
+		return false;
+        }
+    }
+
+
+TInt DPriSamplerImpl::SampleImpl()
+    {
+	/*
+	 *
+	 *	EKA-2 implementation of PRI trace
+	 *
+	 */
+	if(this->iProcessing == ENothingToProcess)
+	    {
+	    if((iCountti % iPriSamplingPeriod) != 0 ) return 0;
+	    
+        LOGTEXT("Processing threads...");
+
+        DObjectCon& threads = *Kern::Containers()[EThread];
+
+        // PRI trace variables
+        this->iThreadCount = 0; 
+        this->iNewThreadCount = 0;
+        TInt totalThreadCount = threads.Count();
+
+        for(TInt i=0;i<totalThreadCount;i++)
+            {
+            DThread* t = (DThread*)(threads)[i];
+            LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
+
+            if( (TAG(t) & PROFILER_THREAD_MARK) == 0)
+                {
+                LOGSTRING2("Marking thread %d",i);
+                // this thread's chunk has not been reported yet
+                this->threadNamesToReport[iNewThreadCount] = t;
+                iNewThreadCount++;
+                // tag the thread
+                TAG(t) |= PROFILER_THREAD_MARK;
+                LOGSTRING2("New Thread %d",i);
+                }
+            else
+                {
+                LOGSTRING3("Thread %d marked already - 0x%x",i,TAG(t));
+                }
+
+            // the thread has been tagged, add heap chunks to the list
+            this->threadsToSample[this->iThreadCount] = t;
+            this->iThreadCount++;
+            LOGSTRING2("Added thread %d to threads to sample",i);
+            }
+
+        if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
+            {
+            this->iProcessing = EStartingToProcess;
+            
+            // process the first sample
+            TInt length = this->ProcessChunks();
+            
+            if(length == 0)
+                {
+                this->iProcessing = ENothingToProcess;
+                }
+        
+            return length;
+            }
+        else
+            {
+            // there were no threads, should not take place
+            LOGTEXT("PriSamplerImpl::SampleImpl - Error, no threads"); 
+            return 0;
+            }
+	    }
+	else
+	    {
+		TInt length = this->ProcessChunks();
+		if(length == 0) 
+		    {
+			this->iProcessing = ENothingToProcess;
+		    }
+		return length;
+	    }
+    }
+
+inline TInt DPriSamplerImpl::ProcessChunks()
+    {
+	/*
+	 *
+	 *	EKA-2 implementation of PRI trace
+	 *
+	 */
+
+	if(iNewThreadCount > 0)
+	    {
+		if(this->iProcessing == EStartingToProcess)
+		    {
+			// this is the first sample, encode a code for names
+			this->iProcessing = EProcessingNames;
+			return EncodeNameCode();
+            }
+
+		// there are new thread names to report
+		iNewThreadCount--;
+		DThread* t = this->threadNamesToReport[iNewThreadCount];
+		return EncodeChunkName(*t);
+        }
+	else if(iThreadCount > 0)
+	    {
+		if(this->iProcessing == EProcessingNames || this->iProcessing == EStartingToProcess)
+		    {
+			// this is the first data sample, encode a code for data
+			this->iProcessing = EProcessingData;
+			return EncodeDataCode();
+            }
+
+		// there are no new chunks to report
+		// thus generate the real report
+		iThreadCount--;
+		DThread* t = this->threadsToSample[iThreadCount];
+		LOGSTRING2("PriSamplerImpl::ProcessChunks - starting to process thread 0x%x",t);
+		return EncodeChunkData(*t);
+        }
+	else
+	    {
+		// everything is processed
+		return 0;
+        }
+    }
+
+inline TInt DPriSamplerImpl::EncodeNameCode()
+    {
+	sample[0] = 1;
+	sample[1] = 0xbb;	// pri trace name code
+	return 2;
+    }
+
+inline TInt DPriSamplerImpl::EncodeDataCode()
+    {
+	sample[0] = 1;
+	sample[1] = 0xee;	// pri trace data code
+	return 2;
+    }
+
+
+inline TInt DPriSamplerImpl::EncodeChunkName(DThread& t)
+    {		
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+	this->sampleDescriptor.Zero();
+	
+	t.TraceAppendFullName(this->sampleDescriptor,false);
+	*size += this->sampleDescriptor.Size();
+	
+	// copy the 4 bytes from the thread id field
+	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+	*size += sizeof(TUint);
+
+	// the size is the descriptor length + the size field
+	LOGSTRING2("Name size - %d",*size);
+	return ((TInt)(*size))+1;
+    }
+
+
+inline TInt DPriSamplerImpl::EncodeChunkData(DThread& t)
+    {
+	LOGTEXT("PriSamplerImpl::EncodeChunkData - entry");
+	LOGSTRING2("PriSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t);
+		
+	// the size of the following name is in the first byte
+	TUint8* size = &sample[0];
+	*size = 0;
+	this->sampleDescriptor.Zero();
+
+	LOGTEXT("PriSamplerImpl::EncodeChunkData - cleared");
+
+    // append the thread id
+    this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+    *size += sizeof(TUint);
+    
+//    NKern::LockSystem();
+//    TInt priority(-1);
+//    if(&t && t.Open()== KErrNone)
+//        {
+//       priority = t.iDefaultPriority;
+//        }
+//    NKern::UnlockSystem();
+    
+    // append the priority of the nanokernel fast semaphore
+//    this->sampleDescriptor.Append((TUint8*)&priority,sizeof(TUint8));
+    // append the priority of the nanokernel fast semaphore
+    this->sampleDescriptor.Append((TUint8*)&(t.iNThread.iPriority),sizeof(TUint8));
+    // add space because EKA-1 implementation needs it
+    this->sampleDescriptor.Append((TUint8)0x0);
+    *size += 2*sizeof(TUint8);
+
+    LOGTEXT("PriSamplerImpl::EncodeChunkData - appended priority");
+        
+
+    LOGSTRING2("Data size - %d",*size);
+    return ((TInt)(*size))+1;	
+    }
+
+
+void DPriSamplerImpl::Reset()
+    {
+	/*
+	 *
+	 *	EKA-2 implementation of PRI trace
+	 *
+	 */
+
+	LOGTEXT("PriSamplerImpl::Reset");
+	iCountti = 50;	// sample threads 16 cycles before actual MEM and PRI sample time...
+	this->iThreadCount = 0;
+	this->iNewThreadCount = 0;
+	this->iProcessing = ENothingToProcess;
+	this->sampleDescriptor.Zero();
+
+
+	// clear all thread tags
+	DObjectCon* threads = Kern::Containers()[EThread];
+	TInt totalThreadCount = threads->Count();
+	for(TInt i=0;i<totalThreadCount;i++)
+	    {
+		DThread* t = (DThread*)(*threads)[i];
+		TAG(t) = (TAG(t) & 0xfffffffd);
+	    }
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/rom/piprofiler.iby	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PIPROFILER__
+#define __PIPROFILER__
+
+// PI Profiler Engine itself 
+file=ABI_DIR\BUILD_DIR\PIProfilerEngine.exe						sys\bin\PIProfilerEngine.exe
+file=ABI_DIR\BUILD_DIR\PIProfiler.exe							sys\bin\PIProfiler.exe
+data=ZSYSTEM\Install\PIProfiler_stub.sis						system\install\PIProfiler_stub.sis
+
+// sampler plugins
+// NOTE: Mandatory kernel driver included in piprofiler_ldd.iby
+ECOM_PLUGIN(PIProfilerGenerals.dll, PIProfilerGenerals.rsc)
+
+ECOM_PLUGIN(PIProfilerBUP.dll, PIProfilerBUP.rsc)
+file=ABI_DIR\BUILD_DIR\PIProfilerTouchEventAnim.dll				sys\bin\PIProfilerTouchEventAnim.dll
+
+// Writer plugins
+ECOM_PLUGIN(piprofilerdebugwriter.dll, piprofilerdebugwriter.rsc)
+ECOM_PLUGIN(piprofilerdiskwriter.dll, piprofilerdiskwriter.rsc)
+
+#endif //__PIPROFILER__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/rom/piprofiler_ldd.iby	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef __PIPROFILER_LDD__
+#define __PIPROFILER_LDD__
+
+// kernel side driver
+device[VARID]=KERNEL_DIR\BUILD_DIR\PIProfilerGeneralsSampler.ldd				sys\bin\PIProfilerGeneralsSampler.ldd
+
+#endif //__PIPROFILER_LDD__
--- a/stif/Parser/src/StifParser.cpp	Tue May 11 17:39:09 2010 +0300
+++ b/stif/Parser/src/StifParser.cpp	Tue May 25 14:22:58 2010 +0300
@@ -845,7 +845,7 @@
 //
 //    Method: HandleSpecialMarks
 //
-//    Description: Handles special marks.( '\/\/', '\/\*' and '*/\/' ). This
+//    Description: Handles special marks.( '\/' and '\*' ). This
 //         		   is used when ECStyleComments comment type is used.
 //
 //    Parameters: TPtr& aBuf: inout: section to parsed
@@ -862,68 +862,28 @@
     {
     TLex lex( aBuf );
     TInt firstPos( 0 );
-    TInt secondPos( 0 );
-
-    //        // => \/\/ => //
-    //        /* => \/\* => /*
-    //        */ => \*\/ => */
-  
+    
+    //        Replace \/ with /
+    //        Replace \* with *
+    
     do
         {
+        //RDebug::Print( _L("Print : %S"), &aBuf );
         firstPos = lex.Offset();
         TChar get = lex.Get();
         // Check is '\'
         if( get == '\\' ) 
             {
-            // Peek next character( '/' )
-            if( lex.Peek() == '/' )
+            firstPos = (lex.Offset()-1);
+            // Peek next character( '/' or '*' )
+            if( lex.Peek() == '/' || lex.Peek() == '*')
                 {
-                lex.Inc();
-                secondPos = lex.Offset();
-                // Peek next character( '\' )
-                if( lex.Peek() == '\\' )
-                    {
-                    lex.Inc();
-                    // Peek next character( '/' )
-                    if( lex.Peek() == '/' )
-                        {
-                        // Delete mark '\/\/' and replace this with '//'
-                        aBuf.Delete( secondPos, 1 );
-                        aBuf.Delete( firstPos, 1 );
-                        lex = aBuf;
-                        }
-                    // Peek next character( '/' )
-                    else if( lex.Peek() == '*' )
-                        {
-						// Delete mark '\/\*' and replace this with '/*'                        
-                        aBuf.Delete( secondPos, 1 );
-                        aBuf.Delete( firstPos, 1 );
-                        lex = aBuf;
-                        }
-                    }
-                }
-            // Peek next character( '/' )
-            else if( lex.Peek() == '*' )
-                {
-                lex.Inc();
-                secondPos = lex.Offset();
-                // Peek next character( '\' )
-                if( lex.Peek() == '\\' )
-                    {
-                    lex.Inc();
-                    // Peek next character( '/' )
-                    if( lex.Peek() == '/' )
-                        {
-                        // Delete mark '\*\/' and replace this with '*\'
-                        aBuf.Delete( secondPos, 1 );
-                        aBuf.Delete( firstPos, 1 );
-                        lex = aBuf;
-                        }
-                    }
+                aBuf.Delete (firstPos,1);
+                lex = aBuf;
                 }
             }
+           
         firstPos = 0;
-        secondPos = 0;
         } while ( !lex.Eos() );
 
     }
--- a/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp	Tue May 11 17:39:09 2010 +0300
+++ b/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp	Tue May 25 14:22:58 2010 +0300
@@ -27,7 +27,6 @@
 SECUREID        0x102073DD
 EPOCALLOWDLLDATA
 
-
 TARGET          StifKernelTestClassBase.dll
 TARGETTYPE      kdll
 UID             0x1000008D 0x101FB3E3
@@ -43,9 +42,4 @@
 
 SOURCE          StifKernelTestClassBase.cpp
 
-LIBRARY         ekern.lib
-
-
-
 LANG            SC
-
--- a/stif/group/ReleaseNote.txt	Tue May 11 17:39:09 2010 +0300
+++ b/stif/group/ReleaseNote.txt	Tue May 25 14:22:58 2010 +0300
@@ -1,5 +1,5 @@
 ========================================================================
-RELEASE NOTE FOR STIF - STIF_201016 (7.3.31)
+RELEASE NOTE FOR STIF - STIF_201018 (7.3.32)
 SUPPORTING SERIES 60 3.0 ->
 ========================================================================
 
--- a/stif/inc/version.h	Tue May 11 17:39:09 2010 +0300
+++ b/stif/inc/version.h	Tue May 25 14:22:58 2010 +0300
@@ -20,9 +20,9 @@
 
 #define STIF_MAJOR_VERSION 7
 #define STIF_MINOR_VERSION 3
-#define STIF_BUILD_VERSION 31
+#define STIF_BUILD_VERSION 32
 
-#define STIF_REL_DATE "19th Apr 2010"
+#define STIF_REL_DATE "04th May 2010"
 
 #define TO_UNICODE(text) _L(text) 
 
Binary file stif/sis/Stif_31.sis has changed