Catchup to latest Symbian^4 GCC_SURGE
authorWilliam Roberts <williamr@symbian.org>
Thu, 22 Jul 2010 16:50:07 +0100
branchGCC_SURGE
changeset 35 1ea875759131
parent 29 b58b1294947a (current diff)
parent 34 7259cf1302ad (diff)
Catchup to latest Symbian^4
memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp
memspy/Driver/User/Include/RBuildQueryableHeap.h
memspy/Driver/User/Source/RBuildQueryableHeap.cpp
memspy/Engine/eabi/MemSpyEngineu.def
memspy/MemSpyServer/Include/MemSpyServer.h
memspy/MemSpyServer/Include/MemSpyServerSession.h
memspy/MemSpyServer/Source/MemSpyServer.cpp
memspy/MemSpyServer/Source/MemSpyServerSession.cpp
osrndtools_info/osrndtools_metadata/osrndtools_metadata.mrp
package_definition.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/bwins/atoolcleaneru.def	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,3 @@
+EXPORTS
+	_Z18GetCallBackAddressv @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/group/analyzetoolcleaner.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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>
+#include <e32svr.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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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_4
+
+
+#endif  // __SYMBIAN_VERSION_HRH
--- a/group/bld.inf	Mon Jun 21 22:45:06 2010 +0100
+++ b/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -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/HtiFramework/src/HtiDispatcher.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/HtiFramework/src/HtiDispatcher.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -48,6 +48,7 @@
     EHtiHideConsole    = 0x09,
     EHtiInstanceId     = 0x0A,
     EHtiDebugPrint     = 0x0B,
+    EHtiRestartServices= 0x0C,
     EHtiError          = 0xFF
     };
 
@@ -70,6 +71,8 @@
 _LIT( KHtiWatchDogMatchPattern, "HtiWatchDog*" );
 _LIT( KHtiDeviceRebootExeOS,    "HtiDeviceRebootOS.exe" );
 _LIT( KHtiDeviceRebootExeUI,    "HtiDeviceRebootUI.exe" );
+_LIT( KHtiRestartExeName,       "HtiRestart.exe");
+
 _LIT( KParamNormalRfs, "rfsnormal" );
 _LIT( KParamDeepRfs,   "rfsdeep" );
 
@@ -124,7 +127,7 @@
     iHtiInstanceId( 0 ),
     iShowErrorDialogs( aShowErrorDialogs ),
     iReconnectDelay(aReconnectDelay),
-    iRebootReason(0)
+    iRebootReason(-1)
     {
     HTI_LOG_FORMAT( "MaxQueueMemorySize %d", iMaxQueueMemorySize );
     iQueueSizeLowThresold = ( iMaxQueueMemorySize / 2 ) / 2;
@@ -869,13 +872,14 @@
                         }
                     else if(aMessage.Length() == 1)
                         {
-                        iRebootReason = 0;
+                        iRebootReason = -1;
                         }
                     else
                         {
                         User::LeaveIfError(DispatchOutgoingErrorMessage( KErrArgument,
                                       KErrDescrInvalidParameter,
                                       KHtiSystemServiceUid ) );
+                        break;
                         }
                     ShutdownAndRebootDeviceL();
                     }
@@ -894,6 +898,43 @@
                     }
                     break;
 
+                case EHtiRestartServices:
+                    {
+                    HTI_LOG_TEXT("RESTARTSERVISE");
+                    if(aMessage.Length() != 1 && aMessage.Length() != 5)
+                        {
+                        User::LeaveIfError(DispatchOutgoingErrorMessage( KErrArgument,
+                                                    KErrDescrInvalidParameter,
+                                                    KHtiSystemServiceUid ) );
+                        break;
+                        }
+                    
+                    //stop all requests
+                    //cancel just incoming request
+                    //after all outgoing messages sent system will go down
+                    iListener->Cancel();
+
+                    // kill the watchdog, so HTI stays stopped
+                    KillHtiWatchDogL();
+                    
+                    TUint milliseconds = 0;
+                    if(aMessage.Length() == 5)
+                        {
+                        milliseconds = aMessage[1] + ( aMessage[2] << 8 )
+                                + ( aMessage[3] << 16 )
+                                + ( aMessage[4] << 24 );
+                        }
+                    
+                    TBuf<20> buf;
+                    buf.Format(_L("%d"), milliseconds * 1000);
+                    
+                    RProcess htiProcess;
+                    User::LeaveIfError( htiProcess.Create(
+                            KHtiRestartExeName, buf ) );
+                    htiProcess.Resume();
+                    htiProcess.Close();
+                    break;
+                    }
                 case EHtiReset:
                     {
                     HTI_LOG_TEXT( "RESET" );
@@ -1039,7 +1080,7 @@
     TInt err = KErrNone;
     RProcess rebootProcess;
     // First try the UI layer rebooter
-    if(iRebootReason == 0)
+    if(iRebootReason == -1)
         {
         err = rebootProcess.Create( KHtiDeviceRebootExeUI, KNullDesC );
         }
--- a/hti/HtiFramework/src/HtiFramework.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/HtiFramework/src/HtiFramework.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -56,7 +56,7 @@
 const static TInt KHtiDefaultPriority = 3;
 const static TInt KHtiWatchDogEnabledDefault = 0;
 const static TInt KHtiConsoleEnabledDefault = 0;
-const static TInt KHtiAutoStartEnabledDefault = 1;
+const static TInt KHtiAutoStartEnabledDefault = 0;
 const static TInt KHtiShowErrorDialogsDefault = 1;
 const static TInt KHtiReconnectDelay = 0;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiRestart/group/HtiRestart.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,40 @@
+/*
+* 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:  Build description file for HtiRestart
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+TARGET		  HtiRestart.exe
+TARGETTYPE	  exe
+
+UID             0x1000008d 0x200315B3
+
+VENDORID        0x101FB657
+
+CAPABILITY      ALL -TCB
+
+SOURCEPATH      ../src
+SOURCE		  HtiRestart.cpp
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY         euser.lib
+LIBRARY         flogger.lib
+
+SMPSAFE
+
+// End of File
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiRestart/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,32 @@
+/*
+* 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:  Build information file for HtiRestart
+*
+*/
+
+
+PRJ_PLATFORMS
+
+DEFAULT
+
+PRJ_EXPORTS
+
+PRJ_TESTEXPORTS
+
+PRJ_MMPFILES
+HtiRestart.mmp
+
+PRJ_TESTMMPFILES
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiRestart/src/HtiRestart.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -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:  HtiWatchDog implementation.
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32base.h>
+
+#ifdef __ENABLE_LOGGING__
+
+#include <flogger.h>
+_LIT( KLogFolder, "hti" );
+_LIT( KLogFile,   "htirestart.txt" );
+
+#define HTI_LOG_TEXT(a1) {_LIT(temp, a1); RFileLogger::Write(KLogFolder, KLogFile, EFileLoggingModeAppend, temp);}
+#define HTI_LOG_DES(a1) {RFileLogger::Write(KLogFolder, KLogFile, EFileLoggingModeAppend, a1);}
+#define HTI_LOG_FORMAT(a1,a2) {_LIT(temp, a1); RFileLogger::WriteFormat(KLogFolder, KLogFile, EFileLoggingModeAppend, temp, (a2));}
+
+#else   // !__ENABLE_LOGGING__
+
+#define HTI_LOG_TEXT(a1)
+#define HTI_LOG_DES(a1)
+#define HTI_LOG_FORMAT(a1,a2)
+
+#endif // __ENABLE_LOGGING__
+
+// CONSTANTS
+_LIT( KHtiFrameworkExeName,    "HtiFramework.exe" );
+_LIT( KHtiMainThreadName,      "HtiMain" );
+_LIT( KHtiRestartName,        "HtiRestart" );
+_LIT( KHtiAdminStartParameter, "admin" );
+
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ LOCAL FUNCTIONS ===============================
+
+LOCAL_C void StartHtiProcessL()
+    {
+    RProcess htiProcess;
+    User::LeaveIfError( htiProcess.Create(
+            KHtiFrameworkExeName, KHtiAdminStartParameter ) );
+    htiProcess.Resume();
+    htiProcess.Close();
+    }
+
+
+LOCAL_C TInt StartL()
+    {
+    HTI_LOG_TEXT( "HtiRestart starting..." );
+    TFullName threadName;
+    TFullName matchPattern;
+    matchPattern.Append(_L( "*" ));
+    matchPattern.Append(KHtiMainThreadName);
+    matchPattern.Append(_L( "*" ));
+
+    // Use thread finder to find the HTI main thread
+    TFindThread threadFinder;
+    threadFinder.Find(matchPattern);
+    HTI_LOG_TEXT( "Trying to find HTI main thread" );
+    TInt err = threadFinder.Next(threadName);
+
+    if (err == KErrNone)
+        {
+        HTI_LOG_TEXT( "HTI main thread found, opening it" );
+        RThread thread;
+        err = thread.Open(threadName);
+        if (err)
+            {
+            HTI_LOG_FORMAT( "Could not open HTI main thread, err: %d", err );
+            User::Panic(_L( "HTI open err" ), err);
+            }
+
+        // Logon to HTI main thread and wait for its death
+        HTI_LOG_TEXT( "HTI main thread opened, waiting for its death" );
+        TRequestStatus status;
+        thread.Logon(status);
+        User::WaitForRequest(status);
+        thread.Close();
+
+        HTI_LOG_TEXT( "HTI died");
+        }
+
+    TBuf<0x20> cmd;
+    User::CommandLine(cmd);
+
+    TLex lex(cmd);
+    TInt microseconds = 0;
+    lex.Val(microseconds);
+    HTI_LOG_FORMAT("After %d milliseconds...", microseconds);
+    User::After(microseconds);
+
+    // try to restart HTI
+    HTI_LOG_TEXT( "Trying to restart it" );
+    TRAP( err, StartHtiProcessL() );
+    if (err)
+        {
+        HTI_LOG_FORMAT( "Could not restart HTI, err: %d", err );
+        User::Panic(_L( "HTI start err" ), err);
+        }
+
+    HTI_LOG_TEXT( "HtiRestart shutting down" );
+    return KErrNone;
+    }
+
+GLDEF_C TInt E32Main()
+    {
+    __UHEAP_MARK;
+
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    CActiveScheduler *scheduler = new(ELeave) CActiveScheduler;
+    CActiveScheduler::Install( scheduler );
+
+    User::RenameThread( KHtiRestartName );
+
+    TRAPD( err, StartL() );
+
+    delete scheduler;
+    delete cleanup;
+
+   __UHEAP_MARKEND;
+
+    return err;
+    }
+
+
+// End of File
--- a/hti/HtiServicePlugins/HtiFtpServicePlugin/inc/HtiFtpServicePlugin.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/HtiServicePlugins/HtiFtpServicePlugin/inc/HtiFtpServicePlugin.h	Thu Jul 22 16:50:07 2010 +0100
@@ -28,37 +28,41 @@
 // CONSTANTS
 enum TFtpCommand
     {
-    EFtpSTOR         = 0x02,
-    EFtpSTOR_u       = 0x03,
-    EFtpRETR         = 0x04,
-    EFtpRETR_u       = 0x05,
-    EFtpLIST         = 0x06,
-    EFtpLIST_u       = 0x07,
-    EFtpMKD          = 0x08,
-    EFtpMKD_u        = 0x09,
-    EFtpRMD          = 0x0A,
-    EFtpRMD_u        = 0x0B,
-    EFtpDELE         = 0x0C,
-    EFtpDELE_u       = 0x0D,
-    EFtpCANCEL       = 0x0E,
-    EFtpFILESIZE     = 0x0F,
-    EFtpLISTDIR      = 0x10,
-    EFtpLISTDIR_u    = 0x11,
-    EFtpLISTSIZES    = 0x12,
-    EFtpLISTSIZES_u  = 0x13,
-    EFtpLISTDRIVES   = 0x14,
-    EFtpLISTDRIVES_u = 0x15,
-    EFtpRENAME       = 0x16,
-    EFtpRENAME_u     = 0x17,
-    EFtpCOPY         = 0x18,
-    EFtpCOPY_u       = 0x19,
-    EFtpMOVE         = 0x1A,
-    EFtpMOVE_u       = 0x1B,
-    EFtpSETFORCE     = 0x20,
-    EFtpCHECKSUM     = 0x30,
-    EFtpCHECKSUM_u   = 0x31,
-    EFtpFORMAT       = 0x40,
-    EFtpOK           = 0xF0,
+    EFtpSTOR                = 0x02,
+    EFtpSTOR_u              = 0x03,
+    EFtpRETR                = 0x04,
+    EFtpRETR_u              = 0x05,
+    EFtpLIST                = 0x06,
+    EFtpLIST_u              = 0x07,
+    EFtpMKD                 = 0x08,
+    EFtpMKD_u               = 0x09,
+    EFtpRMD                 = 0x0A,
+    EFtpRMD_u               = 0x0B,
+    EFtpDELE                = 0x0C,
+    EFtpDELE_u              = 0x0D,
+    EFtpCANCEL              = 0x0E,
+    EFtpFILESIZE            = 0x0F,
+    EFtpLISTDIR             = 0x10,
+    EFtpLISTDIR_u           = 0x11,
+    EFtpLISTSIZES           = 0x12,
+    EFtpLISTSIZES_u         = 0x13,
+    EFtpLISTDRIVES          = 0x14,
+    EFtpLISTDRIVES_u        = 0x15,
+    EFtpRENAME              = 0x16,
+    EFtpRENAME_u            = 0x17,
+    EFtpCOPY                = 0x18,
+    EFtpCOPY_u              = 0x19,
+    EFtpMOVE                = 0x1A,
+    EFtpMOVE_u              = 0x1B,
+    EFtpSETFORCE            = 0x20,
+    EFtpCHECKSUM            = 0x30,
+    EFtpCHECKSUM_u          = 0x31,
+    EFtpListDetail          = 0x32,
+    EFtpListDetail_u        = 0x33,
+    EFtpListDirDetail       = 0x34,
+    EFtpListDirDetail_u     = 0x35,
+    EFtpFORMAT              = 0x40,
+    EFtpOK                  = 0xF0,
     };
 
 enum TAlgorithm
@@ -283,6 +287,14 @@
     * @param aSizes if ETrue filesizes are included in the response
     */
     void HandleListL( TBool aUnicodText, TUint aReadingAtt, TBool aSizes );
+    
+    /**
+    * Handle LIST FILES DETAIL command
+    *
+    * @param aUnicodText if ETrue then response in unicode
+    * @param aReadingAtt specifies what entries to read from a dir
+    */
+    void HandleListDetailL( TBool aUnicodText, TUint aReadingAtt);
 
     /**
     * Extracts and validate file name to iFileName
--- a/hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -370,6 +370,17 @@
                     }
                 }
                 break;
+            case EFtpListDetail:
+            case EFtpListDetail_u:
+                {
+                if ( GetDirectoryL( aMessage.Mid( 1 ),
+                                   unicode ) )
+                    {
+                    HandleListDetailL( unicode,
+                        KEntryAttHidden| KEntryAttSystem|KEntryAttNormal);
+                    }
+                }
+                break;
             case EFtpLISTDIR:
             case EFtpLISTDIR_u:
                 {
@@ -383,6 +394,18 @@
                     }
                 }
                 break;
+            case EFtpListDirDetail:
+            case EFtpListDirDetail_u:
+                {
+                if ( GetDirectoryL( aMessage.Mid( 1 ),
+                                   unicode ) )
+                    {
+                    HandleListDetailL( unicode,
+                            KEntryAttMatchExclusive|KEntryAttHidden|
+                            KEntryAttSystem|KEntryAttDir);
+                    }
+                }
+                break;
             case EFtpMKD:
             case EFtpMKD_u:
                 {
@@ -682,15 +705,33 @@
     TInt newNameLength = aMessage[newNamePos];
     GetFileNameL( aMessage.Mid( newNamePos, newNameLength + 1 ), aUnicode );
 
+    TInt msglen = aMessage.Length();
+    TInt recurse = 1;
+    if(msglen>originalLenngth+newNameLength+3)        
+        {
+        recurse = aMessage[newNamePos+1+newNameLength];
+        }
+    
+    TInt err=0;
     if ( IsFileTcb( origName ) || IsFileTcb( iFileName ) )
         {
         HandleTcbCopyL( origName, iFileName );
         }
     else{
         iHandlerAO = new ( ELeave ) CFtpHandlerAO( this );
-        TInt err = iFileMan->Copy( origName, iFileName,
+        
+        if (recurse)
+            {
+            err = iFileMan->Copy( origName, iFileName,
                 ( CFileMan::EOverWrite | CFileMan::ERecurse ),
                 iHandlerAO->iStatus );
+            }
+        else
+            {
+            err = iFileMan->Copy( origName, iFileName,
+                ( CFileMan::EOverWrite ),
+                iHandlerAO->iStatus );
+            }
 
         if ( err == KErrNone)
             {
@@ -972,6 +1013,82 @@
     HTI_LOG_FUNC_OUT("HandleListL");
     }
 
+void CHtiFtpServicePlugin::HandleListDetailL( TBool aUnicodText, TUint aReadingAtt)
+    {
+    HTI_LOG_FUNC_IN("HandleListDetailL");
+    CDir* dir;
+    TInt err = iFs.GetDir( iFileName, aReadingAtt, ESortNone, dir );
+    if ( err != KErrNone )
+        {
+        User::LeaveIfError( SendErrorMsg( err, KErrDescrFailedGetDir ) );
+        return;
+        }
+
+    CleanupStack::PushL( dir );
+    //build list
+    delete iSendBuffer;
+    iSendBuffer = NULL;
+    TInt bufferLen = dir->Count()*KMaxFileName;
+    if ( aUnicodText )
+        {
+        bufferLen *= 2;
+        }
+    // 1 bytes for name length, 4 bytes for file size, 
+    // 6 bytes for date time, 3 bytes for attributes(hide, readonly and system)
+    bufferLen += (1 + 4 + 6 + 3) * dir->Count();
+
+    iSendBuffer = HBufC8::NewL( bufferLen );
+    TInt dirNameLen = 0;
+    for ( TInt i = 0; i < dir->Count(); ++i)
+        {
+        dirNameLen = (*dir)[i].iName.Length();
+        iSendBuffer->Des().Append( dirNameLen );
+        if ( aUnicodText )
+            {
+            iSendBuffer->Des().Append( (TUint8*)((*dir)[i].iName.Ptr()),
+                                       dirNameLen*2 );
+            }
+        else
+            {
+            iSendBuffer->Des().Append( (*dir)[i].iName );
+            }
+        TInt year = (*dir)[i].iModified.DateTime().Year();
+        iSendBuffer->Des().Append((TUint8*)(&year), 2 );
+        iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Month()+1);
+        iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Day()+1);
+        iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Hour());
+        iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Minute());
+        iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Second());
+        iSendBuffer->Des().Append( (*dir)[i].IsHidden());
+        iSendBuffer->Des().Append( (*dir)[i].IsReadOnly());
+        iSendBuffer->Des().Append( (*dir)[i].IsSystem());
+        if((*dir)[i].IsDir() == EFalse)
+            {
+            TInt size = (*dir)[i].iSize;
+            iSendBuffer->Des().Append( (TUint8*)(&size), 4 );
+            }
+        }
+
+    err = iDispatcher->DispatchOutgoingMessage(iSendBuffer,
+                        KFtpServiceUid,
+                        EFalse,
+                        EHtiPriorityControl);
+
+    if (  err != KErrNone )
+        {
+        //wait for a memory
+        iState = EListBusy;
+        iDispatcher->AddMemoryObserver( this );
+        }
+    else
+        {
+        iSendBuffer = NULL;
+        }
+
+    CleanupStack::PopAndDestroy();//dir
+    HTI_LOG_FUNC_OUT("HandleListDetailL");
+    }
+
 void CHtiFtpServicePlugin::HandleDataMessageL( const TDesC8& aMessage )
     {
     switch ( iState )
--- a/hti/group/bld.inf	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -53,5 +53,7 @@
 // Hti Watchdog
 #include "../HtiWatchDog/group/bld.inf"
 
+// Hti Restart
+#include "../HtiRestart/group/bld.inf"
 
 // End of File
--- a/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h	Thu Jul 22 16:50:07 2010 +0100
@@ -113,6 +113,6 @@
     TUid iDtor_ID_Key;
     };
 
-#include <HTICommPluginInterface.inl>
+#include <HtiCommPluginInterface.inl>
 
 #endif
--- a/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h	Thu Jul 22 16:50:07 2010 +0100
@@ -110,6 +110,6 @@
     TUid iDtor_ID_Key;
     };
 
-#include <HTIServicePluginInterface.inl>
+#include <HtiServicePluginInterface.inl>
 
 #endif
--- a/hti/hti_plat/hti_api/inc/HtiVersion.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/hti_plat/hti_api/inc/HtiVersion.h	Thu Jul 22 16:50:07 2010 +0100
@@ -25,13 +25,13 @@
 // CONSTANTS
 
 const TUint8 KHtiVersionMajor = 2;
-const TUint8 KHtiVersionMinor = 21;
+const TUint8 KHtiVersionMinor = 25;
 const TUint8 KHtiVersionBuild = 0;
 
 const TUint16 KHtiVersionYear  = 2010;
-const TUint8  KHtiVersionMonth = 4;
-const TUint8  KHtiVersionWeek  = 15;
-const TUint8  KHtiVersionDay   = 16;
+const TUint8  KHtiVersionMonth = 6;
+const TUint8  KHtiVersionWeek  = 23;
+const TUint8  KHtiVersionDay   = 11;
 
 //  MACROS
 
--- a/hti/rom/htios.iby	Mon Jun 21 22:45:06 2010 +0100
+++ b/hti/rom/htios.iby	Thu Jul 22 16:50:07 2010 +0100
@@ -57,6 +57,9 @@
  // HTI Watchdog
 file=ABI_DIR\BUILD_DIR\HtiWatchDog.exe              SHARED_LIB_DIR\HtiWatchDog.exe
 
+ // HTI Restart
+file=ABI_DIR\BUILD_DIR\HtiRestart.exe               SHARED_LIB_DIR\HtiRestart.exe
+
 
 #endif // __HTIOS_IBY__
 
--- a/memspy/CommandLine/Include/MemSpyCommandLine.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/CommandLine/Include/MemSpyCommandLine.h	Thu Jul 22 16:50:07 2010 +0100
@@ -22,6 +22,9 @@
 #include <e32base.h>
 #include <f32file.h>
 #include <badesca.h>
+#include <e32cons.h>
+
+#include "MemSpyCommands.h"
 
 #ifdef _DEBUG
 #   define TRACE( x ) x
@@ -36,21 +39,28 @@
 class RFs;
 class CCommandLineArguments;
 class RMemSpyEngineClientInterface;
+class CConsoleBase;
+class RMemSpySession;
 
-class CMemSpyCommandLine : public CBase
+class CMemSpyCommandLine :  public CActive
     {
 public:
-    static CMemSpyCommandLine* NewLC();
+    //static CMemSpyCommandLine* NewLC();
+	static CMemSpyCommandLine* NewLC( CConsoleBase& aConsole );
     ~CMemSpyCommandLine();
 
 private:
-    CMemSpyCommandLine();
+    //CMemSpyCommandLine();
+    CMemSpyCommandLine( CConsoleBase& aConsole );
     void ConstructL();
 
 public: // API
-    void PerformBatchL( const TDesC& aFileName );
+    //void PerformBatchL( const TDesC& aFileName ); 	//support of the batch files removed 
     void PerformOpL( const CCommandLineArguments& aCommandLine );
     void PerformSingleOpL( const TDesC& aCommand, const CDesCArray& aParameters );
+    //
+    //AO request method
+    void WaitForInput();
 
 private: // Internal methods
     void ConnectToMemSpyL();
@@ -60,10 +70,26 @@
     TInt FindBatchFile( TDes &aFileName );
     TInt FindFile( TDes &aFileName, const TDesC &aDirPath );
 
+private: // Console write methods
+    void RedrawInputPrompt();
+    void RedrawStatusMessage();
+    void RedrawStatusMessage( const TDesC& aMessage );
+    void ProcessCommandBufferL();
+    void RunL(); // from CActive
+    TInt RunError( TInt aError );
+    void DoCancel();
+    
 private: // Data members
     RFs iFsSession;
     RMemSpyEngineClientInterface* iMemSpy;
+    RMemSpySession* iMemSpySession;
     TBool iIsBatch; // For avoiding recursion
+    
+private: // Data members - console - write status messages
+    CConsoleBase& iConsole;
+    TPoint iCommandPromptPos;
+    TPoint iStatusMessagePos;
+    TBuf<KMemSpyMaxInputBufferLength> iCommandBuffer;
     };
 
 
--- a/memspy/CommandLine/Include/MemSpyCommands.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/CommandLine/Include/MemSpyCommands.h	Thu Jul 22 16:50:07 2010 +0100
@@ -18,39 +18,77 @@
 #ifndef MEMSPYCOMMANDS_H
 #define MEMSPYCOMMANDS_H
 
+// Literal constants
+_LIT( KMemSpyCLINewLine, "\r\n" );
+_LIT( KMemSpyCLIName, "MemSpy CommandLineInterpreter" );
+_LIT( KMemSpyCLIInputPrompt, " > %S" );
+_LIT( KMemSpyCLIWildcardCharacter, "*" );
 
-// Literal constants
-_LIT( KMemSpyCmdHeapDump, "CmdHeap_Dump" );
-_LIT( KMemSpyCmdHeapDumpKernel, "CmdHeap_Dump_Kernel" );
-_LIT( KMemSpyCmdHeapCompact, "CmdHeap_Compact" );
-_LIT( KMemSpyCmdSWMTForceUpdate, "CmdSWMT_ForceUpdate" );
-_LIT( KMemSpyCmdSWMTReset, "CmdSWMT_Reset" );
-_LIT( KMemSpyCmdOpenFile, "CmdOpenFile" );
-_LIT( KMemSpyCmdContainer, "CmdContainer" );
-_LIT( KMemSpyCmdBitmapsSave, "CmdBitmaps_Save" );
-_LIT( KMemSpyCmdRamDisableAknIconCache, "CmdRAM_DisableAknIconCache" );
-_LIT( KMemSpyCmdOutputToFile, "CmdOutput_ToFile" );
-_LIT( KMemSpyCmdOutputToTrace, "CmdOutput_ToTrace" );
+// Numerical constants
+const TInt KMemSpyMaxDisplayLengthThreadName = 48;
+const TInt KMemSpyMaxDisplayLengthSizeText = 14;
+const TInt KMemSpyMaxInputBufferLength = 200;
+
+// Key constants (S60)
+const TInt KMemSpyUiS60KeyCodeButtonOk = 2000;
+const TInt KMemSpyUiS60KeyCodeButtonCancel = 2001;
+const TInt KMemSpyUiS60KeyCodeRockerEnter = 63557;
 
+// Status messages
+_LIT( KOutputChangeMessage, "Change output mode opetarion in progress" );
+_LIT( KHeapDumpMessage, "Heap dump opetarion in progress" );
+_LIT( KSWMTMessage, "System Wide Memory Tracking opetarion in progress" );
 
-_LIT( KMemSpyCmdUiSendToBackground, "CmdUI_Background" );
-_LIT( KMemSpyCmdUiBringToForeground, "CmdUI_Foreground" );
+// Help text
+_LIT( KHelpMessage, "=== MemSpy CommandLineInterpreter Help ===\r\n" );
+_LIT( KHelpOutputCommand, "Change output mode to trace: 'memspy output trace'\r\n" );
+_LIT( KHelpOutputToFileCommand, "Change output mode to trace: 'memspy output file'\r\n" );
+_LIT( KHelpHeapDumpCommand, "Heap dump: 'memspy heapdup <all | kernel | user heap filter >'\r\n" );
+_LIT( KHelpSwmtCommand, "SWMT: 'memspy swmt <starttimer <value in seconds> | stop timer | dumpnow > <categories>'\r\n" );
+_LIT( KHelpKillServerCommand, "Kill server: 'memspy killserver'\r\n" );
+_LIT( KHelpCommand, "Press 'c' to continue" );
+
+//new commands
 
-_LIT( KMemSpyCmdUiExit, "CmdUI_Exit" );
+//HELP
+_LIT( KMemSpyCmdHelp1, "-?" );
+_LIT( KMemSpyCmdHelp2, "-h" );
+_LIT( KMemSpyCmdHelp3, "-help" );
+_LIT( KMemSpyCmdHelp4, "--help" );
+
+//OUTPUT
+_LIT( KMemSpyCmdOutput, "output" );
+_LIT( KMemSpyCmdOutputParameterTrace, "trace" );
+_LIT( KMemSpyCmdOutputParameterFile, "file" );
+//<directory> //parameter to be parsed
+
+//HEAP DUMP
+_LIT( KMemSpyCmdHeapDump, "heapdump" );
+_LIT( KMemSpyCmdHeapDumpParameterAll, "all" ); //default
+_LIT( KMemSpyCmdHeapDumpParameterKernel, "kernel" ); //kernel heap dump
 
-_LIT( KMemSpyCmdSWMTTypeHeap,                    "HEAP" );
-_LIT( KMemSpyCmdSWMTTypeChunk,                   "CHNK" );
-_LIT( KMemSpyCmdSWMTTypeCode,                    "CODE" );
-_LIT( KMemSpyCmdSWMTTypeStack,                   "STAK" );
-_LIT( KMemSpyCmdSWMTTypeGlobalData,              "GLOD" );
-_LIT( KMemSpyCmdSWMTTypeRamDrive,                "RAMD" );
-_LIT( KMemSpyCmdSWMTTypeOpenFile,                "FILE" );
-_LIT( KMemSpyCmdSWMTTypeDiskSpace,               "DISK" );
-_LIT( KMemSpyCmdSWMTTypeHandleGeneric,           "HGEN" );
-_LIT( KMemSpyCmdSWMTTypeFbserv,                  "FABS" );
-_LIT( KMemSpyCmdSWMTTypeFileServerCache,         "F32C" );
-_LIT( KMemSpyCmdSWMTTypeSystemMemory,            "SYSM" );
-_LIT( KMemSpyCmdSWMTTypeWindowGroup,             "WNDG" );
-_LIT( KMemSpyCmdSWMTTypeHeapFilter,              "HEAPFilter:" );
+//SWMT
+_LIT( KMemSpyCmdSwmt, "swmt" );
+_LIT( KMemSpyCmdSwmtParameterStarttimer, "starttimer" ); //<value in seconds> optionaly
+_LIT( KMemSpyCmdSwmtParameterStoptimer, "stoptimer" );
+_LIT( KMemSpyCmdSwmtParameterDumpnow, "dumpnow" );
+
+//KILL SERVER
+_LIT( KMemSpyCmdKillServer, "killserver"); //kills the server in case of it is running
 
+//SWMT CATEGORIES (TYPES)
+_LIT( KMemSpyCmdSWMTTypeHeap,                    "heap" );
+_LIT( KMemSpyCmdSWMTTypeChunk,                   "chnk" );
+_LIT( KMemSpyCmdSWMTTypeCode,                    "code" );
+_LIT( KMemSpyCmdSWMTTypeStack,                   "stak" );
+_LIT( KMemSpyCmdSWMTTypeGlobalData,              "glob" );
+_LIT( KMemSpyCmdSWMTTypeRamDrive,                "ramd" );
+_LIT( KMemSpyCmdSWMTTypeOpenFile,                "file" );
+_LIT( KMemSpyCmdSWMTTypeDiskSpace,               "disk" );
+_LIT( KMemSpyCmdSWMTTypeHandleGeneric,           "hgen" );
+_LIT( KMemSpyCmdSWMTTypeFbserv,                  "fabs" );
+_LIT( KMemSpyCmdSWMTTypeFileServerCache,         "f32c" );
+_LIT( KMemSpyCmdSWMTTypeSystemMemory,            "sysm" );
+_LIT( KMemSpyCmdSWMTTypeWindowGroup,             "wndg" );
+_LIT( KMemSpyCmdSWMTTypeAll,					 "all"	); //default value, dumps all categories expect heap dumps	
 #endif
--- a/memspy/CommandLine/Source/MemSpyCommandLine.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/CommandLine/Source/MemSpyCommandLine.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -21,148 +21,52 @@
 #include <bacline.h>
 #include <bautils.h>
 #include <memspyengineclientinterface.h>
+#include <memspysession.h>
 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
 
 // User includes
 #include "MemSpyCommands.h"
 
-
+/*
 CMemSpyCommandLine::CMemSpyCommandLine()
-    {
+    {	
     }
+*/
 
+CMemSpyCommandLine::CMemSpyCommandLine( CConsoleBase& aConsole )
+	: CActive( EPriorityHigh ), iConsole( aConsole )
+    {	
+	CActiveScheduler::Add( this );
+    }
 
 CMemSpyCommandLine::~CMemSpyCommandLine()
     {
-    if ( iMemSpy )
+	Cancel();
+	
+    if ( iMemSpySession )
         {
-        iMemSpy->Close();
+        iMemSpySession->Close();
         }
-    delete iMemSpy;
+    delete iMemSpySession;
     iFsSession.Close();
     }
 
 
 void CMemSpyCommandLine::ConstructL()
     {
-    User::LeaveIfError( iFsSession.Connect() );
-    iMemSpy = new(ELeave) RMemSpyEngineClientInterface();
-    ConnectToMemSpyL();
+    User::LeaveIfError( iFsSession.Connect() );   
+    iMemSpySession = new(ELeave) RMemSpySession();
+    ConnectToMemSpyL();                    
     }
 
-
-CMemSpyCommandLine* CMemSpyCommandLine::NewLC()
+CMemSpyCommandLine* CMemSpyCommandLine::NewLC( CConsoleBase& aConsole )
     {
-    CMemSpyCommandLine* self = new(ELeave) CMemSpyCommandLine();
+    CMemSpyCommandLine* self = new(ELeave) CMemSpyCommandLine( aConsole );
     CleanupStack::PushL( self );
     self->ConstructL();
     return self;
     }
 
-
-void CMemSpyCommandLine::PerformBatchL( const TDesC& aFileName )
-    {
-    TInt err = KErrNone;
-    RFile file;
-    err = file.Open( iFsSession, aFileName, EFileRead );
-    TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformBatchL() - START - this: 0x%08x, openErr: %d, fileName: %S"), this, err, &aFileName ) );
-    User::LeaveIfError( err );
-
-    CleanupClosePushL( file );
-    CDesCArray* lines = ReadLinesL( file );
-    CleanupStack::PopAndDestroy( &file );
-    CleanupStack::PushL( lines );
-    
-    const TInt count = lines->Count();
-    TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got %d lines", count ) );
-    iIsBatch = ETrue;
-    for( TInt i=0; i<count; i++ )
-        {
-        const TPtrC pLine( (*lines)[ i ] );
-        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - processing line[%03d] \"%S\""), i, &pLine ) );
-    
-        // Must be at least 3 chars big, i.e. '[' and <command> and then ']'
-        if  ( pLine.Length() <= 2 || pLine[ 0 ] != '[' )
-            {
-            TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - ignoring line: \"%S\""), &pLine ) );
-            }
-        else if  ( pLine[0] == '[' )
-            {
-            // Try to find end of command...
-            const TInt posOfClosingArgChar = pLine.Locate( ']' );
-            if  ( posOfClosingArgChar >= 2 )
-                {
-                // Get command
-                const TPtrC pCommand( pLine.Mid( 1, posOfClosingArgChar - 1 ) );
-                TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got command: %S"), &pCommand ) );
-
-                // Next, try to get any args
-                CDesCArrayFlat* args = new(ELeave) CDesCArrayFlat( 2 );
-                CleanupStack::PushL( args );
-
-                // There must be a mandatory space between closing ] and start of args...
-                // E.g.:
-                //
-                //  [CMD] ARG
-                //
-                const TInt remainderLength = pLine.Length() - posOfClosingArgChar;
-                if  ( remainderLength > 1 )
-                    {
-                    const TPtrC remainder( pLine.Mid( posOfClosingArgChar + 1 ) );
-                    TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got remainder: %S"), &pLine ) );
-
-                    // Extract arguments separated by tabs or space characters
-                    // and store in arguments array
-                    HBufC* argText = HBufC::NewLC( pLine.Length() + 1 );
-                    TPtr pArgText( argText->Des() );
-                    for( TInt j=0; j<remainder.Length(); j++ )
-                        {
-                        const TChar c( remainder[ j ] );
-                        //
-                        if  ( c == '\t' || c == ' ' )
-                            {
-                            pArgText.Trim();
-                            if  ( pArgText.Length() )
-                                {
-                                TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - arg[%02d] %S"), args->Count(), &pArgText ) );
-                                args->AppendL( pArgText );
-                                pArgText.Zero();
-                                }
-                            }
-                        else
-                            {
-                            pArgText.Append( c );
-                            }
-                        }
-
-                    // Save leftovers...
-                    pArgText.Trim();
-                    if  ( pArgText.Length() )
-                        {
-                        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - arg[%02d] %S"), args->Count(), &pArgText ) );
-                        args->AppendL( pArgText );
-                        }
-
-                    CleanupStack::PopAndDestroy( argText );
-                    }
-
-                // Now we can perform the operation!
-                PerformSingleOpL( pCommand, *args );
-
-                CleanupStack::PopAndDestroy( args );
-                }
-            }
-
-        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - processing line: \"%S\""), &pLine ) );
-        }
-
-    iIsBatch = EFalse;
-    
-    CleanupStack::PopAndDestroy( lines );
-    TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformBatchL() - END - this: 0x%08x, fileName: %S"), this, &aFileName ) );
-    }
-
-
 void CMemSpyCommandLine::PerformOpL( const CCommandLineArguments& aCommandLine )
     {
     const TInt count = aCommandLine.Count();
@@ -218,125 +122,187 @@
     batchFile.Append( aCommand );
     
     TInt err = KErrNotSupported;
-    if  ( aCommand.CompareF( KMemSpyCmdSWMTForceUpdate ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - SWMT_ForceUpdate", this ) );
-        if ( paramCount > 0 )
-            {
-            TInt categories( 0 );
-            TName threadNameFilter;
-            TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter ) );            
-            if ( !err )
-                {
-                err = iMemSpy->SystemWideMemoryTrackerCategoriesSet( categories );
-                if ( !err && threadNameFilter.Length() > 0 )
-                    {
-                    err = iMemSpy->SystemWideMemoryTrackerThreadFilterSet( threadNameFilter );
-                    }
-                }
-            }
-        if ( !err )
-            {
-            err = iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate );
-            }
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdSWMTReset ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - SWMT_Reset", this ) );
-        err = iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingReset );
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdHeapDumpKernel ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_DumpKernel", this ) );
-        err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData, KMemSpyClientServerThreadIdKernel );
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdHeapCompact ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Compact", this ) );
-        err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapInfoCompact );
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdContainer ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Container", this ) );
-        err = iMemSpy->PerformOperation( EMemSpyClientServerOpEnumerateKernelContainerAll );
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdBitmapsSave ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Bitmaps_Save", this ) );
-        err = iMemSpy->SaveAllBitmaps();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdRamDisableAknIconCache ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Ram_DisableAknIconCache", this ) );
-        err = iMemSpy->DisableAknIconCache();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdOutputToFile ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output_ToFile", this ) );
-        err = iMemSpy->SwitchOutputModeFile();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdOutputToTrace ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output_ToTrace", this ) );
-        err = iMemSpy->SwitchOutputModeTrace();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdUiSendToBackground ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Background", this ) );
-        err = iMemSpy->SendToBackground();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdUiBringToForeground ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Foreground", this ) );
-        err = iMemSpy->BringToForeground();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdUiExit ) == 0 )
-        {
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Exit", this ) );
-        err = iMemSpy->Exit();
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdHeapDump ) == 0 )
-        {
-        if  ( paramCount == 0 )
-            {
-            // Dump heap data for all threads
-            TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (all threads)", this ) );
-            err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData );
-            }
-        else if ( paramCount >= 1 )
-            {
-            // Dump heap data for named thread
-            const TPtrC pThreadName( aParameters[ 0 ] );
-            TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (%S)"), this, &pThreadName ) );
-            err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData, pThreadName );
-            }
-        }
-    else if ( aCommand.CompareF( KMemSpyCmdOpenFile ) == 0 )
-        {
-        if  ( paramCount == 0 )
-            {
-            // Dump heap data for all threads
-            TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - OpenFile (all threads)", this ) );
-            err = iMemSpy->PerformOperation( EMemSpyClientServerOpOpenFiles );
-            }
-        else if ( paramCount >= 1 )
-            {
-            // Dump heap data for named thread
-            const TPtrC pThreadName( aParameters[ 0 ] );
-            TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - OpenFile (%S)"), this, &pThreadName ) );
-            err = iMemSpy->PerformOperation( EMemSpyClientServerOpOpenFiles, pThreadName );
-            }
-        }
-    else if ( !iIsBatch && FindBatchFile( batchFile ) == KErrNone )
-        {
-        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Batch file: %S"), this, &batchFile ) );
-        PerformBatchL( batchFile );
-        }
-    else
-        {
-        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Unsupported Command: %S"), this, &aCommand ) );
-        }
+    TInt error = KErrNotSupported;
+    
+    // --- HELP
+    if ( aCommand.CompareF( KMemSpyCmdHelp1) == 0 || 
+    	 aCommand.CompareF( KMemSpyCmdHelp2) == 0 ||
+    	 aCommand.CompareF( KMemSpyCmdHelp3) == 0 ||
+    	 aCommand.CompareF( KMemSpyCmdHelp4) == 0 )
+    	{
+		iConsole.Write( KHelpMessage );
+		iConsole.Write( KMemSpyCLINewLine );		
+		iConsole.Write( KHelpOutputCommand );
+		iConsole.Write( KHelpOutputToFileCommand );
+		iConsole.Write( KHelpHeapDumpCommand );
+		iConsole.Write( KHelpSwmtCommand );
+		iConsole.Write( KHelpKillServerCommand );
+		iConsole.Write( KMemSpyCLINewLine );
+		iConsole.Write( KHelpCommand );
 
+	    // Show input prompt.
+	    iCommandPromptPos = iConsole.CursorPos();
+	    RedrawInputPrompt();
+	    WaitForInput();
+	    
+	    CActiveScheduler::Start();
+    	}
+    // --- OUTPUT
+    //TODO: directory option to be added
+    else if  ( aCommand.CompareF( KMemSpyCmdOutput ) == 0 )	//change output mode   
+    	{    						
+		if( paramCount >= 1 )
+			{
+			if( aParameters[0].CompareF( KMemSpyCmdOutputParameterFile ) == 0 )
+				{
+				if( paramCount == 2 )
+					{
+					TBuf<KMaxFileName> directory;
+					directory.Copy( aParameters[1] );
+					iMemSpySession->SwitchOutputToFileL( directory );
+					}
+				else
+					{
+					iMemSpySession->SwitchOutputToFileL( KNullDesC );
+					}
+				}
+			else if( aParameters[0].CompareF( KMemSpyCmdOutputParameterTrace ) == 0)
+				{
+				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output Trace", this ) );
+				iMemSpySession->SwitchOutputToTraceL();
+				}
+			}		           
+    	}    	
+    // --- HEAP DUMP    
+    else if ( aCommand.CompareF( KMemSpyCmdHeapDump) == 0 )    	
+		{		
+		RedrawStatusMessage( KHeapDumpMessage );
+		
+		if( paramCount == 0 ) // no parameter - dump all heap data + kernel heap at the end
+			{		
+		
+			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (all threads)", this ) );			
+			// Dump heap data for all threads - Thread agnostic operation					
+			iMemSpySession->OutputHeapData();
+			// Dump kernel heap data
+			iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );					
+			}
+		else if( paramCount >= 1)
+			{
+			if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterAll ) == 0 )
+				{
+				iMemSpySession->OutputHeapData();				
+				iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );				
+				}
+			else if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterKernel ) == 0 )
+				{
+				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_DumpKernel", this ) );
+				iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel );				
+				}
+			else
+				{				
+				// Dump heap data for named thread - filter
+				const TPtrC pThreadName( aParameters[0] );
+				TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (%S)"), this, &pThreadName ) );				
+				iMemSpySession->OutputThreadHeapDataL( pThreadName );
+				}
+  			}
+		}
+    
+    // --- SYSTEM WIDE MEMORY TRACKING    
+    else if( aCommand.CompareF( KMemSpyCmdSwmt ) == 0 )
+    	{    
+		RedrawStatusMessage( KSWMTMessage );
+    		
+		TInt categories( 0 );
+		TName threadNameFilter;
+		
+		if( paramCount == 0 ) //default state -> "dumpnow" command with "all" categories
+			{
+			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - dumpnow command", this ) );
+			TInt category = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
+			iMemSpySession->SetSwmtCategoriesL( category );			
+			iMemSpySession->ForceSwmtUpdateL();			
+			}
+		else if( paramCount >= 1)
+			{
+			const TPtrC pParam( aParameters[0] );
+			if( pParam.CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 ) // "starttimer" - start tracking
+				{
+				TInt result(0);
+				categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
+				iMemSpySession->SetSwmtTimerIntervalL( KMemSpySysMemTrackerConfigMinTimerPeriod );
+				
+				if( paramCount >= 2 ) // user gave some optional parameters - <categories> or <value in seconds>
+					{					
+					TLex lex( aParameters[1] );
+				    if ( lex.Val( result ) == KErrNone ) //if 2nd parameter is not number, then parse parameters
+				    	{
+						if( result >= KMemSpySysMemTrackerConfigMinTimerPeriod && result <= KMemSpySysMemTrackerConfigMaxTimerPeriod )
+							{
+							iMemSpySession->SetSwmtTimerIntervalL( result );							;
+							}											
+				    	}				   
+				    TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
+					}																				
+				
+				//if( !err )
+				//	{
+					/*
+					_LIT( KPressS, "Press 's' to stop the timer " );
+					iConsole.Write( KPressS );
+					
+					iCommandPromptPos = iConsole.CursorPos();					
+					RedrawInputPrompt();					
+					WaitForInput();
+					*/
+					    
+					iMemSpySession->StartSwmtTimerL();
+					
+					//CActiveScheduler::Start();									
+				//	}	
+				}
+			else if( pParam.CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 ) // "stoptime" - stop tracking
+				{
+				iMemSpySession->StopSwmtTimerL();
+				}
+			else if( pParam.CompareF( KMemSpyCmdSwmtParameterDumpnow ) == 0 ) // "dumpnow" - runs one tracking cycle (CmdSWMT_ForceUpdate before)
+				{
+				categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
+				if( paramCount >= 2 ) // user gave some optional parameters - <categories>
+					{
+					TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
+					}				
+																
+				if( !err )
+					{
+					iMemSpySession->SetSwmtCategoriesL( categories );
+					iMemSpySession->ForceSwmtUpdateL();
+					}												
+				}							
+			else //no parameters ("starttimer / stoptimer / dumpnow"), just categories / thread filter
+				 //so dumpnow is used as default with category / thread specified
+				{
+				TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) );
+				if( !err )
+					{
+					iMemSpySession->SetSwmtCategoriesL( categories );
+					if( threadNameFilter.Length() > 0 )
+						{
+						iMemSpySession->SetSwmtFilter( threadNameFilter );
+						}
+					}								
+					iMemSpySession->ForceSwmtUpdateL();				
+				}
+			}
+    	}
+    // --- KILL SERVER
+    else if ( aCommand.CompareF( KMemSpyCmdKillServer ) == 0 )
+    	{    
+    	}
+    
+   // RedrawStatusMessage();   
+    
     TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - END - err: %d, this: 0x%08x, cmd: %S" ), err, this, &aCommand ) );
 
     // Calculate duration
@@ -364,7 +330,7 @@
     {
     TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - START - this: 0x%08x", this ) );
 
-    TInt err = iMemSpy->Connect();
+    TInt err = iMemSpySession->Connect();
     TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - connect #1 err: %d, this: 0x%08x", err, this ) );
 
     if  ( err == KErrNotFound )
@@ -390,47 +356,48 @@
 
     TInt err = KErrGeneral;
     RProcess proc;
-
-    // First try with s60 UI
-    err = proc.Create( KMemSpyProcessName1, KNullDesC );
-    if  ( err == KErrNone )
-        {
-        TFullName fullName;
-        proc.FullName( fullName );
-        TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create S60 UI process successfully... - this: 0x%08x, name: %S"), this, &fullName ) );
+    
+    // Try to run server first
+    err = proc.Create( KMemSpyProcessName0, KNullDesC );
+    if ( err == KErrNone )
+    	{
+		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create server process successfully... - this: 0x%08x", this ) );
 
-        TRequestStatus status;
-        proc.Rendezvous( status );
-        proc.Resume();
+		TRequestStatus status;
+		proc.Rendezvous( status );
+		proc.Resume();
+
+		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
 
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
-        User::WaitForRequest( status );
-        err = status.Int();
-        proc.Close();
+		User::WaitForRequest( status );
+		err = status.Int();
+		proc.Close();
+
+		TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
+    	}
 
-        TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
-        }
-    if  ( err != KErrNone )
-        {
-        // Try console UI
-        err = proc.Create( KMemSpyProcessName2, KNullDesC );
-        if  ( err == KErrNone )
-            {
-            TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create Console UI process successfully... - this: 0x%08x", this ) );
-
-            TRequestStatus status;
-            proc.Rendezvous( status );
-            proc.Resume();
-
-            TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
-
-            User::WaitForRequest( status );
-            err = status.Int();
-            proc.Close();
-
-            TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
-            }
-        }
+    // If server is not available, try with s60 UI
+    if ( err != KErrNone )
+    	{
+		err = proc.Create( KMemSpyProcessName1, KNullDesC );
+		if  ( err == KErrNone )
+			{
+			TFullName fullName;
+			proc.FullName( fullName );
+			TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create S60 UI process successfully... - this: 0x%08x, name: %S"), this, &fullName ) );
+	
+			TRequestStatus status;
+			proc.Rendezvous( status );
+			proc.Resume();
+	
+			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
+			User::WaitForRequest( status );
+			err = status.Int();
+			proc.Close();
+	
+			TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
+			}
+    	}
 
     TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - final error: %d, this: 0x%08x", err, this ) );
     User::LeaveIfError( err );
@@ -534,11 +501,12 @@
     // In that case other parameters are ignored.
     TLex lex( aParameters[ 0 ] );
     if ( lex.Val( result ) != KErrNone )
-        {
+        {		
         // Parameters were given in text form:
         const TInt count( aParameters.Count() );
         for ( TInt i = 0; i < count ; i++ )
             {
+			lex = aParameters[ i ]; //check if num.
             if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeHeap ) == 0 )
                 result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap |
                           TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap;
@@ -565,17 +533,31 @@
                 result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryFileServerCache;
             else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeSystemMemory ) == 0 )
                 result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategorySystemMemory;
-            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeWindowGroup ) == 0 )
-                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups;
-            else if ( aParameters[i].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
-                {
-                aFilter.Copy( aParameters[i].Right( aParameters[i].Length() -11 ) );
+            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeWindowGroup ) == 0 )            	
+                result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups;            
+            else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeAll) == 0 ) //"all" category added
+            	result = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
+            else if ( aParameters[i].CompareF( KMemSpyCmdSwmtParameterDumpnow) == 0 || 
+            		aParameters[i].CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 || 
+            		aParameters[i].CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 )
+            	{    
+				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: command parameter") );
+            	}
+            else if ( lex.Val( result ) == KErrNone )
+            	{
+				TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: number - timer period") );
+            	}
+            else// if ( aParameters[i].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
+                {				
+                aFilter.Copy( aParameters[i].Right( aParameters[i].Length() -11 ) );              
                 }
-            else
-                User::Leave( KErrNotSupported );
+          /*  else
+            	{
+                //User::Leave( KErrNotSupported );            	            
+            	}*/
             }
         }
-    else if ( aParameters.Count() > 1 && aParameters[1].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
+    else if ( aParameters.Count() > 1 )//&& aParameters[1].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 )
         {
         aFilter.Copy( aParameters[1].Right( aParameters[1].Length() -11 ) );
         }
@@ -607,3 +589,110 @@
     return err;
     }
 
+
+//CLI status messages methods
+void CMemSpyCommandLine::RedrawInputPrompt()
+    {
+    iConsole.SetCursorPosAbs( iCommandPromptPos );
+    iConsole.ClearToEndOfLine();
+    iConsole.Printf( KMemSpyCLIInputPrompt, &iCommandBuffer );
+    }
+
+
+void CMemSpyCommandLine::RedrawStatusMessage()
+    {
+    RedrawStatusMessage( KNullDesC );
+    }
+
+
+void CMemSpyCommandLine::RedrawStatusMessage( const TDesC& aMessage )
+    {
+    iConsole.SetCursorPosAbs( iStatusMessagePos );
+    iConsole.ClearToEndOfLine();
+    iConsole.Write( aMessage );
+    iConsole.Write( KMemSpyCLINewLine );
+    }
+
+void CMemSpyCommandLine::WaitForInput()
+    {
+    ASSERT( !IsActive() );
+    iConsole.Read( iStatus );
+    SetActive();
+    }
+
+void CMemSpyCommandLine::DoCancel()
+    {
+    iConsole.ReadCancel();
+    }
+
+void CMemSpyCommandLine::RunL()
+    {
+    TKeyCode key = iConsole.KeyCode();
+    //
+    if  ( key == EKeyEnter || key == KMemSpyUiS60KeyCodeButtonOk || key == KMemSpyUiS60KeyCodeRockerEnter )
+        {
+        TRAP_IGNORE( ProcessCommandBufferL() );
+        }
+    else
+        {
+        TChar character( key );
+        if  ( character.IsPrint() )
+            {
+            if  ( iCommandBuffer.Length() < iCommandBuffer.MaxLength() )
+                {
+                iCommandBuffer.Append( TChar( key ) );
+                }
+
+            RedrawInputPrompt();
+            }
+        }
+
+    WaitForInput();
+    }
+
+TInt CMemSpyCommandLine::RunError( TInt aError )
+	{	
+	return KErrNone;
+	}
+
+void CMemSpyCommandLine::ProcessCommandBufferL()
+    {
+    iCommandBuffer.Trim();
+    //
+#ifdef _DEBUG
+    RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::ProcessCommandBufferL() - cmd: [%S]"), &iCommandBuffer );
+#endif
+    //
+    TBool validCommand = EFalse;
+    if  ( iCommandBuffer.Length() == 1 )
+        {
+        // Reset if not recognised...
+        validCommand = ETrue;
+
+        const TChar cmd = iCommandBuffer[ 0 ]; 
+        switch( cmd )
+            {
+        	case 's':
+        	case 'S':
+        		{
+        		iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop );
+        		
+        		CActiveScheduler::Stop();
+        		return;
+        		}
+        	case 'c':
+        	case 'C':
+        		CActiveScheduler::Stop();
+        		return;            
+        	default:
+        		validCommand = EFalse;
+        		break;
+            }
+        }    
+    if  ( !validCommand )
+        {
+        _LIT( KInvalidEntry, "*** ERROR - Invalid Command ***" );
+        RedrawStatusMessage( KInvalidEntry );
+        RedrawInputPrompt();
+        }
+    }
--- a/memspy/CommandLine/Source/MemSpyCommandLineMain.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/CommandLine/Source/MemSpyCommandLineMain.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -25,7 +25,7 @@
 
 // User includes
 #include "MemSpyCommandLine.h"
-
+#include "MemSpyCommands.h"
 
 // ---------------------------------------------------------------------------
 // DoMainL()
@@ -38,21 +38,27 @@
     CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
     CActiveScheduler::Install( scheduler );
     CleanupStack::PushL( scheduler );
-
+    
     // Get command line 
     CCommandLineArguments* args = CCommandLineArguments::NewLC();
-
+    
+    //--
+    CConsoleBase* console = Console::NewL( KMemSpyCLIName, TSize( KConsFullScreen, KConsFullScreen ) );
+    CleanupStack::PushL( console );
+    //--
+    
     // Command line manager
-    CMemSpyCommandLine* commandLineMgr = CMemSpyCommandLine::NewLC();
+    CMemSpyCommandLine* commandLineMgr = CMemSpyCommandLine::NewLC( *console );
 
     // Play nicely with external processes
     RProcess::Rendezvous( KErrNone );
 
     // Perform op
-    commandLineMgr->PerformOpL( *args );
-
+    commandLineMgr->PerformOpL( *args );  
+        
     // Tidy up
-    CleanupStack::PopAndDestroy( 3, scheduler ); // scheduler, args, commandLineMgr
+    //CleanupStack::PopAndDestroy( 3, scheduler ); // scheduler, args, commandLineMgr
+    CleanupStack::PopAndDestroy( 4 ); // scheduler, args,  console, commandLineMgr
     }
    
 
--- a/memspy/CommandLine/group/MemSpyCommandLine.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/CommandLine/group/MemSpyCommandLine.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -25,7 +25,7 @@
 VENDORID		VID_DEFAULT
 SMPSAFE
 
-CAPABILITY			none
+CAPABILITY		WriteDeviceData
 
 SOURCEPATH      ../Source
 SOURCE          MemSpyCommandLine.cpp
@@ -37,6 +37,12 @@
 
 OS_LAYER_SYSTEMINCLUDE
 
-LIBRARY					euser.lib efsrv.lib bafl.lib 
+APP_LAYER_SYSTEMINCLUDE
+
+LIBRARY         MemSpyClient.lib
+
+LIBRARY					euser.lib 
+LIBRARY 				efsrv.lib 
+LIBRARY 				bafl.lib 
 
 
--- a/memspy/Console/Include/ConsoleMenu.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/Include/ConsoleMenu.h	Thu Jul 22 16:50:07 2010 +0100
@@ -26,22 +26,22 @@
 // Engine includes
 #include <memspy/engine/memspyengine.h>
 #include <memspy/engine/memspyengineobserver.h>
-
+#include <memspysession.h>
 // User includes
 #include "ConsoleConstants.h"
 
 // Classes referenced
 class CConsoleBase;
-
+class RMemSpySession;
 
 class CMemSpyConsoleMenu : public CActive, public MMemSpyEngineObserver
     {
 public:
-    static CMemSpyConsoleMenu* NewLC( CMemSpyEngine& aEngine, CConsoleBase& aConsole );
+    static CMemSpyConsoleMenu* NewLC( RMemSpySession& aSession, CConsoleBase& aConsole );
     ~CMemSpyConsoleMenu();
 
 private:
-    CMemSpyConsoleMenu( CMemSpyEngine& aEngine, CConsoleBase& aConsole );
+    CMemSpyConsoleMenu( RMemSpySession& aEngine, CConsoleBase& aConsole );
     void ConstructL();
 
 public: // API
@@ -74,8 +74,10 @@
     void InitiateMemSpyClientServerOperationL( TInt aOpCode );
 
 private: // Data members
-    CMemSpyEngine& iEngine;
+    RMemSpySession& iSession;
     CConsoleBase& iConsole;
+    
+    TMemSpyOutputType iOutputType;
     //
     TBuf<KMemSpyMaxInputBufferLength> iCommandBuffer;
     TPoint iCommandPromptPos;
--- a/memspy/Console/Source/ConsoleDWOperation.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/Source/ConsoleDWOperation.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -56,7 +56,7 @@
 #endif
 
     iWaiter = new(ELeave) CActiveSchedulerWait();
-    iOperation = CMemSpyDeviceWideOperations::NewL( iEngine, *this, aOperation );
+    //iOperation = CMemSpyDeviceWideOperations::NewL( iEngine, *this, aOperation );
 
 #ifdef _DEBUG
     RDebug::Printf("[MCon] CMemSpyDeviceWideOperationWaiter::ExecuteL() - starting scheduler wait..." );
--- a/memspy/Console/Source/ConsoleMain.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/Source/ConsoleMain.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -26,6 +26,7 @@
 
 // Engine includes
 #include <memspy/engine/memspyengine.h>
+#include <memspysession.h>
 
 // User includes
 #include "ConsoleMenu.h"
@@ -54,11 +55,12 @@
 	CleanupStack::PushL( console );
 
     // Engine
-    CMemSpyEngine* engine = CMemSpyEngine::NewL( fsSession );
-    CleanupStack::PushL( engine );
+    RMemSpySession session;
+    User::LeaveIfError(session.Connect());
+    CleanupClosePushL(session);
 
     // Menu & event handler AO
-    CMemSpyConsoleMenu::NewLC( *engine, *console );
+    CMemSpyConsoleMenu::NewLC( session, *console );
 
     // Play nicely with external processes
     RProcess::Rendezvous( KErrNone );
--- a/memspy/Console/Source/ConsoleMenu.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/Source/ConsoleMenu.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -39,18 +39,17 @@
 #include "ConsoleDWOperation.h"
 
 
-CMemSpyConsoleMenu::CMemSpyConsoleMenu( CMemSpyEngine& aEngine, CConsoleBase& aConsole )
-:   CActive( EPriorityHigh ), iEngine( aEngine ), iConsole( aConsole )
+CMemSpyConsoleMenu::CMemSpyConsoleMenu( RMemSpySession& aSession, CConsoleBase& aConsole )
+:   CActive( EPriorityHigh ), iSession( aSession ), iConsole( aConsole ), iOutputType(EOutputTypeDebug)
     {
     CActiveScheduler::Add( this );
-    iEngine.SetObserver( this );
+    // TODO: iEngine.SetObserver( this );
     }
 
 
 CMemSpyConsoleMenu::~CMemSpyConsoleMenu()
     {
     Cancel();
-    iEngine.SetObserver( NULL );
     }
 
 
@@ -61,9 +60,9 @@
     }
 
 
-CMemSpyConsoleMenu* CMemSpyConsoleMenu::NewLC( CMemSpyEngine& aEngine, CConsoleBase& aConsole )
+CMemSpyConsoleMenu* CMemSpyConsoleMenu::NewLC( RMemSpySession& aSession, CConsoleBase& aConsole )
     {
-    CMemSpyConsoleMenu* self = new(ELeave) CMemSpyConsoleMenu( aEngine, aConsole );
+    CMemSpyConsoleMenu* self = new(ELeave) CMemSpyConsoleMenu( aSession, aConsole );
     CleanupStack::PushL( self );
     self->ConstructL();
     return self;
@@ -76,7 +75,7 @@
    
     // First line - sink type (defaults to file)
     _LIT( KLine1, "1 or T. Toggle output mode between file or trace [%S]" );
-    if  ( iEngine.SinkType() == ESinkTypeDebug )
+    if  ( iOutputType == EOutputTypeDebug )
         {
         _LIT( KLine1Trace, "Trace" );
         iConsole.Printf( KLine1, &KLine1Trace );
@@ -204,14 +203,7 @@
 
 void CMemSpyConsoleMenu::OnCmdSinkTypeToggleL()
     {
-    if  ( iEngine.SinkType() == ESinkTypeDebug )
-        {
-        iEngine.InstallSinkL( ESinkTypeFile );
-        }
-    else
-        {
-        iEngine.InstallSinkL( ESinkTypeDebug );
-        }
+	iOutputType = iOutputType == EOutputTypeFile ? EOutputTypeDebug : EOutputTypeFile;
     }
 
 
@@ -224,7 +216,7 @@
     _LIT( KMsg, "Ouputting Kernel data..." );
     RedrawStatusMessage( KMsg );
 
-    iEngine.HelperHeap().OutputHeapDataKernelL();
+    iSession.OutputKernelHeapDataL( iOutputType );
 
     RedrawStatusMessage( KNullDesC );
     }
@@ -239,14 +231,7 @@
     _LIT( KMsg, "Ouputting Kernel Object listing..." );
     RedrawStatusMessage( KMsg );
     //
-    CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
-    CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
-    CleanupStack::PushL( model );
-    //
-    CMemSpyEngineOutputSink& sink = iEngine.Sink();
-    model->OutputL( sink );
-    //
-    CleanupStack::PopAndDestroy( model );
+    iSession.OutputKernelObjectsL( iOutputType );
 
     RedrawStatusMessage( KNullDesC );
     }
@@ -258,7 +243,7 @@
     RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingStackL() - START" );
 #endif
 
-    iEngine.HelperStack().OutputStackInfoForDeviceL();
+    iSession.OutputCompactStackInfoL( iOutputType );
     }
 
 
@@ -268,7 +253,7 @@
     RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingHeapL() - START" );
 #endif
 
-    iEngine.HelperHeap().OutputHeapInfoForDeviceL();
+    iSession.OutputCompactHeapInfoL( iOutputType );
     }
 
 
@@ -296,44 +281,34 @@
         TPtr pCmdBuf( cmdBuf->Des() );
         pCmdBuf.Copy( iCommandBuffer );
         pCmdBuf.Append( KMemSpyConsoleWildcardCharacter );
-        //
-        CMemSpyEngineObjectContainer& container = iEngine.Container();
-        const TInt count = container.Count();
-        TFullName fullThreadName;
+        
+        TInt err;
+        TProcessId procId;
+        TRAP(err, procId = iSession.GetProcessIdByNameL(pCmdBuf));
         //
-        TInt index = 0;
-#ifdef _DEBUG
-        RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procCount: %d", count );
-#endif
-
-        while( index < count )
-            {
-            CMemSpyProcess& process = container.At( index );
-            const TPtrC processName( process.Name() );
-#ifdef _DEBUG
-            RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procName: 0x%08x %S"), &process, &processName );
-#endif
-
-            //
-            if  ( processName.MatchF( pCmdBuf ) >= 0 )
-                {
-                _LIT( KProcessingRequest, "** Dumping Heap Data for thread: %S" );
-                const TInt threadCount = process.Count();
-                for( TInt i=0; i<threadCount; i++ )
+        if (err == KErrNone) 
+        	{
+        	RArray<CMemSpyApiThread*> threads;
+        	
+        	TRAP(err, iSession.GetThreadsL(procId, threads));
+        	if (err == KErrNone)
+        		{
+				_LIT( KProcessingRequest, "** Dumping Heap Data for thread: %S" );     	
+				TFullName fullThreadName;
+				
+                for( TInt i=0; i<threads.Count(); i++ )
                     {
-                    CMemSpyThread& thread = process.At( i );
+                    CMemSpyApiThread* thread = threads[i];
                     //
-                    fullThreadName = thread.FullName();
+                    fullThreadName = thread->Name();
                     iConsole.Printf( KProcessingRequest, &fullThreadName );
                     iConsole.Write( KMemSpyConsoleNewLine );
                     //
-                    TRAP_IGNORE( iEngine.HelperHeap().OutputHeapDataUserL( thread ) );
+                    TRAP_IGNORE( iSession.OutputThreadHeapDataL(iOutputType, thread->Id()) );
+                    
+                    delete thread;
                     }
-
-                break;
                 }
-            
-            ++index;
             }
 
         CleanupStack::PopAndDestroy( cmdBuf );
@@ -369,38 +344,36 @@
         TPtr pCmdBuf( cmdBuf->Des() );
         pCmdBuf.Copy( iCommandBuffer );
         pCmdBuf.Append( KMemSpyConsoleWildcardCharacter );
-        //
-        CMemSpyEngineObjectContainer& container = iEngine.Container();
-        const TInt count = container.Count();
-        TFullName fullThreadName;
-        //
-        TInt index = 0;
-        while( index < count )
-            {
-            CMemSpyProcess& process = container.At( index );
-            const TPtrC processName( process.Name() );
-            //
-            if  ( processName.MatchF( pCmdBuf ) >= 0 )
-                {
-                _LIT( KProcessingRequest, "** Dumping Heap Cell List for thread: %S" );
-                const TInt threadCount = process.Count();
-                for( TInt i=0; i<threadCount; i++ )
-                    {
-                    CMemSpyThread& thread = process.At( i );
-                    //
-                    fullThreadName = thread.FullName();
-                    iConsole.Printf( KProcessingRequest, &fullThreadName );
-                    iConsole.Write( KMemSpyConsoleNewLine );
-                    //
-                    TRAP_IGNORE( iEngine.HelperHeap().OutputCellListingUserL( thread ) );
-                    }
-
-                break;
-                }
-            
-            ++index;
-            }
-
+        
+        TInt err;
+		TProcessId procId;
+		TRAP(err, procId = iSession.GetProcessIdByNameL(pCmdBuf));
+		//
+		if (err == KErrNone) 
+			{
+			RArray<CMemSpyApiThread*> threads;
+			
+			TRAP(err, iSession.GetThreadsL(procId, threads));
+			if (err == KErrNone)
+				{
+				_LIT( KProcessingRequest, "** Dumping Heap Cell List for thread: %S" );     	
+				TFullName fullThreadName;
+				
+				for( TInt i=0; i<threads.Count(); i++ )
+					{
+					CMemSpyApiThread* thread = threads[i];
+					//
+					fullThreadName = thread->Name();
+					iConsole.Printf( KProcessingRequest, &fullThreadName );
+					iConsole.Write( KMemSpyConsoleNewLine );
+					//
+					TRAP_IGNORE( iSession.OutputThreadCellListL(iOutputType, thread->Id()) );
+					
+					delete thread;
+					}
+				}
+			}
+        
         CleanupStack::PopAndDestroy( cmdBuf );
         DrawMenuL();
         }
@@ -604,71 +577,72 @@
 
 void CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL( TInt aOpCode )
     {
-#ifdef _DEBUG
-    RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - START - aOpCode: %d, iRunningDeviceWideOperation: %d", aOpCode, iRunningDeviceWideOperation );
-#endif
-    //
-    if ( aOpCode == EMemSpyClientServerOpExit )
-        {
-        // Exit console app UI
-        CActiveScheduler::Stop();
-        }
-    else
-        {
-        CMemSpyDeviceWideOperations::TOperation op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
-        switch( aOpCode )
-            {
-        case EMemSpyClientServerOpSummaryInfo:
-            op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
-            break;
-        case EMemSpyClientServerOpSummaryInfoDetailed:
-            op = CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed;
-            break;
-        //
-        case EMemSpyClientServerOpHeapInfo:
-            op = CMemSpyDeviceWideOperations::EPerEntityHeapInfo;
-            break;
-        case EMemSpyClientServerOpHeapCellListing:
-            op = CMemSpyDeviceWideOperations::EPerEntityHeapCellListing;
-            break;
-        case EMemSpyClientServerOpHeapData:
-            op = CMemSpyDeviceWideOperations::EPerEntityHeapData;
-            break;
-        //
-        case EMemSpyClientServerOpStackInfo:
-            op = CMemSpyDeviceWideOperations::EPerEntityStackInfo;
-            break;
-        case EMemSpyClientServerOpStackDataUser:
-            op = CMemSpyDeviceWideOperations::EPerEntityStackDataUser;
-            break;
-        case EMemSpyClientServerOpStackDataKernel:
-            op = CMemSpyDeviceWideOperations::EPerEntityStackDataKernel;
-            break;
-        
-        // These are not supported by the console UI
-        default:
-        case EMemSpyClientServerOpBitmapsSave:
-        case EMemSpyClientServerOpSendToBackground:
-        case EMemSpyClientServerOpBringToForeground:
-            User::Leave( KErrNotSupported );
-            break;
-            }
-
-        if  ( iRunningDeviceWideOperation )
-            {
-            User::Leave( KErrInUse );
-            }
-        else
-            {
-            iRunningDeviceWideOperation = ETrue;
-            TRAP_IGNORE( CMemSpyDeviceWideOperationWaiter::ExecuteLD( iEngine, op ) );
-            iRunningDeviceWideOperation = EFalse;
-            }
-        }
-
-#ifdef _DEBUG
-    RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - END - aOpCode: %d", aOpCode );
-#endif
+	// TODO: ....
+//#ifdef _DEBUG
+//    RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - START - aOpCode: %d, iRunningDeviceWideOperation: %d", aOpCode, iRunningDeviceWideOperation );
+//#endif
+//    //
+//    if ( aOpCode == EMemSpyClientServerOpExit )
+//        {
+//        // Exit console app UI
+//        CActiveScheduler::Stop();
+//        }
+//    else
+//        {
+//        CMemSpyDeviceWideOperations::TOperation op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
+//        switch( aOpCode )
+//            {
+//        case EMemSpyClientServerOpSummaryInfo:
+//            op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
+//            break;
+//        case EMemSpyClientServerOpSummaryInfoDetailed:
+//            op = CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed;
+//            break;
+//        //
+//        case EMemSpyClientServerOpHeapInfo:
+//            op = CMemSpyDeviceWideOperations::EPerEntityHeapInfo;
+//            break;
+//        case EMemSpyClientServerOpHeapCellListing:
+//            op = CMemSpyDeviceWideOperations::EPerEntityHeapCellListing;
+//            break;
+//        case EMemSpyClientServerOpHeapData:
+//            op = CMemSpyDeviceWideOperations::EPerEntityHeapData;
+//            break;
+//        //
+//        case EMemSpyClientServerOpStackInfo:
+//            op = CMemSpyDeviceWideOperations::EPerEntityStackInfo;
+//            break;
+//        case EMemSpyClientServerOpStackDataUser:
+//            op = CMemSpyDeviceWideOperations::EPerEntityStackDataUser;
+//            break;
+//        case EMemSpyClientServerOpStackDataKernel:
+//            op = CMemSpyDeviceWideOperations::EPerEntityStackDataKernel;
+//            break;
+//        
+//        // These are not supported by the console UI
+//        default:
+//        case EMemSpyClientServerOpBitmapsSave:
+//        case EMemSpyClientServerOpSendToBackground:
+//        case EMemSpyClientServerOpBringToForeground:
+//            User::Leave( KErrNotSupported );
+//            break;
+//            }
+//
+//        if  ( iRunningDeviceWideOperation )
+//            {
+//            User::Leave( KErrInUse );
+//            }
+//        else
+//            {
+//            iRunningDeviceWideOperation = ETrue;
+//            TRAP_IGNORE( CMemSpyDeviceWideOperationWaiter::ExecuteLD( iEngine, op ) );
+//            iRunningDeviceWideOperation = EFalse;
+//            }
+//        }
+//
+//#ifdef _DEBUG
+//    RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - END - aOpCode: %d", aOpCode );
+//#endif
     }
 
 
--- a/memspy/Console/group/MemSpyConsole.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/group/MemSpyConsole.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -25,8 +25,8 @@
 
 #include		"../../group/MemSpyCapabilities.mmh"
 
-EPOCSTACKSIZE   0x4000
-EPOCHEAPSIZE	0x100000 0x4000000
+//EPOCSTACKSIZE   0x4000
+//EPOCHEAPSIZE	0x100000 0x4000000
 
 
 SOURCEPATH      ../Source
@@ -41,6 +41,5 @@
 LIBRARY         euser.lib
 LIBRARY         efsrv.lib 
 
-LIBRARY         memspydriverclient.lib
-LIBRARY         memspyengine.lib 
-
+LIBRARY		MemSpyClient.lib
+LIBRARY     MemSpyEngine.lib
\ No newline at end of file
--- a/memspy/Console/group/bld.inf	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Console/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -23,4 +23,4 @@
 
 
 PRJ_MMPFILES
-MemSpyConsole.mmp
+//MemSpyConsole.mmp
--- a/memspy/Driver/BWINS/memspydriverclientu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/BWINS/memspydriverclientu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -67,4 +67,5 @@
 	?WalkHeapReadCellData@RMemSpyDriverClient@@QAEHPAXAAVTDes8@@H@Z @ 66 NONAME ; int RMemSpyDriverClient::WalkHeapReadCellData(void *, class TDes8 &, int)
 	?GetCondVarSuspendedThreads@RMemSpyDriverClient@@QAEHPAXPAPAXAAH@Z @ 67 NONAME ; int RMemSpyDriverClient::GetCondVarSuspendedThreads(void *, void * *, int &)
 	?GetCondVarSuspendedThreadInfo@RMemSpyDriverClient@@QAEHPAXAAVTMemSpyDriverCondVarSuspendedThreadInfo@@@Z @ 68 NONAME ; int RMemSpyDriverClient::GetCondVarSuspendedThreadInfo(void *, class TMemSpyDriverCondVarSuspendedThreadInfo &)
+	?GetHeapInfoUser@RMemSpyDriverClient@@QAEHAAVTMemSpyHeapInfo@@IAAV?$RArray@VTMemSpyDriverFreeCell@@@@H@Z @ 69 NONAME ; int RMemSpyDriverClient::GetHeapInfoUser(class TMemSpyHeapInfo &, unsigned int, class RArray<class TMemSpyDriverFreeCell> &, int)
 
--- a/memspy/Driver/Kernel/Include/MemSpyDriverHeap.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeap.h	Thu Jul 22 16:50:07 2010 +0100
@@ -28,104 +28,39 @@
 #include "MemSpyDriverObjectsInternal.h"
 
 // Constants
+// We shouldn't be using any of these any more! -Tomsci
 const TUint KRHeapObjectSize = 0x74;
 const TUint KRAllocatorAndRHeapMemberDataOffset = 4; // 4 bytes past start of allocator address, i.e. skipping the vtable
 const TUint KRHeapMemberDataSize = KRHeapObjectSize - KRAllocatorAndRHeapMemberDataOffset;
 
 // Classes referenced
 class DMemSpyDriverOSAdaption;
-
+namespace LtkUtils
+	{
+	class RAllocatorHelper;
+	}
 
 /**
  * Essentially a mirror of RAllocator and RHeap's layout.
  */
 class RMemSpyDriverRHeapBase
 	{
-public:
-	struct SCell
-        {
-        TInt len; 
-        SCell* next;
-        };
-
-    struct SDebugCell
-        {
-        TInt len;
-        TInt nestingLevel;
-        TInt allocCount;
-        };
-
-    struct _s_align {char c; double d;};
-
-    struct SHeapCellInfo { RHeap* iHeap; TInt iTotalAlloc;	TInt iTotalAllocSize; TInt iTotalFree; TInt iLevelAlloc; SDebugCell* iStranded; };
-	
-    enum {ECellAlignment = sizeof(_s_align)-sizeof(double)};
-	enum {EFreeCellSize = sizeof(SCell)};
-	enum TDebugOp {EWalk=128};
-	enum TCellType
-		{EGoodAllocatedCell, EGoodFreeCell, EBadAllocatedCellSize, EBadAllocatedCellAddress,
-		EBadFreeCellAddress, EBadFreeCellSize};
-	
-    enum TDebugHeapId {EUser=0, EKernel=1};
-
 protected:
     RMemSpyDriverRHeapBase();
 
-public: // Inlines
-    inline TUint8* Base() const { return iBase; }
-    inline TInt Size() const { return iTop - iBase; }
-    inline TInt MaxLength() const { return iMaxLength; }
-
 public: // API
     void PrintInfo();
-    void CopyObjectDataTo( TMemSpyHeapObjectDataRHeap& aData );
+	LtkUtils::RAllocatorHelper* Helper();
+	TMemSpyHeapInfo::THeapImplementationType GetTypeFromHelper() const;
 
 public: // Virtual API
     virtual void Reset();
-    virtual void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes ) = 0;
-    virtual void DisassociateWithKernelChunk() = 0;
+	virtual void Close();
     virtual DChunk& Chunk() = 0;
     virtual const DChunk& Chunk() const = 0;
-    virtual TLinAddr ChunkKernelAddress() const = 0;
-    virtual TBool ChunkIsInitialised() const = 0;
-    virtual TUint ClientToKernelDelta() const = 0;
-    virtual void GetHeapSpecificInfo( TMemSpyHeapInfo& /*aInfo*/ ) const { }
 
-public: // Utilities
-    TBool CheckCell( TAny* aCellAddress, TInt aLength ) const;
-    static TInt AllocatedCellHeaderSize( TBool aDebugLibrary );
-    static TInt FreeCellHeaderSize();
-    static TInt CellHeaderSize( const TMemSpyDriverInternalWalkHeapParamsCell& aCell, TBool aDebugEUser );
-
-public: // From RAllocator
-	TInt iAccessCount;
-	TInt iHandleCount;
-	TInt* iHandles;
-	TUint32 iFlags;
-	TInt iCellCount;
-	TInt iTotalAllocSize;
-
-public: // From RHeap
-	TInt iMinLength;
-	TInt iMaxLength;
-	TInt iOffset;
-	TInt iGrowBy;
-	TInt iChunkHandle;
-	RFastLock iLock;
-	TUint8* iBase;
-	TUint8* iTop;
-	TInt iAlign;
-	TInt iMinCell;
-	TInt iPageSize;
-	SCell iFree;
-	TInt iNestingLevel;
-	TInt iAllocCount;
-    RAllocator::TAllocFail iFailType;
-	TInt iFailRate;
-	TBool iFailed;
-	TInt iFailAllocCount;
-	TInt iRand;
-	TAny* iTestData;
+protected:
+	LtkUtils::RAllocatorHelper* iHelper;
     };
 
 
@@ -137,17 +72,12 @@
     RMemSpyDriverRHeapReadFromCopy( DMemSpyDriverOSAdaption& aOSAdaption );
 
 public: // New API
-    TInt ReadFromUserAllocator( DThread& aThread );
+    void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes );
 
 public: // From RMemSpyDriverRHeapBase
     void Reset();
-    void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes );
-    void DisassociateWithKernelChunk();
     DChunk& Chunk();
     const DChunk& Chunk() const;
-    TLinAddr ChunkKernelAddress() const;
-    TBool ChunkIsInitialised() const;
-    TUint ClientToKernelDelta() const;
 
 protected:
     inline DMemSpyDriverOSAdaption& OSAdaption() { return iOSAdaption; }
@@ -162,7 +92,7 @@
 
     // Calculated delta between client's address space values and actual kernel
     // address of the heap chunk.
-    TUint iClientToKernelDelta;
+    //TUint iClientToKernelDelta;
     };
 
 
@@ -171,13 +101,21 @@
 
 
 
-class RMemSpyDriverRHeapUser : public RMemSpyDriverRHeapReadFromCopy
+class RMemSpyDriverRHeapUser : public RMemSpyDriverRHeapBase
 	{
 public:
     RMemSpyDriverRHeapUser( DMemSpyDriverOSAdaption& aOSAdaption );
+	TInt OpenUserHeap(DThread& aThread, TBool aEuserUdeb);
 
-public: // New API
-    TInt ReadFromUserAllocator( DThread& aThread );
+	DChunk& Chunk() { return *iChunk; }
+	const DChunk& Chunk() const { return *iChunk; }
+
+private:
+    inline DMemSpyDriverOSAdaption& OSAdaption() { return iOSAdaption; }
+
+private:
+    DMemSpyDriverOSAdaption& iOSAdaption;
+	DChunk* iChunk;
     };
 
 
@@ -191,8 +129,8 @@
     void SetKernelHeap( RHeapK& aKernelHeap );
 
 public: // From RMemSpyDriverRHeapBase
-    void DisassociateWithKernelChunk();
-    void GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const;
+    //void DisassociateWithKernelChunk();
+	void Close();
 
 private:
     RHeapK* iKernelHeap;
@@ -204,50 +142,19 @@
     {
 public:
     RMemSpyDriverRHeapKernelInPlace();
+	TInt OpenKernelHeap();
     
-public: // API
-    void FailNext();
-    void SetKernelHeap( RHeapK& aKernelHeap );
 
 public: // From RMemSpyDriverRHeapBase
-    void Reset();
-    void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes );
-    void DisassociateWithKernelChunk();
+    void Close();
+
     DChunk& Chunk();
     const DChunk& Chunk() const;
-    TLinAddr ChunkKernelAddress() const;
-    TBool ChunkIsInitialised() const;
-    TUint ClientToKernelDelta() const;
-    void GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const;
 
-private: // Internal methods
-    void CopyMembersFromKernelHeap();
-
-private: // Internal class
-
-    /**
-     * Used when opening the kernel heap
-     */
-#ifndef __SYMBIAN_KERNEL_HYBRID_HEAP__
-    class RHeapKExtended : public RHeapK
-        {
-    public:
-        inline void FailNext()
-            {
-            SetFailType( RAllocator::EFailNext );
-            SetFailRate( 1 );
-            ResetFailed();
-            ResetFailAllocCount();
-            }
-        inline void SetFailType( TAllocFail aType ) { iFailType = aType; }
-        inline void SetFailRate( TInt aRate ) { iFailRate = aRate; }
-        inline void ResetFailed() { iFailed = EFalse; }
-        inline void ResetFailAllocCount() { iFailAllocCount = 0; }
-        };
-#endif
+	// Only important member data is the base class's RAllocatorHelper
+	// We do cache the chunk though
 private:
-    RHeapK* iKernelHeap;
-    DChunk* iChunk;
+	DChunk* iChunk;
     };
 
 	
--- a/memspy/Driver/Kernel/Include/MemSpyDriverHeapStatistics.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeapStatistics.h	Thu Jul 22 16:50:07 2010 +0100
@@ -69,7 +69,8 @@
     TUint iLargestCellAddressFreePrevious;
 
     // The overhead associated with a free cell (header length)
-    TUint iFreeCellOverheadHeaderLength;
+    //TUint iFreeCellOverheadHeaderLength;
+	TUint iReserved1;
 
     // The slace space at the end of the heap
     TUint iSlackSpace;
@@ -93,7 +94,8 @@
     TLinAddr iLargestCellAddressAlloc;
    
     // The overhead associated with an allocated cell (header length)
-    TUint iAllocCellOverheadHeaderLength;
+    //TUint iAllocCellOverheadHeaderLength;
+	TUint iReserved2;
 
 public: // Common
 
--- a/memspy/Driver/Kernel/Include/MemSpyDriverHeapWalker.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeapWalker.h	Thu Jul 22 16:50:07 2010 +0100
@@ -29,32 +29,23 @@
 #include "MemSpyDriverHeap.h"
 #include "MemSpyDriverHeapStatistics.h"
 
+#include "heaputils.h"
+using namespace LtkUtils;
 
 // Heap walker observer interface - can be used to make a record of each cell
 class MMemSpyHeapWalkerObserver
     {
 public:
-    virtual TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) = 0;
+    virtual TBool HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber) = 0;
     virtual void HandleHeapWalkInit() = 0;
     };
 
 
-
-// A null observer that is used to collect basic statistics
-class TMemSpyHeapWalkerNullObserver : public MMemSpyHeapWalkerObserver
-    {
-public:
-    TBool HandleHeapCell( TInt /*aCellType*/, TAny* /*aCellAddress*/, TInt /*aLength*/, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/ ) { return ETrue; }
-    void HandleHeapWalkInit() { }
-    };
-
-
 // Heap walker - allows in-place walking of any heap
 class RMemSpyDriverHeapWalker
     {
 public:
-    RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator );
-    RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator, MMemSpyHeapWalkerObserver& aObserver );
+	RMemSpyDriverHeapWalker(RMemSpyDriverRHeapBase& aHeap, MMemSpyHeapWalkerObserver* aObserver=NULL);
 		
 public: // API
     TInt Traverse();
@@ -63,12 +54,9 @@
     inline void SetPrintDebug() { iPrintDebug = ETrue; }
     inline const TMemSpyHeapWalkStatistics& Stats() const { return iStats; }
 
-public: // Utility functions
-    static TAny* KernelAddress( TAny* aUserAddress, TUint aDelta );
-    static TAny* UserAddress( TAny* aKernelAddress, TUint aDelta );
-    static RMemSpyDriverRHeapBase::SCell* CellByUserAddress( TAny* aAddress, TUint aDelta );
-
 private: // Internal methods
+	static TBool CellCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength);
+	TBool DoCellCallback(RAllocatorHelper& aHelper, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength);
     TBool NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel = -1, TInt aAllocNumber = -1 );
     //
     void UpdateStats( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
@@ -76,14 +64,10 @@
     void FinaliseStats();
     void PrintStats();
     //
-    TAny* KernelAddress( TAny* aUserAddress ) const;
-    TAny* UserAddress( TAny* aKernelAddress ) const;
-    //
     inline TBool PrintDebug() const { return iPrintDebug; }
 
 private:
     RMemSpyDriverRHeapBase& iHeap;
-    TBool iIsDebugAllocator;
     TBool iPrintDebug;
     MMemSpyHeapWalkerObserver* iObserver;
     TMemSpyHeapWalkStatistics iStats;
--- a/memspy/Driver/Kernel/Include/MemSpyDriverInspectedProcess.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverInspectedProcess.h	Thu Jul 22 16:50:07 2010 +0100
@@ -138,6 +138,8 @@
     void ResetPendingChanges();
     void PrintChunkInfo( DChunk& aChunk ) const;
     TBool IsChunkRelevantToOurProcess( DChunk& aChunk ) const;
+	void Lock() const;
+	void Unlock() const;
 
 public: // Queue link for process manager
 	SDblQueLink iPMLink;
--- a/memspy/Driver/Kernel/Include/MemSpyDriverLog.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverLog.h	Thu Jul 22 16:50:07 2010 +0100
@@ -119,5 +119,6 @@
 #   define TRACE_CHUNK( x )
 #endif
 
+#define LOG(args...) TRACE(Kern::Printf(args))
 
 #endif
--- a/memspy/Driver/Kernel/Include/MemSpyDriverOSAdaption.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverOSAdaption.h	Thu Jul 22 16:50:07 2010 +0100
@@ -106,7 +106,7 @@
     TUint GetId( DProcess& aObject ) const;
     MemSpyObjectIx* GetHandles( DProcess& aObject ) const;
     TExitType GetExitType( DProcess& aObject ) const;
-    DThread* GetFirstThread( DProcess& aObject ) const;
+    DThread* OpenFirstThread( DProcess& aObject ) const;
     TUint32 GetSID( DProcess& aObject ) const;
     TUint GetSecurityZone( DProcess& aObject ) const;
     SSecurityInfo& GetSecurityInfo( DProcess& aObject ) const;
@@ -122,6 +122,7 @@
     TUint8* GetAddressOfOwningProcess( DProcess& aObject ) const;
     TUint8* GetAddressOfDataBssStackChunk( DProcess& aObject ) const;
     TBool IsHandleIndexValid( DProcess& aObject ) const;
+	TBool IsKernProcess(DProcess& aProcess) const;
 
 private: // Data members
     };
--- a/memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h	Thu Jul 22 16:50:07 2010 +0100
@@ -126,8 +126,8 @@
 	// common operations
     RMemSpyObjectIx();
 
-    static void Wait();
-	static void Signal();
+    //static void Wait();
+	//static void Signal();
 
     inline TInt Count()
 		{ return iCount; }
@@ -137,7 +137,7 @@
 public:
 	// uncommon operations
 	DObject* operator[](TInt aIndex);
-	TInt At(DObject* aObject);
+	TBool Find(DObject* aObject);
 
 private:
 	TRWSpinLock		iRWL;
@@ -171,11 +171,11 @@
 public:
 	DObject* At(TInt aHandle,TInt aUniqueID);
 	DObject* At(TInt aHandle);
-	TInt At(DObject* aObject);
+	TBool Find(DObject* aObject);
 	TInt Count(DObject* aObject);
 	DObject* operator[](TInt aIndex);
-	static void Wait( DMemSpyObjectIx* aObjectIndex );
-	static void Signal( DMemSpyObjectIx* aObjectIndex );
+	//static void Wait( DMemSpyObjectIx* aObjectIndex );
+	//static void Signal( DMemSpyObjectIx* aObjectIndex );
 	inline TInt Count();
 	inline TInt ActiveCount();
 
@@ -206,24 +206,24 @@
 #if MCL_ROBJECTIX_DUPLICATION
 
     #define MemSpyObjectIx                                          RMemSpyObjectIx
-    #define MemSpyObjectIx_Wait( IX )                               RMemSpyObjectIx::Wait()
-    #define MemSpyObjectIx_Signal( IX )                             RMemSpyObjectIx::Signal()
+    //#define MemSpyObjectIx_Wait( IX )                               RMemSpyObjectIx::Wait()
+    //#define MemSpyObjectIx_Signal( IX )                             RMemSpyObjectIx::Signal()
     #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD )       reinterpret_cast< MemSpyObjectIx* >( &DTHREAD.iHandles )
     #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS )     reinterpret_cast< MemSpyObjectIx* >( &DPROCESS.iHandles )
 
 #elif MCL_DOBJECTIX_DUPLICATION
 
     #define MemSpyObjectIx                                          DMemSpyObjectIx
-    #define MemSpyObjectIx_Wait( IX )                               DMemSpyObjectIx::Wait( IX )
-    #define MemSpyObjectIx_Signal( IX )                             DMemSpyObjectIx::Signal( IX )
+    //#define MemSpyObjectIx_Wait( IX )                               DMemSpyObjectIx::Wait( IX )
+    //#define MemSpyObjectIx_Signal( IX )                             DMemSpyObjectIx::Signal( IX )
     #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD )       reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
     #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS )     reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles )
 
 #else
 
     #define MemSpyObjectIx                  DObjectIx
-    #define MemSpyObjectIx_Wait( IX )       
-    #define MemSpyObjectIx_Signal( IX )     
+    //#define MemSpyObjectIx_Wait( IX )       
+    //#define MemSpyObjectIx_Signal( IX )     
     #define MemSpyObjectIx_IsValid_Thread( DTHREAD )    ( DTHREAD.iHandles != NULL )
     #define MemSpyObjectIx_IsValid_Process( DPROCESS )  ( DPROCESS.iHandles != NULL )
     #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD )       reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
@@ -231,4 +231,7 @@
 
 #endif
 
+#define MemSpyObjectIx_HandleLookupLock()							NKern::LockSystem()
+#define MemSpyObjectIx_HandleLookupUnlock()							NKern::UnlockSystem()
+
 #endif
--- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanContainerBase.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanContainerBase.h	Thu Jul 22 16:50:07 2010 +0100
@@ -42,8 +42,8 @@
 protected: // Internal methods
     static TObjectType ObjectTypeFromMemSpyContainerType( TMemSpyDriverContainerType aType );
 
-    /** Returns with System Locked */
-    DObject* CheckIfObjectIsInContainer( TMemSpyDriverContainerType aContainerType, DObject* aSearchFor, TBool aQuick = EFalse );
+	// Must be in critical section to call
+	DObject* CheckedOpen(TMemSpyDriverContainerType aContainerType, DObject* aObject, TBool aQuick=EFalse);
 
 protected: // Internal methods
     void ResetTempHandles();
--- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapBase.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapBase.h	Thu Jul 22 16:50:07 2010 +0100
@@ -61,33 +61,20 @@
 protected: // Capability checks for heap access
     TDrmMatchType IsDrmThread( DThread& aThread );
 
-private: // From MHeapWalkerObserver
+protected: // From MHeapWalkerObserver
     void HandleHeapWalkInit();
-    TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
+    TBool HandleHeapCell( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
 
 protected: // Heap utility functions
     TInt OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName = NULL );
-    TInt OpenKernelHeap( RMemSpyDriverRHeapKernelInPlace& aHeap, TDes8* aClientHeapChunkName = NULL );
     TInt OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName = NULL );
-    TInt OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName = NULL );
-    TBool GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable );
-    TBool IsDebugKernel();
-    TBool IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap );
-    TInt GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer );
+    TInt GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer);
     void PrintHeapInfo( const TMemSpyHeapInfo& aInfo );
 
-protected: // Free cells
-    void ReleaseFreeCells();
-    TInt PrepareFreeCellTransferBuffer();
-	TInt FetchFreeCells( TDes8* aBufferSink );
-    TInt CalculateFreeCellBufferSize() const;
-
 private: // Data members
-	RArray< TMemSpyDriverFreeCell > iFreeCells;
 
     // Points to stack-based object whilst walking in progress
     RMemSpyMemStreamWriter* iStackStream;
-    RMemSpyMemStreamWriter* iHeapStream;
     TInt iFreeCellCount;
 	};
 
--- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapInfo.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapInfo.h	Thu Jul 22 16:50:07 2010 +0100
@@ -53,13 +53,22 @@
 private: // Channel operation handlers
     TInt GetHeapInfoUser( TMemSpyDriverInternalHeapRequestParameters* aParams );
     TInt GetHeapInfoKernel( TMemSpyDriverInternalHeapRequestParameters* aParams, TDes8* aTransferBuffer );
-    TInt GetIsDebugKernel( TBool* aIsDebugKernel );
+    TInt GetIsDebugKernel(TAny* aIsDebugKernel);
+
+private: // From MHeapWalkerObserver
+    void HandleHeapWalkInit();
+    TBool HandleHeapCell( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
 
 private: // Internal methods
-    TUint32 CalculateFreeCellBufferSize() const;
+	void ReleaseCellList();
+    TInt PrepareCellListTransferBuffer();
+	TInt FetchCellList(TDes8* aBufferSink);
+    TInt CalculateCellListBufferSize() const;
 
 private: // Data members
     TMemSpyDriverInternalHeapRequestParameters iHeapInfoParams;
+	RArray<TMemSpyDriverCell> iCellList;
+    RMemSpyMemStreamWriter* iHeapStream;
 	};
 
 
--- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapWalk.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapWalk.h	Thu Jul 22 16:50:07 2010 +0100
@@ -61,7 +61,7 @@
     const TMemSpyDriverInternalWalkHeapParamsCell* CellInfoForSpecificAddress( TAny* aAddress ) const;
 
 private: // Heap walker callback
-    TBool WalkerHandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
+    TBool WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber );
 
 private:
     TBool iHeapWalkInitialised;
@@ -85,7 +85,7 @@
 
 public: // From MHeapWalkerObserver
     void HandleHeapWalkInit() { }
-    TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
+    TBool HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
         {
         return iChannel.WalkerHandleHeapCell( aCellType, aCellAddress, aLength, aNestingLevel, aAllocNumber );
         }
--- a/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -170,6 +170,7 @@
 TUint DMemSpyEventMonitor::HandleEvent( TKernelEvent aType, TAny* a1, TAny* /*a2*/ )
 	{ 
 	// TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE WAIT"));
+	NKern::ThreadEnterCS();
 	Kern::MutexWait(*iLock);
 	// TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST WAIT"));
 
@@ -250,6 +251,7 @@
 
 	// TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE SIGNAL "));
 	Kern::MutexSignal( *iLock );
+	NKern::ThreadLeaveCS();
 	// TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST SIGNAL "));
 
 	// Allow other handlers to see this event
--- a/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -23,129 +23,60 @@
 // User includes
 #include "MemSpyDriverOSAdaption.h"
 #include "MemSpyDriverUtils.h"
+#include "heaputils.h"
 
-// Defines
-#define __NEXT_CELL(p)				((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len))
-#define __NEXT_CELL2(p,l)			((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+l))
 
 
 RMemSpyDriverRHeapBase::RMemSpyDriverRHeapBase()
+	: iHelper(NULL)
     {
     Reset();
     }
 
+LtkUtils::RAllocatorHelper* RMemSpyDriverRHeapBase::Helper()
+	{
+	return iHelper;
+	}
+
+TMemSpyHeapInfo::THeapImplementationType RMemSpyDriverRHeapBase::GetTypeFromHelper() const
+	{
+	if (iHelper)
+		{
+		LtkUtils::RAllocatorHelper::TType type = iHelper->GetType();
+		switch (type)
+			{
+			case LtkUtils::RAllocatorHelper::ETypeRHeap:
+				return TMemSpyHeapInfo::ETypeRHeap;
+			case LtkUtils::RAllocatorHelper::ETypeRHybridHeap:
+				return TMemSpyHeapInfo::ETypeRHybridHeap;
+			case LtkUtils::RAllocatorHelper::ETypeUnknown:
+			default:
+				return TMemSpyHeapInfo::ETypeUnknown;
+			}
+		}
+	return TMemSpyHeapInfo::ETypeUnknown;
+	}
 
 void RMemSpyDriverRHeapBase::Reset()
     {
-	iAccessCount = 0;
-	iHandleCount = 0;
-	iHandles = NULL;
-	iFlags = 0;
-	iCellCount = 0;
-	iTotalAllocSize = 0;
-    
-    iMinLength = 0;
-	iMaxLength = 0;
-	iOffset = 0;
-	iGrowBy = 0;
-	iChunkHandle = 0;
-	// iLock needs no initialisation due to default ctor
-	iBase = NULL;
-	iTop = NULL;
-	iAlign = 0;
-	iMinCell = 0;
-	iPageSize = 0;
-	iFree.len = 0;
-	iFree.next = NULL;
-	iNestingLevel = 0;
-	iAllocCount = 0;
-    iFailType = RAllocator::EReset;
-	iFailRate = 0;
-	iFailed = EFalse;
-	iFailAllocCount = 0;
-	iRand = 0;
-	iTestData = NULL;
-    }
-
-
-TBool RMemSpyDriverRHeapBase::CheckCell( TAny* aCellAddress, TInt aLength ) const
-	{
-	const TLinAddr m = TLinAddr(iAlign - 1);
-    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - cell: 0x%08x, len: %8d, iAlign: %d, m: %d", aCellAddress, aLength, iAlign, m) );
-
-    TBool isValid = ETrue;
-    //
-    if ( isValid && (aLength & m) )
-        {
-    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length is odd: %d, iAlign: %d, m: %d", aLength, iAlign, m) );
-        isValid = EFalse;
-        }
-    if ( isValid && aLength < iMinCell )
-        {
-    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length: %d, is less than min cell size (%d)", aLength, iMinCell) );
-        isValid = EFalse;
-        }
-    if ( isValid && (TUint8*)aCellAddress < iBase )
-        {
-    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - cell address: 0x%08x, is before start address: 0x%08x", (TUint8*) aCellAddress, iBase) );
-        isValid = EFalse;
-        }
-
-    if  ( isValid )
-        {
-        const TUint8* nextCell = (TUint8*)__NEXT_CELL2(aCellAddress, aLength);
-        if  ( nextCell > iTop )
-            {
-        	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - nextCell: 0x%08x is after the top of the heap: 0x%08x", nextCell, iTop) );
-            isValid = EFalse;
-            }
-        }
-    //
-    return isValid;
+	Close();
 	}
 
-
-TInt RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( TBool aDebugLibrary )
-    {
-    // Allocated cells are only 4 bytes in UREL, but 12 bytes in UDEB.
-    TInt size = sizeof(SCell*);
-    //
-    if  ( aDebugLibrary )
-        {
-        size = sizeof(SDebugCell);
-        }
-    //
-    return size;
+void RMemSpyDriverRHeapBase::Close()
+	{
+	if (iHelper)
+		{
+	    NKern::ThreadEnterCS();
+		iHelper->Close();
+		delete iHelper;
+		iHelper = NULL;
+		NKern::ThreadLeaveCS();
+		}
     }
 
-
-TInt RMemSpyDriverRHeapBase::FreeCellHeaderSize()
-    {
-    // Free cells remain the same size in UREL and UDEB builds.
-    const TInt size = sizeof(SCell);
-    return size; 
-    }
-
-
-TInt RMemSpyDriverRHeapBase::CellHeaderSize( const TMemSpyDriverInternalWalkHeapParamsCell& aCell, TBool aDebugLibrary )
-    {
-    TInt size = 0;
-    //
-    if  ( aCell.iCellType == EMemSpyDriverGoodAllocatedCell )
-        {
-        size = AllocatedCellHeaderSize( aDebugLibrary );
-        }
-    else if ( aCell.iCellType == EMemSpyDriverGoodFreeCell ) 
-        {
-        size = FreeCellHeaderSize();
-        }
-    //
-    return size;
-    }
-
-
 void RMemSpyDriverRHeapBase::PrintInfo()
     {
+	/* TOMSCI TODO
 #if defined(TRACE_TYPE_KERNELHEAP) || defined(TRACE_TYPE_USERHEAP)
     Kern::Printf(" " );
     Kern::Printf("RMemSpyDriverRHeapBase::PrintInfo - RAllocator - iAccessCount:    0x%08x", iAccessCount );
@@ -173,70 +104,11 @@
     Kern::Printf(" " );
     Kern::Printf(" " );
 #endif
-    }
-
-
-void RMemSpyDriverRHeapBase::CopyObjectDataTo( TMemSpyHeapObjectDataRHeap& aData )
-    {
-    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - START" ) );
-
-    TUint8* sourceAddress = reinterpret_cast< TUint8* >( this );
-    sourceAddress += KRAllocatorAndRHeapMemberDataOffset;
-    memcpy( &aData, sourceAddress, KRHeapObjectSize );
-
-    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - END") );
+	*/
     }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 RMemSpyDriverRHeapReadFromCopy::RMemSpyDriverRHeapReadFromCopy( DMemSpyDriverOSAdaption& aOSAdaption )
-:   iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ), iClientToKernelDelta( 0 )
+:   iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ) /*, iClientToKernelDelta( 0 )*/
     {
     }
 
@@ -248,7 +120,7 @@
     iChunk = NULL;
     iChunkAddress = 0;
     iChunkMappingAttributes = 0;
-    iClientToKernelDelta = 0;
+    //iClientToKernelDelta = 0;
     }
 
 
@@ -263,13 +135,13 @@
     // Calculate start of real heap data (skipping over embedded RHeap object)
     // Since we must operate with kernel-side addressing into our cloned heap chunk,
     // we must use aAddress (the kernel address of the chunk) rather than aChunk->iBase
-    iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize );
+    //TOMSCI iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize );
 
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::AssociateWithKernelChunk() - END - delta between client's user-side base address (base: 0x%08x), kernel-side base address (base: 0x%08x), and kernel-side chunk (base: 0x%08x) is: 0x%08x", Base(), aChunk->iBase, aAddress, iClientToKernelDelta) );
     }
 
 
-void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk()
+/*void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk()
     {
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk ) );
 
@@ -283,7 +155,7 @@
 
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - END") );
     }
-
+*/
 
 DChunk& RMemSpyDriverRHeapReadFromCopy::Chunk()
     {
@@ -297,7 +169,7 @@
     }
 
 
-TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const
+/*TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const
     {
     return iChunkAddress;
     }
@@ -308,118 +180,49 @@
     return iChunk != NULL;
     }
 
-
 TUint RMemSpyDriverRHeapReadFromCopy::ClientToKernelDelta() const
     {
     return iClientToKernelDelta;
     }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+*/
 
 
 
 
 
 RMemSpyDriverRHeapUser::RMemSpyDriverRHeapUser( DMemSpyDriverOSAdaption& aOSAdaption )
-:   RMemSpyDriverRHeapReadFromCopy( aOSAdaption )
+	: RMemSpyDriverRHeapBase(), iOSAdaption(aOSAdaption)
     {
     }
 
 
-TInt RMemSpyDriverRHeapUser::ReadFromUserAllocator( DThread& aThread )
-    {
-    TBuf8<KRHeapMemberDataSize> memberData;
-    memberData.SetMax();
-
-    NKern::ThreadEnterCS();
-    NKern::LockSystem();
-    RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread );
-    NKern::UnlockSystem();
-  	NKern::ThreadLeaveCS();
-
-    TUint8* memberDataAddress = (TUint8*) allocator + KRAllocatorAndRHeapMemberDataOffset;
-	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - START - allocator addr: 0x%08x, therefore going to read %d bytes from address 0x%08x within client thread (0x%08x + %4d bytes)", allocator, KRHeapMemberDataSize, memberDataAddress, allocator, KRAllocatorAndRHeapMemberDataOffset ) );
-
-    const TInt error = Kern::ThreadRawRead( &aThread, memberDataAddress, (TAny*) memberData.Ptr(), KRHeapMemberDataSize );
-    TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", memberData.Ptr(), KRHeapMemberDataSize, KRHeapMemberDataSize ) );
-
-    if  ( error == KErrNone )
-        {
-        TUint8* destinationAddress = reinterpret_cast< TUint8* >( this );
-
-        // Skip over our vTable too...
-        destinationAddress += KRAllocatorAndRHeapMemberDataOffset;
-
-        // Now copy data into this object
-        TPtr8 self( destinationAddress, KRHeapMemberDataSize, KRHeapMemberDataSize );
-        self.Copy( memberData );
-
-        PrintInfo();
-        }
-    else
-        {
-        }
-
-	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - END - read error: %d", error ) );
-    return error;
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+TInt RMemSpyDriverRHeapUser::OpenUserHeap(DThread& aThread, TBool aEuserUdeb)
+	{
+	TLinAddr allocatorAddr = (TLinAddr)OSAdaption().DThread().GetAllocator(aThread);
+	NKern::ThreadEnterCS();
+	LtkUtils::RKernelSideAllocatorHelper* helper = new LtkUtils::RKernelSideAllocatorHelper;
+	if (!helper)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+	TInt err = helper->OpenUserHeap(OSAdaption().DThread().GetId(aThread), allocatorAddr, aEuserUdeb);
+	if (!err)
+		{
+		iChunk = helper->OpenUnderlyingChunk();
+		if (!iChunk) err = KErrNotFound;
+		}
+	if (err)
+		{
+		delete helper;
+		}
+	else
+		{
+		iHelper = helper;
+		}
+	NKern::ThreadLeaveCS();
+	return err;
+	}
 
 RMemSpyDriverRHeapKernelFromCopy::RMemSpyDriverRHeapKernelFromCopy( DMemSpyDriverOSAdaption& aOSAdaption )
 :   RMemSpyDriverRHeapReadFromCopy( aOSAdaption )
@@ -448,6 +251,7 @@
     }
 
 
+/*
 void RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk()
     {
     TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - START - iKernelHeap: 0x%08x", iKernelHeap ));
@@ -455,93 +259,55 @@
     RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk();
     TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - END") );
     }
-
+*/
 
-void RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const
-    {
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap ));
-    //
-    if  ( iKernelHeap )
-        {
-        const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap );
-        //
-        TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
-        TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
-        rHeapMetaData.SetVTable( *pHeap );
-        rHeapMetaData.SetClassSize( KRHeapObjectSize );
-        //
-        TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap ));
-        }
-    //
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - END") );
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+void RMemSpyDriverRHeapKernelFromCopy::Close()
+	{
+	//TOMSCI TODO close the chunk
+	}
 
 RMemSpyDriverRHeapKernelInPlace::RMemSpyDriverRHeapKernelInPlace()
-:   iKernelHeap( NULL ), iChunk( NULL )
+	: iChunk(NULL)
     {
     }
 
-
-void RMemSpyDriverRHeapKernelInPlace::SetKernelHeap( RHeapK& aKernelHeap )
-    {
-    iKernelHeap = &aKernelHeap;
-    CopyMembersFromKernelHeap();
-    }
-
+TInt RMemSpyDriverRHeapKernelInPlace::OpenKernelHeap()
+	{
+	NKern::ThreadEnterCS();
+	LtkUtils::RAllocatorHelper* helper = new LtkUtils::RAllocatorHelper;
+	if (!helper)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+	TInt err = helper->OpenKernelHeap();
+	if (!err)
+		{
+		iChunk = helper->OpenUnderlyingChunk();
+		if (!iChunk) err = KErrNotFound;
+		}
 
-void RMemSpyDriverRHeapKernelInPlace::FailNext()
-    {
-#ifndef __SYMBIAN_KERNEL_HYBRID_HEAP__
-    RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* heap = reinterpret_cast< RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* >( iKernelHeap );
-    heap->FailNext();
-#endif
-    }
+	if (err)
+		{
+		delete helper;
+		}
+	else
+		{
+		iHelper = helper;
+		}
+	NKern::ThreadLeaveCS();
+	return err;
+	}
 
-
-void RMemSpyDriverRHeapKernelInPlace::Reset()
+void RMemSpyDriverRHeapKernelInPlace::Close()
     {
-    RMemSpyDriverRHeapBase::Reset();
-	//
-    iChunk = NULL;
-    }
-
-
-void RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk( DChunk* aChunk, TLinAddr /*aAddress*/, TUint32 /*aMappingAttributes*/ )
-    {
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk() - START - aChunk: %O, aChunk base: 0x%08x", aChunk, aChunk->iBase ) );
-    iChunk = aChunk;
+	NKern::ThreadEnterCS();
+	iChunk->Close(NULL);
+	iChunk = NULL;
+	RMemSpyDriverRHeapBase::Close();
+	NKern::ThreadLeaveCS();
     }
 
-
-void RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk()
-    {
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk ));
-    iChunk = NULL;
-    iKernelHeap = NULL;
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - END") );
-    }
-
-
 DChunk& RMemSpyDriverRHeapKernelInPlace::Chunk()
     {
     return *iChunk;
@@ -553,68 +319,3 @@
     return *iChunk;
     }
 
-
-TLinAddr RMemSpyDriverRHeapKernelInPlace::ChunkKernelAddress() const
-    {
-    const TLinAddr ret = reinterpret_cast< TLinAddr >( iChunk->iBase );
-    return ret;
-    }
-
-
-TBool RMemSpyDriverRHeapKernelInPlace::ChunkIsInitialised() const
-    {
-    return iChunk != NULL;
-    }
-
-
-TUint RMemSpyDriverRHeapKernelInPlace::ClientToKernelDelta() const
-    {
-    // We're operating in kernel address space, there is no delta.
-    return 0;
-    }
-
-
-void RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap()
-    {
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - START" ) );
-
-    // Perform a copy operation in order to populate base class with a duplicate of the kernel's heap info.
-    RHeapK* kernelHeap = iKernelHeap;
-
-    // Source address
-    TUint8* sourceAddress = (TUint8*) kernelHeap + KRAllocatorAndRHeapMemberDataOffset;
-    TUint8* destinationAddress = (TUint8*) this + KRAllocatorAndRHeapMemberDataOffset;
-
-    // Copy 
-    memcpy( destinationAddress, sourceAddress, KRHeapMemberDataSize );
-
-    // And print info in debug builds for verification...
-    PrintInfo();
-
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - END" ) );
-    }
-
-
-void RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const
-    {
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap ));
-    //
-    if  ( iKernelHeap )
-        {
-        const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap );
-        //
-        TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
-        TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
-        rHeapMetaData.SetVTable( *pHeap );
-        rHeapMetaData.SetClassSize( KRHeapObjectSize );
-        //
-        TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap ));
-        }
-    //
-    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - END") );
-    }
-
-
-
-
-
--- a/memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -21,22 +21,14 @@
 #include "MemSpyDriverUtils.h"
 
 // Defines
-#define __NEXT_CELL(p)				((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len))
 #define PRINTDEBUG( a ) { if ( PrintDebug() ) a; }
 
 
-RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator )
-:   iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( NULL )
-    {
-    InitialiseStats();
-    }
-
-
-RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator, MMemSpyHeapWalkerObserver& aObserver )
-:   iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( &aObserver )
-    {
-    InitialiseStats();
-    }
+RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker(RMemSpyDriverRHeapBase& aHeap, MMemSpyHeapWalkerObserver* aObserver)
+	: iHeap(aHeap), iPrintDebug(EFalse), iObserver(aObserver)
+	{
+	InitialiseStats();
+	}
 
 
 TInt RMemSpyDriverHeapWalker::Traverse()
@@ -44,7 +36,7 @@
 // Walk the heap calling the info function.
 //
 	{
-    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START - delta: 0x%08x", iHeap.ClientToKernelDelta() ));
+    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START"));
     InitialiseStats();
     if  ( iObserver )
         {
@@ -53,135 +45,64 @@
         }
 
     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init complete" ));
-    TAny* heapBase = KernelAddress( iHeap.iBase );
-    TAny* heapTop = KernelAddress( iHeap.iTop );
-	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - kernel-side chunk address: 0x%08x, chunkBase: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", iHeap.ChunkKernelAddress(), iHeap.Chunk().iBase, heapBase, heapTop));
-
-    TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", (TUint8*) iHeap.ChunkKernelAddress(), iHeap.Chunk().iSize, iHeap.Chunk().iSize ) );
-   
-	TInt nestingLevel = 0;
-	TInt allocationNumber = 0;
-	//
-	RMemSpyDriverRHeapBase::SCell* pC = (RMemSpyDriverRHeapBase::SCell*) heapBase;		// allocated cells
-	RMemSpyDriverRHeapBase::SCell* pF = &iHeap.iFree;				            // free cells
-	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - before while loop entry - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop));
-    //
-    while( ( pF == &iHeap.iFree ) || ( pF >= heapBase && pF < heapTop ) )
-		{
-        pF = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( pF->next );				// next free cell
-	    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop));
-
-        if  ( pF )
-        	{
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell:       0x%08x", pF ));
 
-            if  ( pF >= heapBase && pF < heapTop )
-                {
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->next: 0x%08x", pF->next ));
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->len:  0x%08x", pF->len ));
-                }
-            else
-                {
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - FATAL ERROR - freeCell:  0x%08x is outside heap bounds!", pF ));
-                }
+	TInt err = iHeap.Helper()->Walk(&CellCallback, this);
+    FinaliseStats();
+    //PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop));
+	return err;
+	}
 
-            PRINTDEBUG( Kern::Printf(" "));
-            }
-		
-        if  (!pF)
-            {
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - next free cell address is NULL"));
-			pF = (RMemSpyDriverRHeapBase::SCell*) heapTop;		// to make size checking work
-            }
-		else if (  (TUint8*) pF < heapBase || (TUint8*) pF >= heapTop || (KernelAddress( pF->next ) && KernelAddress( pF->next ) <= pF ) )
-			{
-			// free cell pointer off the end or going backwards
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", pF ));
-            NotifyCell( EMemSpyDriverBadFreeCellAddress, UserAddress(pF), 0 );
-			return KErrAbort;
-			}
-		else
-			{
-			TInt l = pF->len;
-			if ( l< iHeap.iMinCell || (l & (iHeap.iAlign-1)))
-				{
-				// free cell length invalid
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", pF ));
-		        NotifyCell( EMemSpyDriverBadFreeCellSize, UserAddress(pF), l );
-			    return KErrAbort;
-				}
-			}
+TBool RMemSpyDriverHeapWalker::CellCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength)
+	{
+	return static_cast<RMemSpyDriverHeapWalker*>(aContext)->DoCellCallback(aHelper, aCellType, aCellAddress, aLength);
+	}
 
-        while ( pC != pF )				// walk allocated cells up to next free cell
-			{
-    	    if  ( pC )
-        	    {
-                // The 'next' cell field is only applicable if the cell is a 'free' cell, hence we only print the cell's
-                // address, its length, and its _calculated_ next cell (based upon address + length). Calc length is done
-                // a bit later on...
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell:       0x%08x", pC ));
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell->len:  0x%08x", pC->len ));
-                PRINTDEBUG( Kern::Printf(" "));
-                }
-            
-            TInt l = pC->len;
-			if (l<iHeap.iMinCell || (l & (iHeap.iAlign-1)))
-				{
-				// allocated cell length invalid
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellSize: 0x%08x", pC ));
-		        NotifyCell( EMemSpyDriverBadAllocatedCellSize, UserAddress(pC), l );
-			    return KErrAbort;
-				}
-
-            // ALLOCATED CELL
-            if  ( iIsDebugAllocator )
-                {
-                RMemSpyDriverRHeapBase::SDebugCell* debugCell = (RMemSpyDriverRHeapBase::SDebugCell*) pC;
-                nestingLevel = debugCell->nestingLevel;
-                allocationNumber = debugCell->allocCount;
-                }
-
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", pC ));
-	        if  ( NotifyCell( EMemSpyDriverGoodAllocatedCell, UserAddress(pC), l, nestingLevel, allocationNumber ) == EFalse )
-                {
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END1 - KErrAbort on NotifyCell..."));
-			    return KErrAbort;
-                }
-
-			RMemSpyDriverRHeapBase::SCell* pN = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL( pC );
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell next:  0x%08x", pN ));
-			if (pN > pF)
-				{
-				// cell overlaps next free cell
-                PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", pC ));
-		        NotifyCell( EMemSpyDriverBadAllocatedCellAddress, UserAddress(pC), l );
-			    return KErrAbort;
-				}
-
-            pC = pN;
-			}
-
-        PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell before exit check is: 0x%08x", pF ));
-        if  ((TUint8*) pF >= heapTop )
-            {
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell reached top of heap -> done"));
-			break;		// reached end of heap
-            }
-		
-        pC = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL(pF);	// step to next allocated cell
-
-        // FREE CELL
-        PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", pF ));
-        if  ( NotifyCell( EMemSpyDriverGoodFreeCell, UserAddress(pF), pF->len ) == EFalse )
-            {
-            PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END2 - KErrAbort on NotifyCell..."));
-			return KErrAbort;
-            }
+TBool RMemSpyDriverHeapWalker::DoCellCallback(RAllocatorHelper& aHelper, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength)
+	{
+	TAny* cellAddress = (TAny*)aCellAddress;
+	TMemSpyDriverCellType memspyCellType = (TMemSpyDriverCellType)aCellType; // We make sure these use the same values
+	switch (aCellType)
+		{
+		case RAllocatorHelper::EHeapBadFreeCellAddress:
+			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", cellAddress));
+			NotifyCell(memspyCellType, cellAddress, 0);
+			return EFalse;
+		case RAllocatorHelper::EHeapBadFreeCellSize:
+			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", cellAddress));
+			NotifyCell(memspyCellType, cellAddress, aLength);
+			return EFalse;
+		case RAllocatorHelper::EHeapBadAllocatedCellSize:
+			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellSize: 0x%08x", cellAddress));
+			NotifyCell(memspyCellType, cellAddress, aLength);
+			return EFalse;
+		case RAllocatorHelper::EHeapBadAllocatedCellAddress:
+			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", cellAddress));
+			NotifyCell(memspyCellType, cellAddress, aLength);
+			return EFalse;
+		default:
+			break;
 		}
 
-    FinaliseStats();
-    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop));
-    return KErrNone;
+	if (aCellType & RAllocatorHelper::EAllocationMask)
+		{
+		PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", cellAddress));
+		TInt nestingLevel = -1;
+		aHelper.GetCellNestingLevel(cellAddress, nestingLevel);
+		TInt allocCount = aHelper.AllocCountForCell(cellAddress);
+		if (allocCount < 0) allocCount = -1; // This is what NotifyCell expects
+		return NotifyCell(memspyCellType, cellAddress, aLength, nestingLevel, allocCount);
+		}
+	else if (aCellType & RAllocatorHelper::EFreeMask)
+		{
+		PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", cellAddress));
+		return NotifyCell(memspyCellType, cellAddress, aLength);
+		}
+	else if (aCellType & RAllocatorHelper::EBadnessMask)
+		{
+		NotifyCell(memspyCellType, cellAddress, aLength);
+		return EFalse;
+		}
+	return ETrue; // For any new types that get added
 	}
 
 
@@ -219,9 +140,7 @@
     alloc.SetLargestCellAddress( (TAny*) iStats.iLargestCellAddressAlloc );
     alloc.SetLargestCellSize( iStats.iLargestCellSizeAlloc );
 
-    // Copy common info
-    TMemSpyHeapStatisticsRHeapCommon& common = aStats.StatsCommon();
-    common.SetTotalCellCount( iStats.iNumberOfWalkedCells );
+	aStats.iCommittedFreeSpace = iHeap.Helper()->CommittedFreeSpace();
 
 	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::CopyStatsTo() - END"));
     }
@@ -233,56 +152,6 @@
     iObserver = aObserver;
     }
 
-
-TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress, TUint aDelta )
-    {
-    TAny* ret = NULL;
-    //
-    if  ( aUserAddress )
-        {
-	    TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - aUserAddress: 0x%08x", aUserAddress));
-        ret = (TUint8*) aUserAddress + aDelta;
-        }
-    //
-	TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - ret: 0x%08x", ret));
-    return ret;
-    }
-
- 
-TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress, TUint aDelta )
-    {
-    TAny* ret = NULL;
-    //
-    if  ( aKernelAddress )
-        {
-	    TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - aKernelAddress: 0x%08x", aKernelAddress));
-        ret = (TUint8*) aKernelAddress - aDelta;
-        }
-    //
-	TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - ret: 0x%08x", ret));
-    return ret;
-    }
-
-
-TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress) const
-    {
-    return KernelAddress( aUserAddress, iHeap.ClientToKernelDelta() );
-    }
-
-
-TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress ) const
-    {
-    return UserAddress( aKernelAddress, iHeap.ClientToKernelDelta() );
-    }
-
-
-RMemSpyDriverRHeapBase::SCell* RMemSpyDriverHeapWalker::CellByUserAddress( TAny* aAddress, TUint aDelta )
-    {
-    RMemSpyDriverRHeapBase::SCell* ret = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( aAddress, aDelta );
-    return ret;
-    }
-
-
 TBool RMemSpyDriverHeapWalker::NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
     {
     // Update stats first
@@ -301,32 +170,9 @@
 
 void RMemSpyDriverHeapWalker::UpdateStats( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
     {
-    switch( aCellType )
-        {
-    case EMemSpyDriverGoodAllocatedCell:
-        PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodAllocatedCell       - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ));
-        break;
-    case EMemSpyDriverGoodFreeCell:
-        PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodFreeCell            - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ));
-        break;
-    case EMemSpyDriverBadAllocatedCellSize:
-        Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellSize    - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
-        break;
-    case EMemSpyDriverBadAllocatedCellAddress:
-        Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellAddress - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
-        break;
-    case EMemSpyDriverBadFreeCellAddress:
-        Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellAddress      - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
-        break;
-    case EMemSpyDriverBadFreeCellSize:
-        Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellSize         - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
-        break;
-    default:
-        Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - UHANDLED TYPE!           - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d, type: %d", aCellAddress, aLength, aNestingLevel, aAllocNumber, aCellType );
-        break;
-        }
+    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - type: %d address: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellType, aCellAddress, aLength, aNestingLevel, aAllocNumber ));
 
-    if  ( aCellType == EMemSpyDriverGoodFreeCell )
+    if (aCellType & EMemSpyDriverFreeCellMask)
         {
         // Update checksum
         iStats.iFreeCellCRC = iStats.iFreeCellCRC ^ reinterpret_cast<TUint32>( aCellAddress );
@@ -355,7 +201,7 @@
             iStats.iFirstFreeCellAddress = (TLinAddr) aCellAddress;
             }
         }
-    else if ( aCellType == EMemSpyDriverGoodAllocatedCell )
+    else if (aCellType & EMemSpyDriverAllocatedCellMask)
         {
         // Track cell counts and length
         ++iStats.iAllocCellCount;
@@ -372,14 +218,10 @@
             iStats.iLargestCellAddressAlloc = (TLinAddr) aCellAddress;
             }
         }
-    else
-        {
-        iStats.iLastFreeCellLength = aLength;
-        }
 
     iStats.iLastCellType = aCellType;
     iStats.iLastCellAddress = (TLinAddr) aCellAddress;
-    iStats.iLastCellWasFreeCell = ( aCellType == EMemSpyDriverGoodFreeCell );
+    iStats.iLastCellWasFreeCell = (aCellType & EMemSpyDriverFreeCellMask);
     ++iStats.iNumberOfWalkedCells;
     }
 
@@ -390,7 +232,7 @@
     iStats.iNumberOfWalkedCells = 0;
     iStats.iFirstFreeCellAddress = 0;
     iStats.iFirstFreeCellLength = 0;
-    iStats.iLastCellType = EMemSpyDriverGoodAllocatedCell;
+    iStats.iLastCellType = EMemSpyDriverAllocatedCellMask;
     iStats.iLastCellWasFreeCell = EFalse;
     iStats.iLastFreeCellLength = 0;
     iStats.iTotalFreeSpace = 0;
@@ -406,10 +248,6 @@
     iStats.iLargestCellAddressFreePrevious = 0;
     iStats.iSpackSpaceCellAddress = 0;
     iStats.iLastCellAddress = 0;
-
-    // These two can be identified up front
-    iStats.iFreeCellOverheadHeaderLength = RMemSpyDriverRHeapBase::FreeCellHeaderSize();
-    iStats.iAllocCellOverheadHeaderLength = RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iIsDebugAllocator );
     }
 
 
@@ -447,4 +285,3 @@
     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressAlloc     : 0x%08x", iStats.iLargestCellAddressAlloc ) );
     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iFreeCellCRC                 : 0x%08x", iStats.iFreeCellCRC ) );
     }
-
--- a/memspy/Driver/Kernel/Source/MemSpyDriverInspectedProcess.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverInspectedProcess.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -78,6 +78,7 @@
 
 TInt DMemSpyInspectedProcess::Open( DProcess* aProcess )
     {
+	__ASSERT_CRITICAL;
     TRACE( Kern::Printf("DMemSpyInspectedProcess::Open() - START - this: 0x%08x, aProcess: 0x%08x (%O)", this, aProcess, aProcess ));
 
     TInt error = KErrNone;
@@ -128,7 +129,7 @@
 
 TInt DMemSpyInspectedProcess::NotifyOnChange( DThread* aThread, TRequestStatus* aRequestStatus, TMemSpyDriverProcessInspectionInfo* aInfo )
     {
-	Kern::MutexWait( *iLock );
+	Lock();
 
     TInt err = KErrInUse;
     const TBool notificationQueued = NotifyOnChangeQueued();
@@ -158,9 +159,7 @@
 			CompleteClientsRequest( KErrNone, &cachedChange->iInfo );
 			
 			// Discard cached entry
-            NKern::ThreadEnterCS();
 			delete cachedChange;
-            NKern::ThreadLeaveCS();
 			}
         else if ( iAmDead )
             {
@@ -174,14 +173,14 @@
 	//
     TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - END - this: 0x%08x, err: %d", this, err ) );
 
-	Kern::MutexSignal( *iLock );
+	Unlock();
     return err;
     }
 
 
 TInt DMemSpyInspectedProcess::NotifyOnChangeCancel()
     {
-	Kern::MutexWait( *iLock );
+	Lock();
     TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - START - this: 0x%08x, queued: %d, iChangeObserverThread: 0x%08x, iChangeObserverRS: 0x%08x", this, NotifyOnChangeQueued(), iChangeObserverThread, iChangeObserverRS ) );
     //
     if  ( NotifyOnChangeQueued() )
@@ -194,7 +193,7 @@
         }
 	//
     TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - END - this: 0x%08x", this ) );
-	Kern::MutexSignal( *iLock );
+	Unlock();
 
     return KErrNone;
     }
@@ -204,9 +203,9 @@
     {
     TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - START - this: 0x%08x", this ) );
     //
-	Kern::MutexWait( *iLock );
+	Lock();
     const TBool queued = ( iChangeObserverRS != NULL );
-	Kern::MutexSignal( *iLock );
+	Unlock();
     //
     TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - END - this: 0x%08x, queued: %d", this, queued ) );
     return queued;
@@ -449,10 +448,9 @@
     const TUint procId = iDevice.OSAdaption().DProcess().GetId( aProcess );
     if  ( procId == iProcessId )
         {
-	    Kern::MutexWait( *iLock );
+	    Lock();
 
         TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - START - this: 0x%08x, iProcess: 0x%08x (%O)", this, iProcess, iProcess ) );
-	    NKern::ThreadEnterCS();
 
         // Mark all tracked chunks as dirty whilst we work out
         // what is and isn't mapped into the process
@@ -476,10 +474,9 @@
             CompleteClientsRequest( KErrNone, &iInfoCurrent );
             }
 
-        NKern::ThreadLeaveCS();
         TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - END - this: 0x%08x", this ) );
 
-        Kern::MutexSignal( *iLock );
+        Unlock();
         }
     }
 
@@ -491,10 +488,9 @@
 
     if  ( pid == iProcessId )
         {
-	    Kern::MutexWait( *iLock );
+	    Lock();
 
         TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - START - this: 0x%08x", this ) );
-	    NKern::ThreadEnterCS();
 
         // We will implement a multi phased approach to the process being removed.
         //
@@ -529,10 +525,9 @@
         // Stop listening to events since we've drained everything now...
         iAmDead = ETrue;
 
-        NKern::ThreadLeaveCS();
         TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - END - this: 0x%08x", this ) );
 
-        Kern::MutexSignal( *iLock );
+        Unlock();
         }
     }
 
@@ -600,7 +595,7 @@
 
 void DMemSpyInspectedProcess::EMHandleThreadChanged( DThread& /*aThread*/ )
     {
-	Kern::MutexWait( *iLock );
+	Lock();
 
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - START - this: 0x%08x", this ) );
 
@@ -608,7 +603,6 @@
     // We must be careful to only access the members of aThread that still
     // exist as if it is being destroyed, the object may be in an intermediate
     // state.
-	NKern::ThreadEnterCS();
 
     // All we are really interested in is recalculating the stack usage
     // for the process... 
@@ -617,19 +611,17 @@
     // Always inform observer about new results.
     CompleteClientsRequest( KErrNone, &iInfoCurrent );
 
-    NKern::ThreadLeaveCS();
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - END - this: 0x%08x", this ) );
 
-    Kern::MutexSignal( *iLock );
+    Unlock();
     }
 
 
 void DMemSpyInspectedProcess::EMHandleChunkAdd( DChunk& aChunk )
     {
-	Kern::MutexWait( *iLock );
+	Lock();
 
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - START - this: 0x%08x, aChunk: 0x%08x (%O)", this, &aChunk, &aChunk ) );
-	NKern::ThreadEnterCS();
 
     // Is this chunk related to our process somehow?
     if  ( IsChunkRelevantToOurProcess( aChunk ) )
@@ -656,19 +648,17 @@
             }
         }
 
-    NKern::ThreadLeaveCS();
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - END - this: 0x%08x", this ) );
 
-    Kern::MutexSignal( *iLock );
+    Unlock();
     }
 
 
 void DMemSpyInspectedProcess::EMHandleChunkUpdated( DChunk& aChunk )
     {
-	Kern::MutexWait( *iLock );
+	Lock();
 
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - START - this: 0x%08x, aChunk: 0x%08x [S: %8d] (%O)", this, &aChunk, aChunk.Size(), &aChunk ) );
-	NKern::ThreadEnterCS();
 
     // Is this chunk mapped into our process?
     TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk );
@@ -712,19 +702,17 @@
             }
         }
 
-    NKern::ThreadLeaveCS();
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - END - this: 0x%08x", this ) );
 
-    Kern::MutexSignal( *iLock );
+    Unlock();
     }
 
 
 void DMemSpyInspectedProcess::EMHandleChunkDeleted( DChunk& aChunk )
     {
-	Kern::MutexWait( *iLock );
+	Lock();
 
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - START - this: 0x%08x", this ) );
-	NKern::ThreadEnterCS();
 
     // Is this chunk mapped into our process?
     TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk );
@@ -742,10 +730,9 @@
             }
         }
 
-    NKern::ThreadLeaveCS();
     TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - END - this: 0x%08x", this ) );
 
-    Kern::MutexSignal( *iLock );
+    Unlock();
     }
 
 
@@ -884,6 +871,7 @@
         TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) );
         if  ( firstThread != NULL )
             {
+			NKern::ThreadEnterCS();
             TInt err = firstThread->Open();
             TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread open result: %d", err ) );
 
@@ -912,6 +900,7 @@
                 TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - closing first thread..." ) );
             	Kern::SafeClose( (DObject*&) firstThread, NULL );
                 }
+			NKern::ThreadLeaveCS();
             }
         }
     //
@@ -1116,6 +1105,7 @@
 
 void DMemSpyInspectedProcess::FindChunks( DProcess& aProcess )
     {
+	__ASSERT_CRITICAL;
     TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - START - this: 0x%08x", this ) );
   
     DMemSpyDriverOSAdaptionDChunk& chunkAdaption = iDevice.OSAdaption().DChunk();
@@ -1125,9 +1115,11 @@
     if  ( processAdaption.IsHandleIndexValid( aProcess ) )
         {
 	    MemSpyObjectIx* processHandles = processAdaption.GetHandles( aProcess );
-        MemSpyObjectIx_Wait( processHandles );
+		
+		MemSpyObjectIx_HandleLookupLock();
+        const TInt count = processHandles->Count();
+		MemSpyObjectIx_HandleLookupUnlock();
 
-        const TInt count = processHandles->Count();
         TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - got: %d handles...", count ) );
 
 	    for( TInt i=0; i<count; i++ )
@@ -1135,9 +1127,11 @@
             TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - checking handle index: %2d", i ) );
 
     	    // Get a handle from the process container...
-            NKern::LockSystem();
+            MemSpyObjectIx_HandleLookupLock();
+			if (i >= processHandles->Count()) break; // Count may have changed in the meantime
     	    DObject* object = (*processHandles)[ i ];
-            NKern::UnlockSystem();
+			if (object && object->Open() != KErrNone) object = NULL;
+			MemSpyObjectIx_HandleLookupUnlock();
 
             const TObjectType objectType = ( object ? chunkAdaption.GetObjectType( *object ) : EObjectTypeAny );
             TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - object: 0x%08x, type: %2d (%O)", object, objectType, object ) );
@@ -1179,9 +1173,8 @@
                         }
                     }
                 }
+			if (object) object->Close(NULL);
     	    }
-
-        MemSpyObjectIx_Signal( processHandles );
         }
 
     TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - END - this: 0x%08x", this ) );
@@ -1235,6 +1228,17 @@
     }
 
 
+void DMemSpyInspectedProcess::Lock() const
+	{
+	NKern::ThreadEnterCS();
+	Kern::MutexWait(*iLock);
+	}
+
+void DMemSpyInspectedProcess::Unlock() const
+	{
+	Kern::MutexSignal(*iLock);
+	NKern::ThreadLeaveCS();
+	}
 
 
 
--- a/memspy/Driver/Kernel/Source/MemSpyDriverLogicalChannel.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverLogicalChannel.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -51,10 +51,10 @@
 
     NKern::ThreadEnterCS();
     SubChannelsDestroy();
-    NKern::ThreadLeaveCS();
 
     TRACE( Kern::Printf("DMemSpyDriverLogicalChannel::~DMemSpyDriverLogicalChannel() - closing client thread..."));
     Kern::SafeClose( (DObject*&) iClientThread, NULL );
+    NKern::ThreadLeaveCS();
 
     TRACE( Kern::Printf("DMemSpyDriverLogicalChannel::~DMemSpyDriverLogicalChannel() - calling device to cleanup..."));
     MemSpyDevice().Cleanup();
--- a/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -22,20 +22,10 @@
 #include <nk_plat.h>
 
 #ifdef __MARM__
-
 #include <arm.h>
-// Necessary when accessing data members by steam via offsets in order
-// to prevent potential unaligned data aborts
+#endif
 
-#ifdef __CC_ARM
-#define UNALIGNED_DATA_MEMBER __packed
-#endif /* __CC_ARM */
-
-#endif /* __MARM__ */
-
-#ifndef UNALIGNED_DATA_MEMBER
-#define UNALIGNED_DATA_MEMBER
-#endif
+// I've removed UNALIGNED_DATA_MEMBER in preference for just using memcpy to get round the potential unaligned access. -TomS
 
 // User includes
 #include "MemSpyDriverLog.h"
@@ -164,10 +154,9 @@
     {
     DThread* dThread = &aObject;
     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_ExitType;
-    UNALIGNED_DATA_MEMBER TExitType* pRet = reinterpret_cast< TExitType* >( pTarget );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - value: %d", *pRet ) );
-    return *pRet;
+	TUint8 exitType = *reinterpret_cast<TUint8*>(pTarget);
+    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: %d", &aObject, (TInt)exitType ) );
+    return (TExitType)exitType;
     }
 
 
@@ -175,10 +164,11 @@
     {
     DThread* dThread = &aObject;
     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackBase;
-    UNALIGNED_DATA_MEMBER TUint32* pRet = reinterpret_cast< TUint32* >( pTarget );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - 0x%08x: %d", *pRet ) );
-    return *pRet;
+
+	TUint32 ret;
+	memcpy(&ret, (const TAny*)pTarget, sizeof(TUint32));
+    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, ret ) );
+    return ret;
     }
 
 
@@ -186,10 +176,11 @@
     {
     DThread* dThread = &aObject;
     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackSize;
-    UNALIGNED_DATA_MEMBER TInt* pRet = reinterpret_cast< TInt* >( pTarget );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
-    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - value: %d", *pRet ) );
-    return *pRet;
+	
+	TInt ret;
+	memcpy(&ret, (const TAny*)pTarget, sizeof(TInt));
+    TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: %d", &aObject, ret ) );
+    return ret;
     }
 
 
@@ -448,9 +439,23 @@
     }
 
 
-DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const
+DThread* DMemSpyDriverOSAdaptionDProcess::OpenFirstThread( DProcess& aProcess ) const
     {
-    return aObject.FirstThread();
+	// It appears that the system lock needs to be held while manipulating the iThreadQ
+	DThread* result = NULL;
+	NKern::LockSystem();
+	// We don't use DProcess::FirstThread() as that doesn't appear to do any checking of whether the list is empty, ie if there are no threads at all
+	SDblQueLink* threadLink = aProcess.iThreadQ.First();
+	if (threadLink != NULL && threadLink != &aProcess.iThreadQ.iA)
+		{
+		result = _LOFF(threadLink,DThread,iProcessLink);
+		if (result->Open() != KErrNone)
+			{
+			result = NULL;
+			}
+		}
+	NKern::UnlockSystem();
+    return result;
     }
 
 
@@ -545,6 +550,11 @@
     return (TUint8*)aObject.iDataBssStackChunk;
     }
 
+TBool DMemSpyDriverOSAdaptionDProcess::IsKernProcess(DProcess& aProcess) const
+	{
+	// The kernel process always has pid 1
+	return GetId(aProcess) == 1;
+	}
 
 
 
@@ -566,9 +576,32 @@
     }
 
 
-TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const
+TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aChunk ) const
     {
-    return aObject.Base();
+    TUint8* base = aChunk.Base();
+	if (base == 0)
+		{
+		// Under flexible memory model, DChunk::Base() will return NULL (for non-fixed chunks anyway, and that means most of them)
+		// A more useful thing to return is the base address in the owning process
+		DProcess* proc = GetOwningProcess(aChunk);
+		NKern::ThreadEnterCS();
+		if (proc && proc->Open() == KErrNone)
+			{
+			// Probably shouldn't call ChunkUserBase for a non-user-owned chunk
+			if (!OSAdaption().DProcess().IsKernProcess(*proc))
+				{
+				DThread* firstThread = OSAdaption().DProcess().OpenFirstThread(*proc);
+				if (firstThread)
+					{
+					base = Kern::ChunkUserBase(&aChunk, firstThread);
+					firstThread->Close(NULL);
+					}
+				}
+			proc->Close(NULL);
+			}
+		NKern::ThreadLeaveCS();
+		}
+	return base; 
     }
 
 
--- a/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -55,6 +55,30 @@
 	{ Kern::Fault("DOBJECT",aPanic); }
 	
 
+TBool MemSpyObjectIx::Find(DObject* aObj)
+	{
+	//Check preconditions(debug build only)
+	__ASSERT_CRITICAL;
+	__ASSERT_NO_FAST_MUTEX;
+
+	// I don't like the implementation of At() that was here before, it wasn't safe at all without HandleMutex. So I'm replacing it with a simpler
+	// version based on operator[] that only does what we need and does it safely.
+
+	TBool found = EFalse;
+	MemSpyObjectIx_HandleLookupLock();
+	const TInt count = Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		if ((*this)[i] == aObj)
+			{
+			found = ETrue;
+			break;
+			}
+		}
+	MemSpyObjectIx_HandleLookupUnlock();
+	return found;
+	}
+
 #if MCL_ROBJECTIX_DUPLICATION
 
 #define asserta(x)	do { if (!(x)) { __crash(); } } while(0)
@@ -65,17 +89,18 @@
     }
 
 
+/*
 void RMemSpyObjectIx::Wait()
 	{
-//	Kern::MutexWait(*HandleMutex);
+	Kern::MutexWait(*HandleMutex);
 	} // RObjectIx::Wait
 
 
 void RMemSpyObjectIx::Signal()
 	{
-//	Kern::MutexSignal(*HandleMutex);
+	Kern::MutexSignal(*HandleMutex);
 	} // RObjectIx::Signal
-
+*/
 
 DObject* RMemSpyObjectIx::operator[](TInt aIndex)
 	{
@@ -89,73 +114,19 @@
 	} // RObjectIx::operator[]
 
 
-TInt RMemSpyObjectIx::At(DObject* aObj)
-	{
-	//Check preconditions(debug build only)
-	__ASSERT_CRITICAL;
-	__ASSERT_NO_FAST_MUTEX;
-	//__ASSERT_MUTEX(HandleMutex);
-
-	if (iState==ETerminated)
-		{
-		return KErrNotFound;
-		}
-
-	TInt h = KErrNotFound;
-	AcquireWriteLock();
-	iState = (TUint8)ESearching;		// enable monitoring of new handles
-	iModList.iMonitor.iObj = aObj;		// object to check for
-	iModList.iMonitor.iBoundary = 0;	// will change if aObj is added to a slot before this point
-	TInt pos = 0;
-	while (pos<iCount && iActiveCount)	// stop if index empty
-		{
-		TInt limit = pos + EMaxLockedIter;
-		if (limit>iCount)
-			{
-			limit = iCount;
-			}
-		while (pos<limit)
-			{
-			SSlot* slot = iSlots + pos;
-			if (Occupant(slot) == aObj)
-				{
-				// found it, finish
-				h = MakeHandle(pos, slot->iUsed.iAttr);
-				break;
-				}
-			pos++;
-			}
-		if (h>0)
-			{
-			break;	// found it, finish
-			}
-		iModList.iMonitor.iBoundary = pos;	// will change if aObj is added to a slot already checked
-		ReleaseWriteLock();	// let other threads in
-		AcquireWriteLock();
-		pos = iModList.iMonitor.iBoundary;	// next position to check
-		}
-	iState = (TUint8)ENormal;
-	ReleaseWriteLock();
-	return h;
-	} // RObjectIx::At
-
-
-
-
-
-
 #elif MCL_DOBJECTIX_DUPLICATION
 
-void DMemSpyObjectIx::Wait( DMemSpyObjectIx* /*aObjectIndex*/ )
+/*
+void DMemSpyObjectIx::Wait( DMemSpyObjectIx* aObjectIndex )
 	{
 //	Kern::MutexWait(*aObjectIndex->HandleMutex);
 	}
 
-void DMemSpyObjectIx::Signal( DMemSpyObjectIx* /*aObjectIndex*/ )
+void DMemSpyObjectIx::Signal( DMemSpyObjectIx* aObjectIndex )
 	{
 //	Kern::MutexSignal(*aObjectIndex->HandleMutex);
 	}
-
+*/
 
 /** Counts the number of times an object appears in this index.
 
@@ -237,42 +208,6 @@
 	return pS->obj;
 	}
 
-
-
-/**	Looks up an object in the index by object pointer.
-
-	Returns a handle to the object.
-
-	@param	aObj	Pointer to the object to look up.
-	
-	@return	Handle to object (always >0);
-	        KErrNotFound, if object not present in index.
-
-    @pre    Calling thread must be in a critical section.
-    @pre    No fast mutex can be held.
-	@pre	Call in a thread context.
-	@pre	DObject::HandleMutex held.
- */
-TInt DMemSpyObjectIx::At(DObject* aObj)
-	{
-	//Check preconditions(debug build only)
-	__ASSERT_CRITICAL;
-	__ASSERT_NO_FAST_MUTEX;
-
-	if (iCount)
-		{
-		SDObjectIxRec* pS=iObjects;
-		SDObjectIxRec* pE=pS+iCount;
-		TInt i=0;
-		while(pS<pE && pS->obj!=aObj)
-			pS++, i++;
-		if (pS<pE)
-			return(makeHandle(i,pS->str.instance));
-		}
-	return KErrNotFound;
-	}
-
-
 /** Finds the object at a specific position in the index array.
 
 	@param	aIndex	Index into array.
--- a/memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -76,7 +76,7 @@
         }
     else
         {
-        TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteInt32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __RETURN_ADDRESS() ) );
+        //TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteInt32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __RETURN_ADDRESS() ) );
         }
     //
     return ret;
@@ -96,7 +96,7 @@
         }
     else
         {
-        TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteUint32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __RETURN_ADDRESS() ) );
+        //TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteUint32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __RETURN_ADDRESS() ) );
         }
     //
     return ret;
--- a/memspy/Driver/Kernel/Source/MemSpyDriverSuspensionManager.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverSuspensionManager.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -427,10 +427,8 @@
     //
 	if ( iTempObj )
         {
-		NKern::LockSystem();
 		r = iTempObj->Open();
 	    TRACE( Kern::Printf("DMemSpySuspensionManager::OpenTempObject() - open returned: %d", r ));
-		NKern::UnlockSystem();
 		//
         if  ( r == KErrNone )
             {
@@ -499,14 +497,9 @@
 	__ASSERT_DEBUG( iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) );
     if  ( iTempObj )
         {
-	    NKern::ThreadEnterCS();
-        
-        TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - in CS..." ));
+		NKern::ThreadEnterCS();
 	    Kern::SafeClose( iTempObj, NULL );
-        TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - done safe close..." ));
-	    NKern::ThreadLeaveCS();
-
-        TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - left CS" ));
+		NKern::ThreadLeaveCS();
         }
 
     TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - END" ));
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -143,10 +143,8 @@
     //
 	if ( iTempObj )
         {
-		NKern::LockSystem();
 		r = iTempObj->Open();
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - open returned: %d", r ));
-		NKern::UnlockSystem();
 		//
         if  ( r == KErrNone )
             {
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -164,15 +164,18 @@
 
 	    // Iterate through each handle in the process
 	    MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process );
-        MemSpyObjectIx_Wait( processHandles );
+		MemSpyObjectIx_HandleLookupLock();
+        const TInt processHandleCount = processHandles->Count();
+		MemSpyObjectIx_HandleLookupUnlock();
 
-        const TInt processHandleCount = processHandles->Count();
 	    for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ )
     	    {
     	    // Get a handle from the process container...
-            NKern::LockSystem();
+            MemSpyObjectIx_HandleLookupLock();
+			if (processHandleIndex >= processHandles->Count()) break; // Count may have changed in the meantime
     	    DObject* object = (*processHandles)[ processHandleIndex ];
-            NKern::UnlockSystem();
+			if (object && object->Open() != KErrNone) object = NULL;
+			MemSpyObjectIx_HandleLookupUnlock();
             
             if  ( object )
                 {
@@ -187,11 +190,10 @@
                         ++currentWriteIndex;
                         }
                     }
+				object->Close(NULL);
                 }
     	    }
 
-        MemSpyObjectIx_Signal( processHandles );
-
         // If we were asked for process-related chunks, also check the chunk container
         // for entries which we don't have handles to, but do refer to our process
         // Need a listing of all chunks in the system. Let client filter duplicates.
@@ -276,34 +278,36 @@
 	NKern::ThreadEnterCS();
 
     container->Wait();
-    NKern::LockSystem();
     const TInt count = container->Count();
-    NKern::UnlockSystem();
 
     DChunk* foundChunk = NULL;
     
     for(TInt i=0; i<count; i++)
         {
-        NKern::LockSystem();
         DChunk* chunk = (DChunk*) (*container)[i];
-        NKern::UnlockSystem();
-        //
         if  ( chunk == params.iHandle )
             {
             foundChunk = chunk;
             TRACE( PrintChunkInfo( *chunk ) );
+			r = foundChunk->Open();
             break;
             }
         }
 
     container->Signal();
-	NKern::ThreadLeaveCS();
 
     if  ( foundChunk == NULL )
         {
     	Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - KErrNotFound - couldnt find chunk");
+		NKern::ThreadLeaveCS();
         return KErrNotFound;
         }
+	if (r)
+		{
+		Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - %d - Failed to open chunk", r);
+		NKern::ThreadLeaveCS();
+		return r;
+		}
 
     // Prepare return data
     DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk();
@@ -335,6 +339,10 @@
     // Get type & attribs
     params.iType = IdentifyChunkType( *foundChunk );
     params.iAttributes = chunkAdaption.GetAttributes( *foundChunk );
+
+	// Finished with foundChunk
+	foundChunk->Close(NULL);
+	NKern::ThreadLeaveCS();
     
     // Write back to client
     r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalChunkInfoParams) );
@@ -470,40 +478,36 @@
 
     if  ( process && size >= 4 )
         {
+		NKern::ThreadEnterCS();
         // Chunks are mapped into entire process so any thread within the process is enough...
-        DThread* firstThread = processAdaption.GetFirstThread( *process );
+        DThread* firstThread = processAdaption.OpenFirstThread( *process );
         TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) );
         if  ( firstThread != NULL )
             {
-            TInt err = firstThread->Open();
-            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread open result: %d", err ) );
-
+            TBuf8<4> allocatorVTableBuffer;
+            TInt err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() );
+            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err ));
+            //
             if  ( err == KErrNone )
                 {
-                TBuf8<4> allocatorVTableBuffer;
-                err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() );
-                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err ));
-                //
-                if  ( err == KErrNone )
-                    {
-                    TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) );
-                    allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() );
-                    
-                    const TUint32 vtable =   allocatorVTableBuffer[0] +
-                                            (allocatorVTableBuffer[1] << 8) + 
-                                            (allocatorVTableBuffer[2] << 16) + 
-                                            (allocatorVTableBuffer[3] << 24);
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) );
+                TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) );
+                allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() );
+                
+                const TUint32 vtable =   allocatorVTableBuffer[0] +
+                                        (allocatorVTableBuffer[1] << 8) + 
+                                        (allocatorVTableBuffer[2] << 16) + 
+                                        (allocatorVTableBuffer[3] << 24);
+                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) );
 
-                    // Check the v-table to work out if it really is an RHeap
-                    isHeap = ( vtable == rHeapVTable );
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) );
-                    }
+                // Check the v-table to work out if it really is an RHeap
+                isHeap = ( vtable == rHeapVTable );
+                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) );
+                }
 
-                TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) );
-            	Kern::SafeClose( (DObject*&) firstThread, NULL );
-                }
+            TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) );
+            Kern::SafeClose( (DObject*&) firstThread, NULL );
             }
+		NKern::ThreadLeaveCS();
         }
 
     /* We only want RHeap's at the moment
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanClientServer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanClientServer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -96,8 +96,8 @@
     NKern::ThreadEnterCS();
 
     DObject* serverHandle = (DObject*) params.iServerHandle;
-    serverHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeServer, serverHandle );
-    if  ( serverHandle == NULL )
+    DServer* server = static_cast<DServer*>(CheckedOpen(EMemSpyDriverContainerTypeServer, serverHandle));
+    if (server == NULL)
         {
     	Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - END - server not found");
         NKern::ThreadLeaveCS();
@@ -106,47 +106,29 @@
 
 	ResetTempHandles();
 
-    DServer* server = (DServer*) serverHandle;
-    NKern::LockSystem();
-
-    r = server->Open();
-    if  ( r == KErrNone )
+    NKern::LockSystem(); // Iterating session queue requires system lock
+    // Iterate through this server's sessions, writing back session pointer (handle)
+    // to client
+    SDblQue& serverQueue = serverAdaption.GetSessionQueue( *server );
+    SDblQueLink* anchor = &serverQueue.iA;
+    SDblQueLink* link = serverQueue.First();
+    while( link != anchor )
         {
-        // Iterate through this server's sessions, writing back session pointer (handle)
-        // to client
-        SDblQue& serverQueue = serverAdaption.GetSessionQueue( *server );
-        SDblQueLink* anchor = &serverQueue.iA;
-        SDblQueLink* link = serverQueue.First();
-        while( link != anchor )
-        	{
-			DSession* session = serverAdaption.GetSession( link );
+		DSession* session = serverAdaption.GetSession( link );
 
-            // Found a match in the specified container. Write the object's handle (aka the object address)
-            // back to the client address space
-            if  ( session )
-                {
-                AddTempHandle( session );
-                }
-
-            // Get next item
-            link = link->iNext;
+        // Found a match in the specified container. Write the object's handle (aka the object address)
+        // back to the client address space
+        if  ( session )
+            {
+            AddTempHandle( session );
             }
 
-        NKern::ThreadEnterCS();
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - in CS..." ));
-        //
-	    Kern::SafeClose( (DObject*&) server, NULL );
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - done safe close..." ));
-        //
-	    NKern::ThreadLeaveCS();
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - left CS" ));
+        // Get next item
+        link = link->iNext;
         }
-    else
-        {
-    	Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles - error: %d opening server", r);
-        }
-
     NKern::UnlockSystem();
+	server->Close(NULL);
+	NKern::ThreadLeaveCS();
 
     // This variable holds the number of handles that we have already
 	// written to the client-side.
@@ -176,7 +158,6 @@
             }
         }
 
-	NKern::ThreadLeaveCS();
 
 	TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - END - r: %d", r));
 	return r;
@@ -199,74 +180,48 @@
 
 	NKern::ThreadEnterCS();
 
-    DObject* sessionHandle = (DObject*) aSessionHandle;
-    sessionHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeSession, sessionHandle );
-    if  ( sessionHandle == NULL )
+    DSession* session = (DSession*)CheckedOpen(EMemSpyDriverContainerTypeSession, (DObject*)aSessionHandle);
+    if (session == NULL )
         {
     	Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - END - session not found");
         NKern::ThreadLeaveCS();
         return KErrNotFound;
         }
 
-    DSession* session = (DSession*) sessionHandle;
     session->FullName( params.iName );
 
-    NKern::LockSystem();
-    r = session->Open();
-    if  ( r == KErrNone )
+    // Get owner type and id
+    DObject* sessionOwner = sessionAdaption.GetOwner( *session );
+    if  ( sessionOwner )
         {
-        // Get owner type and id
-        DObject* sessionOwner = sessionAdaption.GetOwner( *session );
-        if  ( sessionOwner )
+        const TObjectType objectType = sessionAdaption.GetObjectType( *sessionOwner );
+        if  ( objectType == EProcess )
             {
-            const TObjectType objectType = sessionAdaption.GetObjectType( *sessionOwner );
-            if  ( objectType == EProcess )
-                {
-                DProcess* sessionProcess = (DProcess*) sessionOwner;
-                //
-                params.iOwnerId = processAdaption.GetId( *sessionProcess );
-                params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerProcess;
-                }
-            else if ( objectType == EThread )
-                {
-                DThread* sessionThread = (DThread*) sessionOwner;
-                //
-                params.iOwnerId = threadAdaption.GetId( *sessionThread );
-                params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerThread;
-                }
+            DProcess* sessionProcess = (DProcess*) sessionOwner;
+            //
+            params.iOwnerId = processAdaption.GetId( *sessionProcess );
+            params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerProcess;
             }
-        else
+        else if ( objectType == EThread )
             {
-            params.iOwnerId = -1;
-            params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerNone;
+            DThread* sessionThread = (DThread*) sessionOwner;
+            //
+            params.iOwnerId = threadAdaption.GetId( *sessionThread );
+            params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerThread;
             }
-
-        // Other attributes
-        params.iSessionType = sessionAdaption.GetSessionType( *session );
-        params.iAddress = (TUint8*)session;
-
-        NKern::ThreadEnterCS();
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - in CS..." ));
-        //
-	    Kern::SafeClose( (DObject*&) session, NULL );
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - done safe close..." ));
-        //
-	    NKern::ThreadLeaveCS();
-        TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - left CS" ));
         }
     else
         {
-    	Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo - error: %d opening server", r);
+        params.iOwnerId = -1;
+        params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerNone;
         }
 
-    NKern::UnlockSystem();
-
-    if  ( r == KErrNone )
-        {
-        r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverServerSessionInfo) );
-        }
-
+    // Other attributes
+    params.iSessionType = sessionAdaption.GetSessionType( *session );
+    params.iAddress = (TUint8*)session;
+	session->Close(NULL);
 	NKern::ThreadLeaveCS();
+    r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverServerSessionInfo) );
 
 	TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - END - r: %d", r));
 	return r;
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -49,58 +49,44 @@
 
 
 
-
-
-
-DObject* DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer( TMemSpyDriverContainerType aContainerType, DObject* aSearchFor, TBool aQuick )
-    {
-	__ASSERT_DEBUG( aSearchFor != NULL, MemSpyDriverUtils::Fault( __LINE__ ) );
-    const TObjectType expectedType = ObjectTypeFromMemSpyContainerType( aContainerType );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - START - aSearchFor: 0x%08x, expectedType: %d", aSearchFor, expectedType ));
+DObject* DMemSpyDriverLogChanContainerBase::CheckedOpen(TMemSpyDriverContainerType aContainerType, DObject* aObject, TBool aQuick)
+	{
+	__ASSERT_CRITICAL;
+	__ASSERT_DEBUG(aObject != NULL, MemSpyDriverUtils::Fault( __LINE__ ));
+    const TObjectType expectedType = ObjectTypeFromMemSpyContainerType(aContainerType);
 
-    DObject* ret = NULL;
-    
-    // Quick mode means we just check container ids and we trust that the object
-    // will exist.
-    if ( aQuick )
+    // Quick mode means we just check container ids and we trust that the object will exist.
+	// [TomS: not entirely convinced we can ever be certain of that]
+    TInt err = KErrNotFound;
+    if (aQuick)
         {
-        const TObjectType objectType = OSAdaption().DThread().GetObjectType( *aSearchFor );
-        TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - aSearchFor.iContainerID: %d", objectType ) );
-        if  ( objectType == expectedType )
+		LOG("quick CheckedOpen of %08x", aObject);
+        const TObjectType objectType = OSAdaption().DThread().GetObjectType(*aObject);
+        if (objectType == expectedType)
             {
-            ret = aSearchFor;
+            err = aObject->Open();
             }
         }
-    else
-        {
-        // Full check to see if the specified object is part of the container
-        DObjectCon* container = Kern::Containers()[ expectedType ];
+	else
+		{
+        DObjectCon* container = Kern::Containers()[expectedType];
         container->Wait();
-        NKern::LockSystem();
-
         const TInt count = container->Count();
-        for(TInt i=0; i<count; i++)
+        for (TInt i = 0; i < count; i++)
             {
-            DObject* object = (*container)[ i ];
-
-            // Do the two match?
-            if  ( object == aSearchFor )
+            DObject* object = (*container)[i];
+            if (object == aObject)
                 {
-                TRACE( Kern::Printf("    found match: %O", object));
-
-                ret = object;
-                break;
-                }
-            }
+                err = aObject->Open();
+				break;
+				}
+			}
+		container->Signal();
+		}
 
-        NKern::UnlockSystem();
-        container->Signal();
-        }
-
-    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - END - ret: 0x%08x", ret ));
-    TRACE( Kern::Printf(" ") );
-    return ret;
-    }
+	LOG("CheckedOpen(%d, 0x%08x, quick=%d) returned error %d", aContainerType, aObject, aQuick, err);
+	return (err == KErrNone) ? aObject : NULL;
+	}
 
 
 
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainers.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainers.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -146,7 +146,6 @@
 
         DObjectCon* container = Kern::Containers()[type];
         container->Wait();
-        NKern::LockSystem();
 
         const TInt count = container->Count();
         for(TInt i=0; i<count; i++)
@@ -158,9 +157,7 @@
                 }
             }
 
-        NKern::UnlockSystem();
         container->Signal();
-
     	NKern::ThreadLeaveCS();
         }
     else
@@ -214,34 +211,30 @@
 
                 // Iterate through each handle in the thread/process and add it to the temp handles container if
                 // the handle is of the correct type.
-                MemSpyObjectIx_Wait( handles );
 
-	            TInt handleCount = handles->Count();
+				MemSpyObjectIx_HandleLookupLock();
+				const TInt handleCount = handles->Count();
+				MemSpyObjectIx_HandleLookupUnlock();
                 TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetContainerHandles - %d handles in index...", handleCount ));
 
                 for( TInt handleIndex=0; handleIndex<handleCount; handleIndex++ )
     	            {
     	            // Get a handle from the container...
-                    NKern::LockSystem();
-    	            DObject* objectToSearchFor = (*handles)[ handleIndex ];
-                    NKern::UnlockSystem();
+					MemSpyObjectIx_HandleLookupLock();
+					if (handleIndex >= handles->Count()) break; // Count may have changed in the meantime
+    				DObject* objectToSearchFor = (*handles)[ handleIndex ];
+					if (objectToSearchFor && objectToSearchFor->Open() != KErrNone) objectToSearchFor = NULL;
+					MemSpyObjectIx_HandleLookupUnlock();
         
-                    if  ( objectToSearchFor != NULL )
+                    if (objectToSearchFor && OSAdaption().DThread().GetObjectType(*objectToSearchFor) == ObjectTypeFromMemSpyContainerType(params.iContainer))
                         {
-                        // Check to see if this object is of the specified type. We can use quick mode
-                        // because we know the object is valid since it's registered as a handle of the
-                        // thread/process.
-                        DObject* matchResult = CheckIfObjectIsInContainer( params.iContainer, objectToSearchFor, ETrue );
-                        if  ( matchResult )
-                            {
-                            // Found a match in the specified container. Write the object's handle (aka the object address)
-                            // back to the client address space
-                            AddTempHandle( matchResult );
-                            }
+                        // Found a match in the specified container. Write the object's handle (aka the object address)
+                        // back to the client address space
+                        AddTempHandle( objectToSearchFor );
                         }
+					if (objectToSearchFor) objectToSearchFor->Close(NULL);
     	            }
 
-                MemSpyObjectIx_Signal( handles );
                 NKern::ThreadLeaveCS();
                 }
 
@@ -307,30 +300,21 @@
 
     // First, locate the specific DObject in question. Cast the handle, but don't use the object...
     DObject* handleAsObject = (DObject*) params.iHandle;
-    handleAsObject = CheckIfObjectIsInContainer( params.iType, handleAsObject );
+    handleAsObject = CheckedOpen(params.iType, handleAsObject);
     if  ( handleAsObject != NULL )
         {
         // We found the right object. First get generic info.
         handleAsObject->FullName( params.iName );
         handleAsObject->Name( params.iNameDetail );
         
-        NKern::LockSystem();
-        r = handleAsObject->Open();
-        NKern::UnlockSystem();
-        //
-        if  ( r == KErrNone )
-            {
-            // Using threadAddaption to fetch generic info.
-            // Implementations of following get functions are actually in DMemSpyDriverOSAdaptionDObject
-            // so it does not matter what adaption to use for generic info.
-            DMemSpyDriverOSAdaptionDThread& threadAddaption = OSAdaption().DThread();
-            params.iAccessCount = threadAddaption.GetAccessCount( *handleAsObject );
-            params.iUniqueID = threadAddaption.GetUniqueID( *handleAsObject );
-            params.iProtection = threadAddaption.GetProtection( *handleAsObject );
-            params.iAddressOfKernelOwner = threadAddaption.GetAddressOfKernelOwner( *handleAsObject );
-            //
-            handleAsObject->Close( NULL );
-            }
+        // Using threadAddaption to fetch generic info.
+        // Implementations of following get functions are actually in DMemSpyDriverOSAdaptionDObject
+        // so it does not matter what adaption to use for generic info.
+        DMemSpyDriverOSAdaptionDThread& threadAddaption = OSAdaption().DThread();
+        params.iAccessCount = threadAddaption.GetAccessCount( *handleAsObject );
+        params.iUniqueID = threadAddaption.GetUniqueID( *handleAsObject );
+        params.iProtection = threadAddaption.GetProtection( *handleAsObject );
+        params.iAddressOfKernelOwner = threadAddaption.GetAddressOfKernelOwner( *handleAsObject );
         
         // Get type-specific info.
         if  ( params.iType == EMemSpyDriverContainerTypeThread )
@@ -338,76 +322,49 @@
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeThread" ));
 
             DThread* object = (DThread*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread();
-                //
-                params.iId = threadAdaption.GetId( *object );
-                params.iPriority = threadAdaption.GetPriority( *object );
-                params.iAddressOfOwningProcess = threadAdaption.GetAddressOfOwningProcess( *object );
-                threadAdaption.GetNameOfOwningProcess( *object, params.iNameOfOwner );
-                //
-                object->Close( NULL );
-                }
+            params.iId = threadAdaption.GetId( *object );
+            params.iPriority = threadAdaption.GetPriority( *object );
+            params.iAddressOfOwningProcess = threadAdaption.GetAddressOfOwningProcess( *object );
+            threadAdaption.GetNameOfOwningProcess( *object, params.iNameOfOwner );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeProcess )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeProcess" ));
 
             DProcess* object = (DProcess*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess();
+            //
+            params.iId = processAdaption.GetId( *object );
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess();
-                //
-                params.iId = processAdaption.GetId( *object );
-                //
-                params.iPriority = processAdaption.GetPriority( *object );
-                params.iAddressOfOwningProcess = processAdaption.GetAddressOfOwningProcess( *object );
-                params.iCreatorId = processAdaption.GetCreatorId( *object );
-                params.iSecurityZone = processAdaption.GetSecurityZone( *object );
-                params.iAttributes = processAdaption.GetAttributes( *object );
-                params.iAddressOfDataBssStackChunk = processAdaption.GetAddressOfDataBssStackChunk( *object );
-                //
-                object->Close( NULL );
-                }
+            params.iPriority = processAdaption.GetPriority( *object );
+            params.iAddressOfOwningProcess = processAdaption.GetAddressOfOwningProcess( *object );
+            params.iCreatorId = processAdaption.GetCreatorId( *object );
+            params.iSecurityZone = processAdaption.GetSecurityZone( *object );
+            params.iAttributes = processAdaption.GetAttributes( *object );
+            params.iAddressOfDataBssStackChunk = processAdaption.GetAddressOfDataBssStackChunk( *object );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeChunk )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeChunk" ));
 
             DChunk* object = (DChunk*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDChunk& ca = OSAdaption().DChunk();
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDChunk& ca = OSAdaption().DChunk();
-                //
-                params.iSize = ca.GetSize( *object );
-                params.iId = ca.GetOwningProcessId( *object );
-                params.iAddressOfOwningProcess = ca.GetAddressOfOwningProcess( *object );
-                params.iMaxSize = ca.GetMaxSize( *object );
-                params.iBottom = ca.GetBottom( *object );
-                params.iTop = ca.GetTop( *object );
-                params.iAttributes = ca.GetAttributes( *object );
-                params.iStartPos = ca.GetStartPos( *object );
-                params.iControllingOwner = ca.GetControllingOwnerId( *object );
-                params.iRestrictions = ca.GetRestrictions( *object );
-                params.iMapAttr = ca.GetMapAttr( *object );
-                params.iChunkType = ca.GetType( *object );
-                ca.GetNameOfOwningProcess( *object, params.iNameOfOwner );
-                //
-                object->Close( NULL );
-                }
+            params.iSize = ca.GetSize( *object );
+            params.iId = ca.GetOwningProcessId( *object );
+            params.iAddressOfOwningProcess = ca.GetAddressOfOwningProcess( *object );
+            params.iMaxSize = ca.GetMaxSize( *object );
+            params.iBottom = ca.GetBottom( *object );
+            params.iTop = ca.GetTop( *object );
+            params.iAttributes = ca.GetAttributes( *object );
+            params.iStartPos = ca.GetStartPos( *object );
+            params.iControllingOwner = ca.GetControllingOwnerId( *object );
+            params.iRestrictions = ca.GetRestrictions( *object );
+            params.iMapAttr = ca.GetMapAttr( *object );
+            params.iChunkType = ca.GetType( *object );
+            ca.GetNameOfOwningProcess( *object, params.iNameOfOwner );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeLibrary )
             {
@@ -416,28 +373,19 @@
 	        Kern::AccessCode();
             //
             DLibrary* object = (DLibrary*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDCodeSeg& csa = OSAdaption().DCodeSeg();
+            DCodeSeg* codeSeg = csa.GetCodeSeg( *object );
+            params.iAddressOfCodeSeg = (TUint8*)codeSeg;
+            params.iMapCount = csa.GetMapCount( *object );
+            params.iState = csa.GetState( *object );
             //
-            if  ( r == KErrNone )
+            if  ( codeSeg )
                 {
-                DMemSpyDriverOSAdaptionDCodeSeg& csa = OSAdaption().DCodeSeg();
-                DCodeSeg* codeSeg = csa.GetCodeSeg( *object );
-                params.iAddressOfCodeSeg = (TUint8*)codeSeg;
-                params.iMapCount = csa.GetMapCount( *object );
-                params.iState = csa.GetState( *object );
-                //
-                if  ( codeSeg )
-                    {
-                    params.iSize = csa.GetSize( *codeSeg );
-                    }
-                else
-                    {
-                    r = KErrNotFound;
-                    }
-                //
-                object->Close( NULL );
+                params.iSize = csa.GetSize( *codeSeg );
+                }
+            else
+                {
+                r = KErrNotFound;
                 }
             //
 	        Kern::EndAccessCode();
@@ -447,39 +395,21 @@
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeSemaphore" ));
 
             DSemaphore* object = (DSemaphore*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDSemaphore& sa = OSAdaption().DSemaphore();
-                params.iCount = sa.GetCount( *object );
-                params.iResetting = sa.GetResetting( *object );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDSemaphore& sa = OSAdaption().DSemaphore();
+            params.iCount = sa.GetCount( *object );
+            params.iResetting = sa.GetResetting( *object );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeMutex )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeMutex" ));
 
             DMutex* object = (DMutex*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDMutex& ma = OSAdaption().DMutex();
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDMutex& ma = OSAdaption().DMutex();
-                //
-                params.iCount = ma.GetHoldCount( *object );
-                params.iWaitCount = ma.GetWaitCount( *object );
-                params.iResetting = ma.GetResetting( *object );
-                params.iOrder = ma.GetOrder( *object );
-                //
-                object->Close( NULL );
-                }
+            params.iCount = ma.GetHoldCount( *object );
+            params.iWaitCount = ma.GetWaitCount( *object );
+            params.iResetting = ma.GetResetting( *object );
+            params.iOrder = ma.GetOrder( *object );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeTimer )
             {
@@ -487,98 +417,62 @@
 
             // Get timer properties
             DTimer* object = (DTimer*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDTimer& ta = OSAdaption().DTimer();
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDTimer& ta = OSAdaption().DTimer();
-                //
-                params.iTimerType = MapToMemSpyTimerType( ta.GetType( *object ) );
-                params.iTimerState = MapToMemSpyTimerState( ta.GetState( *object ) );
-                //
-                object->Close( NULL );
-                }
+            params.iTimerType = MapToMemSpyTimerType( ta.GetType( *object ) );
+            params.iTimerState = MapToMemSpyTimerState( ta.GetState( *object ) );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeServer )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeServer" ));
 
             DServer* object = (DServer*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
+            DMemSpyDriverOSAdaptionDServer& sa = OSAdaption().DServer();
             //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDServer& sa = OSAdaption().DServer();
-                //
-                params.iCount = sa.GetSessionCount( *object );
-                params.iId = sa.GetOwningThreadId( *object );
-                params.iSessionType = sa.GetSessionType( *object );
-                params.iAddressOfOwningThread = sa.GetAddressOfOwningThread( *object );
-                sa.GetNameOfOwningThread( *object, params.iNameOfOwner );
-                //
-                object->Close( NULL );
-                }
+            params.iCount = sa.GetSessionCount( *object );
+            params.iId = sa.GetOwningThreadId( *object );
+            params.iSessionType = sa.GetSessionType( *object );
+            params.iAddressOfOwningThread = sa.GetAddressOfOwningThread( *object );
+            sa.GetNameOfOwningThread( *object, params.iNameOfOwner );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeSession )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeSession" ));
 
             DSession* object = (DSession*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
-            //
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - open error: %d", r ));
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDServer& serverAdaption = OSAdaption().DServer();
-                DMemSpyDriverOSAdaptionDSession& sessionAdaption = OSAdaption().DSession();
+            DMemSpyDriverOSAdaptionDServer& serverAdaption = OSAdaption().DServer();
+            DMemSpyDriverOSAdaptionDSession& sessionAdaption = OSAdaption().DSession();
 
-                params.iName.Zero();
+            params.iName.Zero();
 
-                TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting session type..." ));
-                params.iSessionType = sessionAdaption.GetSessionType( *object );
-                params.iAddressOfServer = sessionAdaption.GetAddressOfServer( *object );
-                params.iTotalAccessCount = sessionAdaption.GetTotalAccessCount( *object );
-                params.iSvrSessionType = sessionAdaption.GetSessionType( *object );
-                params.iMsgCount = sessionAdaption.GetMsgCount( *object );
-                params.iMsgLimit = sessionAdaption.GetMsgLimit( *object );
-                
-                // Its more useful in this instance, if the name object
-                // points to the server which the session is connected to
-                // (rather than displaying a process-local name).
-                DServer* server = sessionAdaption.GetServer( *object );
-	            TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting full name, server: 0x%08x", server ));
-                //
-                if  ( server )
+            TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting session type..." ));
+            params.iSessionType = sessionAdaption.GetSessionType( *object );
+            params.iAddressOfServer = sessionAdaption.GetAddressOfServer( *object );
+            params.iTotalAccessCount = sessionAdaption.GetTotalAccessCount( *object );
+            params.iSvrSessionType = sessionAdaption.GetSessionType( *object );
+            params.iMsgCount = sessionAdaption.GetMsgCount( *object );
+            params.iMsgLimit = sessionAdaption.GetMsgLimit( *object );
+            
+            // Its more useful in this instance, if the name object
+            // points to the server which the session is connected to
+            // (rather than displaying a process-local name).
+            DServer* server = (DServer*)CheckedOpen(EMemSpyDriverContainerTypeServer, sessionAdaption.GetServer( *object ));
+	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting full name, server: 0x%08x", server ));
+            //
+            if  ( server )
+                {
+                server->FullName( params.iName );
+
+                // Continue as normal for other items
+	            TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - server: 0x%08x, server->iOwningThread: 0x%08x", server, server->iOwningThread ));
+                DThread* owningThread = serverAdaption.GetOwningThread( *server );
+                if  ( owningThread )
                     {
-	                NKern::LockSystem();
-                    r = server->Open();
-     	            NKern::UnlockSystem();
-
-                    if  ( r == KErrNone )
-                        {
-                        server->FullName( params.iName );
- 
-                        // Continue as normal for other items
-	                    TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - server: 0x%08x, server->iOwningThread: 0x%08x", server, server->iOwningThread ));
-                        DThread* owningThread = serverAdaption.GetOwningThread( *server );
-                        if  ( owningThread )
-                            {
-	                        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting server thread id..." ));
-                            params.iId = serverAdaption.GetOwningThreadId( *server );
-                            }
-
-                        server->Close( NULL );
-                        }
+	                TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting server thread id..." ));
+                    params.iId = serverAdaption.GetOwningThreadId( *server );
                     }
 
-                TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - closing session object..." ));
-                object->Close( NULL );
+                server->Close(NULL);
                 }
             }
         else if ( params.iType == EMemSpyDriverContainerTypeLogicalDevice )
@@ -586,39 +480,21 @@
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeLogicalDevice" ));
 
             DLogicalDevice* object = (DLogicalDevice*) handleAsObject;
-	        NKern::LockSystem();
-            r = object->Open();
-    	    NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDLogicalDevice& lda = OSAdaption().DLogicalDevice();
-                params.iOpenChannels = lda.GetOpenChannels( *object );
-                params.iVersion = lda.GetVersion( *object );
-                params.iParseMask = lda.GetParseMask( *object );
-                params.iUnitsMask = lda.GetUnitsMask( *object );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDLogicalDevice& lda = OSAdaption().DLogicalDevice();
+            params.iOpenChannels = lda.GetOpenChannels( *object );
+            params.iVersion = lda.GetVersion( *object );
+            params.iParseMask = lda.GetParseMask( *object );
+            params.iUnitsMask = lda.GetUnitsMask( *object );
             }
         else if ( params.iType == EMemSpyDriverContainerTypePhysicalDevice )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypePhysicalDevice" ));
 	        
 	        DPhysicalDevice* object = (DPhysicalDevice*) handleAsObject;
-            NKern::LockSystem();
-            r = object->Open();
-            NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDPhysicalDevice& pda = OSAdaption().DPhysicalDevice();
-                params.iVersion = pda.GetVersion( *object );
-                params.iUnitsMask = pda.GetUnitsMask( *object );
-                params.iAddressOfCodeSeg = pda.GetAddressOfCodeSeg( *object );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDPhysicalDevice& pda = OSAdaption().DPhysicalDevice();
+            params.iVersion = pda.GetVersion( *object );
+            params.iUnitsMask = pda.GetUnitsMask( *object );
+            params.iAddressOfCodeSeg = pda.GetAddressOfCodeSeg( *object );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeLogicalChannel )
             {
@@ -629,37 +505,19 @@
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeChangeNotifier" ));
 
 	        DChangeNotifier* object = (DChangeNotifier*) handleAsObject;
-            NKern::LockSystem();
-            r = object->Open();
-            NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDChangeNotifier& cna = OSAdaption().DChangeNotifier();
-                params.iChanges = cna.GetChanges( *object );
-                params.iAddressOfOwningThread = cna.GetAddressOfOwningThread( *object );
-                cna.GetNameOfOwningThread( *object, params.iNameOfOwner );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDChangeNotifier& cna = OSAdaption().DChangeNotifier();
+            params.iChanges = cna.GetChanges( *object );
+            params.iAddressOfOwningThread = cna.GetAddressOfOwningThread( *object );
+            cna.GetNameOfOwningThread( *object, params.iNameOfOwner );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeUndertaker )
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeUndertaker" ));
 	        
             DUndertaker* object = (DUndertaker*) handleAsObject;
-            NKern::LockSystem();
-            r = object->Open();
-            NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDUndertaker& uta = OSAdaption().DUndertaker();
-                params.iAddressOfOwningThread = uta.GetAddressOfOwningThread( *object );
-                uta.GetNameOfOwningThread( *object, params.iNameOfOwner );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDUndertaker& uta = OSAdaption().DUndertaker();
+            params.iAddressOfOwningThread = uta.GetAddressOfOwningThread( *object );
+            uta.GetNameOfOwningThread( *object, params.iNameOfOwner );
             }
         else if ( params.iType == EMemSpyDriverContainerTypeMsgQueue )
             {
@@ -674,26 +532,18 @@
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeCondVar" ));
 	        
             DCondVar* object = (DCondVar*) handleAsObject;
-            NKern::LockSystem();
-            r = object->Open();
-            NKern::UnlockSystem();
-            //
-            if  ( r == KErrNone )
-                {
-                DMemSpyDriverOSAdaptionDCondVar& cva = OSAdaption().DCondVar();
-                params.iResetting = cva.GetResetting( *object );
-                params.iAddressOfOwningThread = cva.GetAddressOfMutex( *object );
-                cva.GetNameOfMutex( *object, params.iNameOfOwner );
-                params.iWaitCount = cva.GetWaitCount( *object );
-                //
-                object->Close( NULL );
-                }
+            DMemSpyDriverOSAdaptionDCondVar& cva = OSAdaption().DCondVar();
+            params.iResetting = cva.GetResetting( *object );
+            params.iAddressOfOwningThread = cva.GetAddressOfMutex( *object );
+            cva.GetNameOfMutex( *object, params.iNameOfOwner );
+            params.iWaitCount = cva.GetWaitCount( *object );
             }
         else
             {
 	        TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - KErrNotSupported" ));
             r = KErrNotSupported;
             }
+		handleAsObject->Close(NULL);
         }
     else
         {
@@ -881,13 +731,12 @@
 	NKern::ThreadEnterCS();
 
     // First, locate the specific DObject in question. Cast the handle, but don't use the object...
-    // NB: This claims the system lock
-    DObject* object = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypePropertyRef, aHandle );
+    DObject* object = CheckedOpen(EMemSpyDriverContainerTypePropertyRef, aHandle);
     TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetPAndSInfo() - handle search returned: 0x%08x", object ));
 
     if  ( object != NULL )
         {
-        NKern::LockSystem();
+        NKern::LockSystem(); // Keep this, the DPropertyRef APIs use it -TomS
 
         DMemSpyDriverOSAdaptionDPropertyRef& pra = OSAdaption().DPropertyRef();
         const TBool isReady = pra.GetIsReady( *object );
@@ -913,6 +762,7 @@
             }
 
         NKern::UnlockSystem();
+		object->Close(NULL);
         }
 
     NKern::ThreadLeaveCS();
@@ -939,7 +789,7 @@
     NKern::ThreadEnterCS();
     
     DObject* condVarHandle = (DObject*) params.iCondVarHandle;
-    condVarHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeCondVar, condVarHandle );
+    condVarHandle = CheckedOpen(EMemSpyDriverContainerTypeCondVar, condVarHandle);
     if  ( condVarHandle == NULL )
         {
         Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrs() - END - condVar not found");
@@ -949,9 +799,9 @@
     
     ResetTempHandles();
         
-    DCondVar* condVar = (DCondVar*) params.iCondVarHandle;;
+    DCondVar* condVar = (DCondVar*) condVarHandle;
     
-    NKern::LockSystem();
+    NKern::LockSystem(); // Keep this, needed for iterating suspended queue -TomS
 
     // Iterate through suspended threads, writing back thread pointer (handle)
     // to client
@@ -1003,6 +853,7 @@
             }
         }
 
+	condVarHandle->Close(NULL);
     NKern::ThreadLeaveCS();
 
     TRACE( Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrs() - END - r: %d", r));
@@ -1026,7 +877,7 @@
     NKern::ThreadEnterCS();
 
     DObject* threadHandle = (DObject*) aThreadHandle;
-    threadHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeThread, threadHandle );
+    threadHandle = CheckedOpen(EMemSpyDriverContainerTypeThread, threadHandle);
     if  ( threadHandle == NULL )
         {
         Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrInfo() - END - thread not found");
@@ -1043,6 +894,7 @@
         r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverCondVarSuspendedThreadInfo) );
         }
     
+	threadHandle->Close(NULL);
     NKern::ThreadLeaveCS();
     
     TRACE( Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrInfo() - END - r: %d", r));
@@ -1106,17 +958,13 @@
 
         if  ( handles != NULL )
             {
-            MemSpyObjectIx_Wait( handles );
-            //
-            TInt searchResult = handles->At( aHandleToLookFor );
-	        if  ( searchResult != KErrNotFound )
+            TBool found = handles->Find( aHandleToLookFor );
+	        if (found)
 		        {
                 TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::SearchThreadsFor - found handle match in [%O]", thread ));
                 aStream.WriteUint32( (TUint32) thread );
                 ++matches;
 		        }
-            //
-            MemSpyObjectIx_Signal( handles );
             }
         }
 
@@ -1151,17 +999,13 @@
 
         if  ( handles != NULL )
             {
-            MemSpyObjectIx_Wait( handles );
-            //
-            TInt searchResult = handles->At( aHandleToLookFor );
-	        if  ( searchResult != KErrNotFound )
+            TBool found = handles->Find( aHandleToLookFor );
+	        if  ( found )
 		        {
                 TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::SearchProcessFor - found handle match in [%O]", process ));
                 aStream.WriteUint32( (TUint32) process );
                 ++matches;
 		        }
-            //
-            MemSpyObjectIx_Signal( handles );
             }
         }
 
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -47,11 +47,6 @@
 
 DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase()
 	{
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - START - this: 0x%08x", this ));
-
-    ReleaseFreeCells();
-
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - END - this: 0x%08x", this ));
 	}
 
 
@@ -173,207 +168,15 @@
 
 
 
-TInt DMemSpyDriverLogChanHeapBase::OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName )
-    {
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap() - START - aHeap.ChunkIsInitialised: %d, aExpectedHeapVTable: 0x%08x, aClientThread: %O", aHeap.ChunkIsInitialised(), aExpectedHeapVTable, &aClientThread ));
-    __ASSERT_ALWAYS( aHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapChunkAlreadyCloned ) );
-
-    TInt r = KErrNotFound;
-    aUserHeapChunk = NULL;
-    
-    NKern::ThreadEnterCS();
-
-    const TBool allocatorIsReallyRHeap = GetUserHeapHandle( aClientThread, aHeap, aExpectedHeapVTable );
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - allocatorIsReallyRHeap: %d", allocatorIsReallyRHeap));
-
-    if  ( allocatorIsReallyRHeap )
-        {
-        RAllocator* allocator = OSAdaption().DThread().GetAllocator( aClientThread );
-
-        // Open client's heap chunk in order to read it's dimensions
-        const TInt clientsHeapChunkHandle = aHeap.iChunkHandle;
-	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunkHandle: 0x%08x, allocatorAddress: 0x%08x", clientsHeapChunkHandle, allocator));
-
- 	    NKern::LockSystem();
-        DChunk* clientsHeapChunk = (DChunk*) Kern::ObjectFromHandle( &aClientThread, clientsHeapChunkHandle, EChunk );
-        NKern::UnlockSystem();
-	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunk: 0x%08x", clientsHeapChunk ));
-       
-        if  ( clientsHeapChunk != NULL )
-            {
-            // Get the chunk name (if the caller asked for it)
-            if  ( aClientHeapChunkName )
-                {
-                clientsHeapChunk->FullName( *aClientHeapChunkName );
-                }
-                
-            // Update the heap chunk pointer. We do this now because this
-            // should point to the _real_ user-side heap chunk, rather than
-            // the copy of the chunk that we are about to make.
-            aUserHeapChunk = clientsHeapChunk;
-
-            // Set up ourselves to duplicate their heap chunk
-            const TInt clientsHeapChunkSize = OSAdaption().DChunk().GetSize( *clientsHeapChunk );
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", clientsHeapChunk->iBase, clientsHeapChunkSize, clientsHeapChunk->iMaxSize, clientsHeapChunk ));
-
-            // Make a new chunk that is the same size, owned by this thread.
-            TChunkCreateInfo info;
-            info.iType         = TChunkCreateInfo::ESharedKernelSingle;
-            info.iMaxSize      = clientsHeapChunkSize;
-            info.iOwnsMemory   = ETrue; // Use memory from system's free pool
-            info.iDestroyedDfc = NULL;
-        #ifdef __EPOC32__
-            info.iMapAttr      = (TInt)EMapAttrFullyBlocking; // Full caching
-        #endif
-
-            // Holds a copy of the client's heap chunk
-            DChunk* heapCopyChunk;
-            TLinAddr heapCopyChunkAddress;
-            TUint32 heapCopyChunkMappingAttributes;
-            r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - creating chunk returned: %d", r));
-            //
-            if  ( r == KErrNone )
-                {
-	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress));
-                
-                // Commit memory for entire buffer
-                TUint32 physicalAddress = 0;
-                r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, clientsHeapChunkSize, physicalAddress );
-	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - commiting chunk returned: %d", r));
-
-                if  ( r != KErrNone)
-                    {
-                    // On error, thow away the chunk we have created
-                    Kern::ChunkClose( heapCopyChunk );
-                    heapCopyChunk = NULL;
-                    }
-                else
-                    {
-    	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - heapCopyChunk->iSize: 0x%08x, heapCopyChunk->iBase: 0x%08x, heapCopyChunkAddress: 0x%08x, physicalAddress: 0x%08x", heapCopyChunk->iSize, heapCopyChunk->iBase, heapCopyChunkAddress, physicalAddress));
-    
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - trying to copy %d bytes from clients allocator address of 0x%08x", clientsHeapChunkSize, allocator ));
-                    r = Kern::ThreadRawRead( &aClientThread, allocator, (TAny*) heapCopyChunkAddress, clientsHeapChunkSize );
-
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - read result of clients heap data is: %d", r));
-                    if  ( r == KErrNone )
-                        {
-                        // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta
-                        // beween the heap addresses in the client's address space and the kernel address space.
-                        aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes );
-                        }
-                    }
-                }
-            }
-        else
-            {
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - could not open clients heap chunk by its handle" ) );
-            r = KErrNotFound;
-            }
-        }
-    else
-        {
-	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clients heap is not an RHeap (allocated vTable mismatch)" ) );
-        r = KErrNotSupported;
-        }
-
-    NKern::ThreadLeaveCS();
-
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - r: %d", r ));
-    return r;
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-TBool DMemSpyDriverLogChanHeapBase::GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable )
-    {
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle() - START - aExpectedVTable: 0x%08x", aExpectedVTable) );
-
-    RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread );
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - allocator addr: 0x%08x", allocator) );
-    TUint* pAllocator = (TUint*) allocator;
-    // 
-    TBool vTableOkay = EFalse;
-    TUint vtable = 0;
-
-    // Read a bit more data than is available for debugging purposes
-    TBuf8<32> vtableBuf;
-    TInt r = Kern::ThreadRawRead( &aThread, pAllocator, (TUint8*) vtableBuf.Ptr(), vtableBuf.MaxLength() );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - read result of vtable data from requested thread is: %d", r));
-    if  ( r == KErrNone )
-        {
-        TRACE( MemSpyDriverUtils::DataDump("allocator vtable data - %lS", vtableBuf.Ptr(), vtableBuf.MaxLength(), vtableBuf.MaxLength() ) );
-        vtableBuf.SetLength( vtableBuf.MaxLength() );
-        
-        vtable = vtableBuf[0] +
-                (vtableBuf[1] << 8) + 
-                (vtableBuf[2] << 16) + 
-                (vtableBuf[3] << 24);
-        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - client VTable is: 0x%08x", vtable) );
-
-        // Check the v-table to work out if it really is an RHeap
-        vTableOkay = ( vtable == aExpectedVTable );
-        if  ( vTableOkay )
-            {
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables okay") );
-            r = aHeap.ReadFromUserAllocator( aThread );
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - after userget, error: %d", r));
-        
-            }
-        else
-            {
-            TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables dont match! - aExpectedVTable: 0x%08x, allocator addr: 0x%08x, client VTable is: 0x%08x, aThread: %O", aExpectedVTable, allocator, vtable, &aThread ) );
-            }
-        }
-    else
-        {
-        TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - error during client vTable reading: %d, aThread: %O", r, &aThread ) );
-        }
-    //
-    return (vTableOkay && (r == KErrNone));
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo )
     {
     const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
-    const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
+    //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
     const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
     const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
 
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
+    /*
+	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator                                      -" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iAccessCount:       %d", rHeapObjectData.iAccessCount ) );
@@ -408,7 +211,7 @@
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iRand:                   %d", rHeapObjectData.iRand ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTestData:               0x%08x", rHeapObjectData.iTestData ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
-
+	*/
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free)                                    -" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
@@ -431,12 +234,6 @@
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
 
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Common)                                  -" ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - total cell count:               %d", rHeapStats.StatsCommon().TotalCellCount() ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) );
-
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info                                      -" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size:                     %d", rHeapMetaData.ChunkSize() ) );
@@ -445,73 +242,15 @@
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator:                %d", rHeapMetaData.IsDebugAllocator() ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap:                    %d", rHeapMetaData.IsSharedHeap() ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread:                    %d", rHeapMetaData.IsUserThread() ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree() ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated() ) );
+    //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree() ) );
+    //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated() ) );
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable:                    0x%08x", rHeapMetaData.VTable() ) );
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size:               %d", rHeapMetaData.ClassSize() ) );
+    //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size:               %d", rHeapMetaData.ClassSize() ) );
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap size:                      %d", rHeapMetaData.iHeapSize ) );
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - allocator address:              0x%08x", rHeapMetaData.iAllocatorAddress ) );
     }
 
-
-
-
-
-
-
-
-
-
-TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel()
-    {
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") );
-    
-    TInt r = KErrNone;
-    TBool debugKernel = EFalse;
-
-    NKern::ThreadEnterCS();
-    RMemSpyDriverRHeapKernelInPlace rHeap;
-    r = OpenKernelHeap( rHeap );
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - open kernel heap returned: %d", r) );
-
-    if  ( r == KErrNone )
-        {
-        debugKernel = IsDebugKernel( rHeap );
-
-        // Tidy up
-        rHeap.DisassociateWithKernelChunk();
-        }
-
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - debugKernel: %d", debugKernel) );
-    NKern::ThreadLeaveCS();
-
- 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - ret: %d", r) );
-    return debugKernel;
-    }
-
-
-TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap )
-    {
-    TBool debugKernel = EFalse;
-    //
- 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") );
-    NKern::ThreadEnterCS();
-
-    // Request that the kernel fail the next heap allocation
-    aHeap.FailNext();
-
-    // Allocate a new cell, and in debug builds of the kernel, this should be NULL
-    TInt* cell = new TInt();
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - cell: 0x%08x", cell) );
-    debugKernel = ( cell == NULL );
-    delete cell;
-
-    NKern::ThreadLeaveCS();
- 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - debugKernel: %d", debugKernel) );
-    //
-    return debugKernel;
-    }
-
-
-TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer )
+TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer )
     {
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) );
 
@@ -520,16 +259,13 @@
 
     // This object holds all of the info we will accumulate for the client.
     TMemSpyHeapInfo masterHeapInfo;
-    masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap );
+    masterHeapInfo.SetType(aHeap.GetTypeFromHelper());
     masterHeapInfo.SetTid( 2 );
     masterHeapInfo.SetPid( 1 );
 
     // This is the RHeap-specific object that contains all RHeap info
     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
 
-    // This is the object data for the RHeap instance
-    TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
-    aHeap.CopyObjectDataTo( rHeapObjectData );
 
     // When walking the kernel heap we must keep track of the free cells
     // without allocating any more memory (on the kernel heap...)
@@ -544,7 +280,7 @@
 
     // We must walk the client's heap in order to build statistics
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - calling heap walker constructor..."));
-    RMemSpyDriverHeapWalker heapWalker( aHeap, aIsDebugAllocator );
+    RMemSpyDriverHeapWalker heapWalker(aHeap);
     if  ( aTransferBuffer )
         {
         // This will allow us to identify that we're writing directly to the stream
@@ -596,18 +332,19 @@
 
     // Get remaining meta data that isn't stored elsewhere
     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
-    rHeapMetaData.SetChunkName( aChunkName );
+	TFullName chunkName;
+	aHeap.Chunk().FullName(chunkName);
+    rHeapMetaData.SetChunkName(chunkName);
     rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() );
     rHeapMetaData.SetChunkHandle( &aHeap.Chunk() );
-    rHeapMetaData.SetChunkBaseAddress( aHeap.Chunk().Base() );
-    rHeapMetaData.SetDebugAllocator( aIsDebugAllocator );
-    rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() );
-    rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( aIsDebugAllocator ) );
+    rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase(aHeap.Chunk()) );
+    rHeapMetaData.SetDebugAllocator(aHeap.Helper()->AllocatorIsUdeb());
     rHeapMetaData.SetUserThread( EFalse );
     rHeapMetaData.SetSharedHeap( ETrue );
-
-    // Get any heap-specific info
-    aHeap.GetHeapSpecificInfo( masterHeapInfo );
+	rHeapMetaData.iHeapSize = aHeap.Helper()->CommittedSize();
+	rHeapMetaData.iAllocatorAddress = (TAny*)aHeap.Helper()->AllocatorAddress();
+	rHeapMetaData.iMinHeapSize = aHeap.Helper()->MinCommittedSize();
+	rHeapMetaData.iMaxHeapSize = aHeap.Helper()->MaxCommittedSize();
 
     PrintHeapInfo( masterHeapInfo );
 
@@ -641,17 +378,12 @@
 
 
 
-TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/ )
+TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/)
     {
     TInt error = KErrNone;
     //
-    if  ( aCellType == EMemSpyDriverGoodFreeCell || aCellType == EMemSpyDriverBadFreeCellAddress || aCellType == EMemSpyDriverBadFreeCellSize )
+    if  (aCellType & EMemSpyDriverFreeCellMask)
         {
-        TMemSpyDriverFreeCell cell;
-        cell.iType = aCellType;
-        cell.iAddress = aCellAddress;
-        cell.iLength = aLength;
-        //
         if  ( iStackStream )
             {
             if  ( !iStackStream->IsFull() )
@@ -669,163 +401,16 @@
                 error = KErrAbort;
                 }
             }
-        else
-            {
-            NKern::ThreadEnterCS();
-            error = iFreeCells.Append( cell );
-            NKern::ThreadLeaveCS();
-            //
-            if ( error == KErrNone )
-                {
-                ++iFreeCellCount;
-                }
-            }
-        }
+       }
     //
     return ( error == KErrNone );
     }
 
 
 void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit()
-    {
-    // Can't delete the free cell list here as we might be walking the kernel heap
-    iFreeCellCount = 0;
-    }
-
-
-
-
-
-
-TInt DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer()
-    {
-    // Transfer free cells immediately from xfer stream
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream ));
-    __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) );
-    //
-    TInt r = KErrNoMemory;
-    //
-    NKern::ThreadEnterCS();
-    //
-    iHeapStream = new RMemSpyMemStreamWriter();
-    if  ( iHeapStream )
-        {
-        const TInt requiredMemory = CalculateFreeCellBufferSize();
-        r = OpenXferStream( *iHeapStream, requiredMemory );
-        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r ));
-
-        if  ( r == KErrNone )
-            {
-            const TInt count = iFreeCells.Count();
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - free cell count: %d", count ));
-            //
-            iHeapStream->WriteInt32( count );
-            for( TInt i=0; i<count; i++ )
-                {
-                const TMemSpyDriverFreeCell& cell = iFreeCells[ i ];
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - storing entry: %d", i ));
-                //
-                iHeapStream->WriteInt32( cell.iType );
-                iHeapStream->WriteUint32( reinterpret_cast<TUint32>( cell.iAddress ) );
-                iHeapStream->WriteInt32( cell.iLength );
-                }
-
-            // Finished with the array now
-            iFreeCells.Reset();
-
-            // We return the amount of client-side memory that needs to be allocated to hold the buffer
-            r = requiredMemory;
-            }
-        }
-    //
-    NKern::ThreadLeaveCS();
-               
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - END - r: %d", r));
-	return r;
-    }
-
-
-TInt DMemSpyDriverLogChanHeapBase::FetchFreeCells( TDes8* aBufferSink )
-    {
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - START - iHeapStream: 0x%08x", iHeapStream ));
-    __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) );
-
-    TInt r = KErrNone;
-
-    // Write buffer to client
-    NKern::ThreadEnterCS();
-    r = iHeapStream->WriteAndClose( aBufferSink );
-
-    // Tidy up
-    ReleaseFreeCells();
-
-    NKern::ThreadLeaveCS();
-    //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - END - r: %d", r));
-	return r;
-    }
-
-
-
-TInt DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() const
-    {
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - START" ));
-
-    const TInt count = iFreeCells.Count();
-    const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 );
-    const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count
-                
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize ));
-	return r;
-    }
-
-
-
-void DMemSpyDriverLogChanHeapBase::ReleaseFreeCells()
-    {
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - START - this: 0x%08x", this ));
-
-    // Housekeeping
-    NKern::ThreadEnterCS();
-    iFreeCells.Reset();
-    //
-    iStackStream = NULL;
-    //
-    delete iHeapStream;
-    iHeapStream = NULL;
-    NKern::ThreadLeaveCS();
-
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - END - this: 0x%08x", this ));
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+	{
+	iFreeCellCount = 0;
+	}
 
 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName )
     {
@@ -905,7 +490,7 @@
         // Finalise construction of heap 
         if  ( kernelHeap != NULL )
             {
-            //TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeap->Base(): 0x%08x, kernelHeapChunk->Base(): 0x%08x", kernelHeap->Base(), kernelHeapChunk->Base() ) );
+            TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeapChunk->Base(): 0x%08x", kernelHeapChunk->Base() ) );
             aHeap = kernelHeap;
             aChunk = kernelHeapChunk;
 
@@ -935,27 +520,6 @@
     return r;
     }
 
-
-TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelInPlace& aHeap, TDes8* aClientHeapChunkName )
-    {
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - START") );
-
-    RHeapK* heap = NULL;
-    DChunk* chunk = NULL;
-    TInt r = OpenKernelHeap( heap, chunk, aClientHeapChunkName );
-	
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - open err: %d", r ) );
-    if  ( r == KErrNone )
-        {
-        aHeap.SetKernelHeap( *heap );
-        aHeap.AssociateWithKernelChunk( chunk, TLinAddr( chunk->iBase ), 0 );
-        }
-
-	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - END - ret: %d", r ) );
-    return r;
-    }
-
-
 TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName )
     {
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - START") );
@@ -1017,7 +581,7 @@
                 NKern::LockSystem();
                 const TUint32 copyLength = heapSize; // TODO Min( heap->Size(), heapSize );
 
-                //TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - trying to copy %d (vs orig estimate of %d) bytes from kernel allocator address: 0x%08x", copyLength, heapSize, heap->Base() ));
+                TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - trying to copy %d (vs orig estimate of %d) bytes from kernel allocator address: 0x%08x", copyLength, heapSize, heap));
                 memcpy( (TUint8*) heapCopyChunkAddress, heap, copyLength );
 
                 NKern::UnlockSystem();
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapData.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapData.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -162,24 +162,20 @@
     //
     // The driver leaves kernel context with the copy of the kernel heap still associated with MemSpy's process.
     // The second driver call will copy the chunk data to user side and release the kernel side chunk.
-    const TBool isInit = iKernelHeap.ChunkIsInitialised();
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - START - isInit: %d", isInit ));
-    __ASSERT_ALWAYS( !isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataInitError ) );
+    //const TBool isInit = iKernelHeap.ChunkIsInitialised();
+    //TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - START - isInit: %d", isInit ));
+    //__ASSERT_ALWAYS( !isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataInitError ) );
 
     iKernelHeap.Reset();
     NKern::ThreadEnterCS();
 
-    // We must identify if we have a debug kernel allocator
-    const TBool debugAllocator = IsDebugKernel();
-    TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - debugAllocator: %d", debugAllocator ) );
-
     TFullName heapChunkName;
     TInt r = OpenKernelHeap( iKernelHeap, &heapChunkName );
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - open err: %d", r));
 
     if  ( r == KErrNone )
         {
-        r = GetHeapInfoKernel( iKernelHeap, debugAllocator, heapChunkName, aInfo, aFreeCells );
+        r = GetHeapInfoKernel( iKernelHeap, aInfo, aFreeCells );
         TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - base class get heap info: %d", r) );
 
         // If everything was okay, we can now return back to user-side, indicating the amount of heap data
@@ -190,10 +186,10 @@
             r = OSAdaption().DChunk().GetSize( iKernelHeap.Chunk() );
             TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - user side buffer needs to be: %d", r) );
             }
-        else if ( iKernelHeap.ChunkIsInitialised() )
+        else
             {
             // Error scenario - must close heap
-            iKernelHeap.DisassociateWithKernelChunk();
+            iKernelHeap.Close();
             }
         }
 
@@ -206,12 +202,15 @@
 
 TInt DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch( TDes8* aSink )
     {
+	//TOMSCI TODO this function is fundamentally flawed
+	return KErrNotSupported;
+	/*
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - START"));
 
     NKern::ThreadEnterCS();
 
     // We should already have an initialised copy of the kernel heap
-    const TBool isInit = iKernelHeap.ChunkIsInitialised();
+    const TBool isInit = iKernelHeap.Helper() != NULL;
     TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - isInit: %d", isInit ));
     __ASSERT_ALWAYS( isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataFetchError ) );
 
@@ -261,6 +260,7 @@
 
 	TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - END - ret: %d", r));
     return r;
+	*/
     }
 
 
@@ -279,7 +279,7 @@
 
 
 
-
+const TInt KPageSize = 4096;
 
 TInt DMemSpyDriverLogChanHeapData::GetHeapDataUser( TMemSpyDriverInternalHeapDataParams& aParams )
     {
@@ -304,135 +304,110 @@
 		    return KErrAccessDenied;
             }
         }
-    
+
     // Check that the process' thread's are suspended
     DThread* thread = (DThread*) TempObject();
     if  ( SuspensionManager().IsSuspended( *thread ) )
         {
-        // Find the chunk with the correct handle
+        // Open the heap
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - thread: %O", thread) );
         RMemSpyDriverRHeapUser heap( OSAdaption() );
-        const TBool allocatorIsReallyRHeap = GetUserHeapHandle( *thread, heap, aParams.iRHeapVTable );
-        if  ( allocatorIsReallyRHeap )
+		r = heap.OpenUserHeap(*thread, aParams.iDebugAllocator);
+		TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - opening heap returned: %d", r) );
+        if  (r == KErrNone)
             {
-            const TInt chunkHandle = heap.iChunkHandle;
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkHandle: 0x%08x, thread: %O", chunkHandle, thread) );
-
-  	        NKern::ThreadEnterCS();
- 	        NKern::LockSystem();
-            DChunk* chunk = (DChunk*) Kern::ObjectFromHandle( thread, chunkHandle, EChunk );
-            NKern::UnlockSystem();
-	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunk: 0x%08x", chunk ) );
-  	        NKern::ThreadLeaveCS();
-
-            if  ( chunk != NULL )
+            if  ( aParams.iChecksum != 0 )
                 {
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", chunk->iBase, chunk->iSize, chunk->iMaxSize, chunk) );
-
-                // If the client specified a checksum value, then we must walk the heap just to make sure
-                // it hasn't changed. Expensive operation, but good for paranoia purposes...
-                if  ( aParams.iChecksum != 0 )
-                    {
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - checksum validation requested - expecting: 0x%08x", aParams.iChecksum ) );
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - checksum validation requested - expecting: 0x%08x", aParams.iChecksum ) );
+                RMemSpyDriverHeapWalker heapWalker(heap);
+                
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - starting traversal..." ));
+#if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) )
+                heapWalker.SetPrintDebug();
+#endif
+                r = heapWalker.Traverse();
+                const TUint32 calculatedChecksum = heapWalker.Stats().iFreeCellCRC;
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - finished traversal - err: %d, checksum: 0x%08x", r, calculatedChecksum ));
 
-                    RMemSpyDriverRHeapUser rHeap( OSAdaption() );
-                    DChunk* userHeapChunk = NULL;
-                    r = OpenUserHeap( *thread, aParams.iRHeapVTable, rHeap, userHeapChunk );
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - opening client heap returned: %d", r) );
-                    if  ( r == KErrNone )
-                        {
-                        TMemSpyHeapWalkerNullObserver observer; 
-                        RMemSpyDriverHeapWalker heapWalker( rHeap, aParams.iDebugAllocator );
-                        heapWalker.SetObserver( &observer );
-                        
-                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - starting traversal..." ));
-#if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) )
-                        heapWalker.SetPrintDebug();
-#endif
-                        r = heapWalker.Traverse();
-                        const TUint32 calculatedChecksum = heapWalker.Stats().iFreeCellCRC;
-                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - finished traversal - err: %d, checksum: 0x%08x", r, calculatedChecksum ));
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x", calculatedChecksum, aParams.iChecksum ));
+                if  ( calculatedChecksum != aParams.iChecksum )
+                    {
+                    Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x for thread %O", calculatedChecksum, aParams.iChecksum, thread );
+                    r = KErrCorrupt;
+                    }
+                }
 
-                        // Release resources
-                        rHeap.DisassociateWithKernelChunk();
+            // Get user side (MemSpy) descriptor length info
+            if  ( r == KErrNone )
+                {
+                TInt destLen = 0;
+                TInt destMax = 0;
+                TUint8* destPtr = NULL;
+                r = Kern::ThreadGetDesInfo( &ClientThread(), aParams.iDes, destLen, destMax, destPtr, ETrue );
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", aParams.iDes, destPtr, destLen, destMax, r ));
+				destMax = destMax & ~(KPageSize-1); // Round down dest max to page size
+				if (destMax <= 0 || (aParams.iReadAddress & (KPageSize-1))) r = KErrArgument; // If destMax is less than a page or the read address isn't a multiple of page size then we don't want to know
 
-                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x", calculatedChecksum, aParams.iChecksum ));
-                        if  ( calculatedChecksum != aParams.iChecksum )
-                            {
-                            Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x for thread %O", calculatedChecksum, aParams.iChecksum, thread );
-                            r = KErrCorrupt;
-                            }
-                        }
-                    else
-                        {
-                        // Couldn't verify checksum in this situation...
-                        }
-                    }
-
-                // Get user side (MemSpy) descriptor length info
                 if  ( r == KErrNone )
                     {
-                    TInt destLen;
-                    TInt destMax;
-                    TUint8* destPtr = NULL;
-                    r = Kern::ThreadGetDesInfo( &ClientThread(), aParams.iDes, destLen, destMax, destPtr, ETrue );
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", aParams.iDes, destPtr, destLen, destMax, r ));
-
-                    if  ( r == KErrNone )
+					const TLinAddr chunkBase = (TLinAddr)OSAdaption().DChunk().GetBase(heap.Chunk());
+					const TLinAddr chunkMaxAddr = chunkBase + OSAdaption().DChunk().GetMaxSize(heap.Chunk());
+        	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkBase:    0x%08x", chunkBase) );
+        
+					TLinAddr readAddress = aParams.iReadAddress;
+                    if (aParams.iRemaining < 0 )
                         {
-                        // Calculate start of real heap data (skipping over embedded RHeap object)
-                        const TUint8* startOfHeapOffset = heap.iBase;
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - startOfHeapOffset:    0x%08x", startOfHeapOffset) );
-            
-                        // Deal with initial case
-                        const TUint heapSize = heap.Size();
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - heapSize:               %8d", heapSize) );
-                        if  ( aParams.iRemaining < 0 )
-                            {
-                            // Initial case, remaining initialised to -1
-                            aParams.iRemaining = heapSize;
-                            }
+                        // Initial case, start from the bottom
+                        readAddress = chunkBase;
+						aParams.iRemaining = heap.Helper()->CommittedSize();
+                        }
+
+                    // The remaining number of bytes should allow us to calculate the position
+                    // to read from.
+                    TInt amountToRead = Min( aParams.iRemaining, destMax );
+        	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - amountToRead:           %8d", amountToRead) );
+        
+                    // Do the read from the heap we are spying on into MemSpy's address space
+					// TomS: I didn't know you could do this - you live and learn
+					do
+						{
+						r = Kern::ThreadRawRead( thread, (const void*)readAddress, destPtr, amountToRead );
+        				TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - read result: %d", r) );
 
-                        // The remaining number of bytes should allow us to calculate the position
-                        // to read from.
-                        const TInt amountToRead = Min( aParams.iRemaining, destMax );
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - amountToRead:           %8d", amountToRead) );
-                        const TInt readOffset = ( heapSize - aParams.iRemaining );
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - readOffset:             %8d", readOffset) );
-                        const TAny* readAddress = startOfHeapOffset + readOffset;
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - readAddress:          0x%08x", readAddress) );
-            
-                        // Do the read from the heap we are spying on into MemSpy's address space
-                        r = Kern::ThreadRawRead( thread, readAddress, destPtr, amountToRead );
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - read result: %d", r) );
-                        //
-                        if  (r == KErrNone)
-                            {
-                            // Client takes care of updating descriptor length.
-                            r = amountToRead;
-                            }
-                        else if ( r == KErrBadDescriptor )
-                            {
-                            MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
-                            }
-            
-                        // Update remaining bytes
-                        aParams.iRemaining -= amountToRead;
-                        aParams.iReadAddress = (TUint) readAddress;
+						if (r == KErrBadDescriptor)
+							{
+							// This is not necessarily an error - it could be we've hit an unmapped page
+							if (amountToRead > KPageSize)
+								{
+								// retry reading a single page instead
+								amountToRead = KPageSize;
+								}
+							else
+								{
+								// Try the next page
+								readAddress += KPageSize;
+								}
+							}
+						} while (r == KErrBadDescriptor && readAddress < chunkMaxAddr);
+                    //
+                    if  (r == KErrNone)
+                        {
+                        // Client takes care of updating descriptor length.
+                        r = amountToRead;
                         }
+        
+                    // Update remaining bytes
+                    aParams.iRemaining -= amountToRead;
+                    aParams.iReadAddress = readAddress;
                     }
                 }
-            else
-                {
-    	        Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunk not found! thread: %O", thread );
-                r = KErrNotFound;
-                }
-            }
+			}
         else
             {
-    	    Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - couldnt find heap - vtable mis-match? thread: %O", thread );
+    	    Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - couldnt open heap for thread %O, err=%d", thread, r);
             r = KErrNotSupported;
             }
+		heap.Close();
         }
     else
         {
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -46,24 +46,18 @@
 DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo()
 	{
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - START - this: 0x%08x", this ));
+	ReleaseCellList();
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - END - this: 0x%08x", this ));
 	}
 
-
-
-
-
-
-
-
 TInt DMemSpyDriverLogChanHeapInfo::Request( TInt aFunction, TAny* a1, TAny* a2 )
 	{
 	TInt r = DMemSpyDriverLogChanHeapBase::Request( aFunction, a1, a2 );
     if  ( r == KErrNone )
         {
-        if  ( aFunction != EMemSpyDriverOpCodeHeapInfoFetchFreeCells )
+        if  ( aFunction != EMemSpyDriverOpCodeHeapInfoFetchCellList )
             {
-            ReleaseFreeCells();
+            ReleaseCellList();
             }
         //
         switch( aFunction )
@@ -75,10 +69,10 @@
             r = GetHeapInfoKernel( (TMemSpyDriverInternalHeapRequestParameters*) a1, (TDes8*) a2 );
             break;
         case EMemSpyDriverOpCodeHeapInfoGetIsDebugKernel:
-            r = GetIsDebugKernel( (TBool*) a1 );
+            r = GetIsDebugKernel(a1);
             break;
-        case EMemSpyDriverOpCodeHeapInfoFetchFreeCells:
-            r = FetchFreeCells( (TDes8*) a1 );
+        case EMemSpyDriverOpCodeHeapInfoFetchCellList:
+            r = FetchCellList( (TDes8*) a1 );
             break;
 
         default:
@@ -132,50 +126,42 @@
             DThread* thread = (DThread*) TempObject();
             if  ( SuspensionManager().IsSuspended( *thread ) )
                 {
-                TFullName chunkName;
-
                 // Open client's heap
                 RMemSpyDriverRHeapUser rHeap( OSAdaption() );
-                DChunk* userHeapChunk = NULL;
-                r = OpenUserHeap( *thread, iHeapInfoParams.iRHeapVTable, rHeap, userHeapChunk, &chunkName );
+				r = rHeap.OpenUserHeap(*thread, iHeapInfoParams.iDebugAllocator);
                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - opening client heap returned: %d", r) );
 
                 if  ( r == KErrNone )
                     {
                     // This object holds all of the info we will accumulate for the client.
                     TMemSpyHeapInfo masterHeapInfo;
-                    masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap );
+                    masterHeapInfo.SetType(rHeap.GetTypeFromHelper());
                     masterHeapInfo.SetTid( iHeapInfoParams.iTid );
                     masterHeapInfo.SetPid( OSAdaption().DThread().GetOwningProcessId( *thread ) );
 
                     // This is the RHeap-specific object that contains all RHeap info
                     TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap();
 
-                    // This is the object data for the RHeap instance
-                    TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
-                    rHeap.CopyObjectDataTo( rHeapObjectData );
 
                     // We must walk the client's heap in order to build statistics
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - calling heap walker constructor..."));
-                    TMemSpyHeapWalkerNullObserver observer; 
-                    RMemSpyDriverHeapWalker heapWalker( rHeap, iHeapInfoParams.iDebugAllocator );
-                    if  ( iHeapInfoParams.iBuildFreeCellList )
+					RMemSpyDriverHeapWalker heapWalker(rHeap);
+                    if  (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList)
                         {
                         heapWalker.SetObserver( this );
-                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - collecting free cells"));
+                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - collecting cells"));
                         }
                     else
                         {
-                        heapWalker.SetObserver( &observer );
-                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - not collecting free cells"));
+                        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - not collecting cells"));
                         }
 
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - starting traversal..." ));
+                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - starting traversal openerr: %d...", r));
 
 #if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) )
                     heapWalker.SetPrintDebug();
 #endif
-                    r = heapWalker.Traverse();
+                    if (r == KErrNone) r = heapWalker.Traverse();
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - finished traversal - err: %d", r ));
 
                     TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
@@ -183,24 +169,26 @@
 
                     // Get remaining meta data that isn't stored elsewhere
                     TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
-                    rHeapMetaData.SetChunkName( chunkName );
-                    rHeapMetaData.SetChunkSize( (TUint) OSAdaption().DChunk().GetSize( *userHeapChunk ) );
-                    rHeapMetaData.SetChunkHandle( userHeapChunk );
-                    rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase( *userHeapChunk ) );
-                    rHeapMetaData.SetDebugAllocator( iHeapInfoParams.iDebugAllocator );
-                    rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() );
-                    rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iHeapInfoParams.iDebugAllocator ) );
+					DChunk& userHeapChunk = rHeap.Chunk();
+					TFullName chunkName;
+					userHeapChunk.FullName(chunkName);
+					rHeapMetaData.SetChunkName( chunkName );
+		            rHeapMetaData.SetChunkSize( (TUint) OSAdaption().DChunk().GetSize( userHeapChunk ) );
+					rHeapMetaData.SetChunkHandle( &userHeapChunk );
+					rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase( userHeapChunk ) );
+                    rHeapMetaData.SetDebugAllocator(rHeap.Helper()->AllocatorIsUdeb());
                     rHeapMetaData.SetUserThread( ETrue );
-
-                    // Get any heap-specific info
-                    rHeap.GetHeapSpecificInfo( masterHeapInfo );
+					rHeapMetaData.iHeapSize = rHeap.Helper()->CommittedSize();
+					rHeapMetaData.iAllocatorAddress = (TAny*)rHeap.Helper()->AllocatorAddress();
+					rHeapMetaData.iMinHeapSize = rHeap.Helper()->MinCommittedSize();
+					rHeapMetaData.iMaxHeapSize = rHeap.Helper()->MaxCommittedSize();
 
                     PrintHeapInfo( masterHeapInfo );
 
                     // Write free cells if requested
-                    if  ( r == KErrNone && iHeapInfoParams.iBuildFreeCellList )
+                    if  ( r == KErrNone && (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList))
                         {
-                        r = PrepareFreeCellTransferBuffer();
+                        r = PrepareCellListTransferBuffer();
                         }
 
                     // Update info ready for writing back to the user-side
@@ -217,7 +205,7 @@
                         }
 
                     // Release resources
-                    rHeap.DisassociateWithKernelChunk();
+					rHeap.Close();
                     }
                 }
             else
@@ -249,18 +237,13 @@
     if  ( r == KErrNone )
         {
         // Open kernel heap
-        TFullName heapChunkName;
         RMemSpyDriverRHeapKernelInPlace rHeap;
-        r = OpenKernelHeap( rHeap, &heapChunkName );
+        r = rHeap.OpenKernelHeap();
         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - open err: %d", r ) );
 
         if  ( r == KErrNone )
             {
-            // We must identify if we have a debug kernel allocator
-            const TBool debugAllocator = IsDebugKernel( rHeap );
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - debugAllocator: %d", debugAllocator ) );
-
-            r = DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( rHeap, debugAllocator, heapChunkName, params.iMasterInfo, aTransferBuffer );
+            r = DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(rHeap, params.iMasterInfo, aTransferBuffer);
             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - base class get heap info: %d", r) );
             }
         }
@@ -278,7 +261,7 @@
 
 
 
-TInt DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel( TBool* aIsDebugKernel )
+TInt DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel(TAny* aResult)
     {
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - START") );
     
@@ -288,22 +271,22 @@
     NKern::ThreadEnterCS();
     
     RMemSpyDriverRHeapKernelInPlace rHeap;
-    r = OpenKernelHeap( rHeap );
+    r = rHeap.OpenKernelHeap();
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - open kernel heap returned: %d", r) );
 
     if  ( r == KErrNone )
         {
-        debugKernel = IsDebugKernel( rHeap );
+        debugKernel = rHeap.Helper()->AllocatorIsUdeb();
 
         // Tidy up
-        rHeap.DisassociateWithKernelChunk();
+        rHeap.Close();
         }
 
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - debugKernel: %d", debugKernel) );
 
     // Write back to user-land
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - writing to user-side...") );
-    r = Kern::ThreadRawWrite( &ClientThread(), aIsDebugKernel, &debugKernel, sizeof(TBool) );
+    r = Kern::ThreadRawWrite( &ClientThread(), aResult, &debugKernel, sizeof(TBool) );
 
     NKern::ThreadLeaveCS();
 
@@ -311,39 +294,120 @@
     return r;
     }
 
-
-
+TInt DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer()
+    {
+    // Transfer free cells immediately from xfer stream
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream ));
+    __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) );
+    //
+    TInt r = KErrNoMemory;
+    //
+    NKern::ThreadEnterCS();
+    //
+    iHeapStream = new RMemSpyMemStreamWriter();
+    if  ( iHeapStream )
+        {
+        const TInt requiredMemory = CalculateCellListBufferSize();
+        r = OpenXferStream( *iHeapStream, requiredMemory );
+        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r ));
 
-
+        if  ( r == KErrNone )
+            {
+            const TInt count = iCellList.Count();
+            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - cell count: %d", count ));
+            //
+            iHeapStream->WriteInt32( count );
+            for( TInt i=0; i<count; i++ )
+                {
+                const TMemSpyDriverCell& cell = iCellList[ i ];
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - storing entry: %d", i ));
+                //
+                iHeapStream->WriteInt32( cell.iType );
+                iHeapStream->WriteUint32( reinterpret_cast<TUint32>( cell.iAddress ) );
+                iHeapStream->WriteInt32( cell.iLength );
+                }
 
+            // Finished with the array now
+            iCellList.Reset();
 
+            // We return the amount of client-side memory that needs to be allocated to hold the buffer
+            r = requiredMemory;
+            }
+        }
+    //
+    NKern::ThreadLeaveCS();
+               
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - END - r: %d", r));
+	return r;
+    }
 
 
-
+TInt DMemSpyDriverLogChanHeapInfo::FetchCellList( TDes8* aBufferSink )
+    {
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::FetchCellList() - START - iHeapStream: 0x%08x", iHeapStream ));
+    __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) );
 
-
+    TInt r = KErrNone;
 
-
+    // Write buffer to client
+    NKern::ThreadEnterCS();
+    r = iHeapStream->WriteAndClose( aBufferSink );
 
+    // Tidy up
+    ReleaseCellList();
 
+    NKern::ThreadLeaveCS();
+    //
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::FetchCellList() - END - r: %d", r));
+	return r;
+    }
 
 
 
-
-
+TInt DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() const
+    {
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() - START" ));
 
-
-
-
+    const TInt count = iCellList.Count();
+    const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 );
+    const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count
+                
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize ));
+	return r;
+    }
 
 
 
-
+void DMemSpyDriverLogChanHeapInfo::ReleaseCellList()
+    {
+	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::ReleaseCellList() - START - this: 0x%08x", this ));
 
+    NKern::ThreadEnterCS();
+    iCellList.Reset();
+    delete iHeapStream;
+    iHeapStream = NULL;
+    NKern::ThreadLeaveCS();
 
-
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::ReleaseCellList() - END - this: 0x%08x", this ));
+    }
 
-
+TBool DMemSpyDriverLogChanHeapInfo::HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/)
+    {
+	TInt err = KErrNone;
+    if (((aCellType & EMemSpyDriverFreeCellMask) && iHeapInfoParams.iBuildFreeCellList) || ((aCellType & EMemSpyDriverAllocatedCellMask) && iHeapInfoParams.iBuildAllocCellList))
+		{
+		TMemSpyDriverCell cell;
+		cell.iType = aCellType;
+		cell.iAddress = aCellAddress;
+		cell.iLength = aLength;
 
+		NKern::ThreadEnterCS();
+		err = iCellList.Append(cell);
+		NKern::ThreadLeaveCS();
+		}
+	return err == KErrNone;
+	}
 
-
+void DMemSpyDriverLogChanHeapInfo::HandleHeapWalkInit()
+	{
+	}
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -124,7 +124,7 @@
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams )
     {
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START"));
-    __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) );
+    __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) );
 
     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) );
     if  ( r == KErrNone )
@@ -141,8 +141,8 @@
                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread: %O", thread));
 
                 // Open client's heap
-                DChunk* userHeapChunk = NULL;
-                r = OpenUserHeap( *thread, iHeapWalkInitialParameters.iRHeapVTable, iWalkHeap, userHeapChunk );
+                r = iWalkHeap.OpenUserHeap(*thread, iHeapWalkInitialParameters.iDebugAllocator);
+
                 TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - opening client heap returned: %d", r) );
 
                 if  ( r == KErrNone )
@@ -154,7 +154,7 @@
 
                     // Walk the client's heap
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - calling heap walker constructor..."));
-                    RMemSpyDriverHeapWalker heapWalker( iWalkHeap, iHeapWalkInitialParameters.iDebugAllocator );
+                    RMemSpyDriverHeapWalker heapWalker(iWalkHeap);
                     
                     TMemSpyDriverLogChanHeapWalkObserver observer( *this );
                     heapWalker.SetObserver( &observer );
@@ -169,7 +169,7 @@
                 if  ( r < KErrNone )
                     {
                     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - error scenario - releasing kernel heap chunk copy" ));
-                    iWalkHeap.DisassociateWithKernelChunk();
+                    iWalkHeap.Close();
                     }
                 }
             else
@@ -199,7 +199,7 @@
     {
     const TInt walkedHeapCellCount = iWalkHeapCells.Count();
 	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount));
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
 
     // Open the original thread
 	TInt r = OpenTempObject( aTid, EThread );
@@ -257,12 +257,7 @@
         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - heap walk was still open..."));
       	NKern::ThreadEnterCS();
 
-        if  ( iWalkHeap.ChunkIsInitialised() )
-            {
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - removing chunk (%O) from process", &iWalkHeap.Chunk() ) );
-            iWalkHeap.DisassociateWithKernelChunk();
-            iWalkHeap.Reset();
-            }
+		iWalkHeap.Close();
 
         // Discard handled cells
         iWalkHeapCells.Reset();
@@ -279,10 +274,9 @@
 
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams)
     {
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
     //
-    const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator;
-	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser));
+	TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
     //
 	TMemSpyDriverInternalWalkHeapCellDataReadParams params;
     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) );
@@ -306,92 +300,58 @@
             {
             // Check we can find the cell in the cell list...
             const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress );
-            if  ( cell == NULL )
-                {
-                // Maybe the client tried the base address of the cell data.
-                // try to take the header into account and retry.
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - didnt find matching cell for address: 0x%08x... trying address minus allocatedCellHeaderSize", params.iCellAddress ));
-
-                const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser );
-        
-                TUint32 addr = (TUint32) params.iCellAddress;
-                addr -= cellHeaderSize;
-                params.iCellAddress = (TAny*) addr;
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - new address: 0x%08x", params.iCellAddress ));
-        
-                // Last try
-                cell = CellInfoForSpecificAddress( params.iCellAddress );
-                }
 
             TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress ));
 
             if  ( cell )
                 {
-                const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength );
-                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - isValidCell: %d", isValidCell ));
-        
-                if  ( isValidCell )
+                const TInt cellLen = cell->iLength;
+                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen ));
+
+                if  ( params.iReadLen <= cellLen )
                     {
-                    // Check the length request is valid
-                    const TInt cellLen = cell->iLength;
-                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen ));
+
+                    // Get user side descriptor length info
+         	        TInt destLen = 0;
+        	        TInt destMax = 0;
+                    TUint8* destPtr = NULL;
 
-                    if  ( params.iReadLen <= cellLen )
+                    r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue );
+        	        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
+
+                    // Work out the start offset for the data...
+                    if  ( r == KErrNone && destMax >= params.iReadLen )
                         {
-                        const TInt cellHeaderSize = RMemSpyDriverRHeapBase::CellHeaderSize( *cell, debugEUser );
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellHeaderSize: %8d", cellHeaderSize ));
+                        const TAny* srcPos = ((TUint8*) cell->iCellAddress);
+        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos ));
 
-                        // Get user side descriptor length info
-         	            TInt destLen = 0;
-        	            TInt destMax = 0;
-                        TUint8* destPtr = NULL;
+                        // Read some data 
+                        r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen );
+    	                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r));
 
-                        r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue );
-        	            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r ));
-
-                        // Work out the start offset for the data...
-                        if  ( r == KErrNone && destMax >= params.iReadLen )
+                        if  ( r == KErrNone )
                             {
-                            const TAny* srcPos = ((TUint8*) cell->iCellAddress) + cellHeaderSize;
-        	                TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos ));
-
-                            // Read some data 
-                            r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen );
-    	                    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r));
-
-                            if  ( r == KErrNone )
-                                {
-                                // Client will update descriptor length in this situation.
-                                r = params.iReadLen;
-                                }
-                            else if ( r == KErrBadDescriptor )
-                                {
-                                MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
-                                }
-                            }
-                        else
-                            {
-                            if  ( r != KErrBadDescriptor )
-                                {
-                                r = KErrArgument;                
-            	                Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" );
-                                }
-                            else
-                                {
-            	                Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" );
-                                }
+                            // Client will update descriptor length in this situation.
+                            r = params.iReadLen;
                             }
                         }
                     else
                         {
-                        r = KErrArgument;
-        	            Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length");
+                        if  ( r != KErrBadDescriptor )
+                            {
+                            r = KErrArgument;                
+            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" );
+                            }
+                        else
+                            {
+            	            Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" );
+                            }
                         }
                     }
                 else
                     {
                     r = KErrArgument;
-                    Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - invalid cell address: 0x%08x", cell);
+        	        Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length");
                     }
                 }
             else
@@ -413,17 +373,16 @@
     	Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found");
 		}
     //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END"));
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r));
     return r;
     }
 
 
 TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams )
     {
-    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
+    __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) );
     //
-    const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator;
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser));
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable));
     TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress));
 
     // Open the original thread
@@ -450,16 +409,6 @@
     if  ( cell == NULL )
         {
         TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress));
-
-        // Maybe the client tried the base address of the cell data.
-        // try to take the header into account and retry.
-        const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser );
-        TUint32 addr = (TUint32) aCellAddress;
-        addr -= cellHeaderSize;
-        
-        TAny* cellByRawStartingAddress = (TAny*) addr;
-        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - trying to search by start of cell address: 0x%08x (cellHeaderSize: %d)", cellByRawStartingAddress, cellHeaderSize));
-        cell = CellInfoForSpecificAddress( cellByRawStartingAddress );
         
         // If the cell still wasn't found, then let's look for any heap cell that contains
         // the client-specified address (i.e. find the heap cell that contains the specified
@@ -473,18 +422,9 @@
 
     if  ( cell )
         {
-        const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength );
-        if  ( isValidCell )
-            {
-            // Have enough info to write back to client now
-            TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber ));
-            r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
-            }
-        else
-            {
-            r = KErrArgument;
-            Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - invalid cell address: 0x%08x", cell);
-            }
+        // Have enough info to write back to client now
+        TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber ));
+        r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) );
         }
     else
         {
@@ -494,7 +434,7 @@
     
     CloseTempObject();
     //
-    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END"));
+    TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r));
     return r;
     }
 
@@ -576,7 +516,7 @@
 
 
 
-TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
+TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
     {
     TInt error = KErrNone;
     //
--- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanMisc.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanMisc.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -171,7 +171,6 @@
 
         DObjectCon* container = Kern::Containers()[ EProcess ];
         container->Wait();
-        NKern::LockSystem();
 
         const TInt count = container->Count();
         for(TInt i=0; i<count; i++)
@@ -193,9 +192,7 @@
                 }
             }
 
-        NKern::UnlockSystem();
         container->Signal();
-
     	NKern::ThreadLeaveCS();
         }
 
--- a/memspy/Driver/Shared/MemSpyDriverObjectsInternal.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Shared/MemSpyDriverObjectsInternal.h	Thu Jul 22 16:50:07 2010 +0100
@@ -33,8 +33,7 @@
     {
 public:
     inline TMemSpyDriverInternalHeapRequestParameters()
-        : iTid( 0 ), iRHeapVTable( 0 ), iBuildFreeCellList( EFalse ), iDebugAllocator( EFalse ), 
-          iMasterInfo( NULL )
+        : iTid(0), iRHeapVTable(0), iBuildFreeCellList(EFalse), iBuildAllocCellList(EFalse), iDebugAllocator(EFalse), iMasterInfo(NULL)
         {
         }
 
@@ -42,6 +41,7 @@
     TUint iTid;
     TUint32 iRHeapVTable;
     TBool iBuildFreeCellList;
+	TBool iBuildAllocCellList;
 
 public: // Params IN or OUT (IN in User heap requests, OUT in Kernel heap requests)
     TBool iDebugAllocator;
--- a/memspy/Driver/Shared/MemSpyDriverOpCodes.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/Shared/MemSpyDriverOpCodes.h	Thu Jul 22 16:50:07 2010 +0100
@@ -56,7 +56,7 @@
 	EMemSpyDriverOpCodeHeapInfoGetUser,
 	EMemSpyDriverOpCodeHeapInfoGetKernel,
     EMemSpyDriverOpCodeHeapInfoGetIsDebugKernel,
-    EMemSpyDriverOpCodeHeapInfoFetchFreeCells,
+    EMemSpyDriverOpCodeHeapInfoFetchCellList,
     EMemSpyDriverOpCodeHeapInfoEnd,
 
     // HEAP DATA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Shared/heaputils.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,1678 @@
+// heaputils.cpp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+#ifdef TEST_HYBRIDHEAP_ASSERTS
+#define private public
+#include <e32def.h>
+#include "slab.h"
+#include "page_alloc.h"
+#include "heap_hybrid.h"
+#endif
+
+#include "heaputils.h"
+
+#ifdef __KERNEL_MODE__
+
+#include <kern_priv.h>
+#define MEM Kern
+__ASSERT_COMPILE(sizeof(LtkUtils::RKernelSideAllocatorHelper) == 10*4);
+#define KERN_ENTER_CS() NKern::ThreadEnterCS()
+#define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
+#define LOG(args...)
+#define HUEXPORT_C
+#else
+
+#include <e32std.h>
+#define MEM User
+#define KERN_ENTER_CS()
+#define KERN_LEAVE_CS()
+//#include <e32debug.h>
+//#define LOG(args...) RDebug::Printf(args)
+#define LOG(args...)
+
+#ifdef STANDALONE_ALLOCHELPER
+#define HUEXPORT_C
+#else
+#define HUEXPORT_C EXPORT_C
+#endif
+
+#endif // __KERNEL_MODE__
+
+using LtkUtils::RAllocatorHelper;
+const TUint KPageSize = 4096;
+__ASSERT_COMPILE(sizeof(RAllocatorHelper) == 9*4);
+
+// RAllocatorHelper
+
+HUEXPORT_C RAllocatorHelper::RAllocatorHelper()
+	: iAllocatorAddress(0), iAllocatorType(EUnknown), iInfo(NULL), iValidInfo(0), iTempSlabBitmap(NULL), iPageCache(NULL), iPageCacheAddr(0)
+#ifdef __KERNEL_MODE__
+	, iChunk(NULL)
+#endif
+	{
+	}
+
+namespace LtkUtils
+	{
+	class THeapInfo
+		{
+	public:
+		THeapInfo()
+			{
+			ClearStats();
+			}
+
+		void ClearStats()
+			{
+			memclr(this, sizeof(THeapInfo));
+			}
+
+		TInt iAllocatedSize; // number of bytes in allocated cells (excludes free cells, cell header overhead)
+		TInt iCommittedSize; // amount of memory actually committed (includes cell header overhead, gaps smaller than an MMU page)
+		TInt iAllocationCount; // number of allocations currently
+		TInt iMaxCommittedSize; // or thereabouts
+		TInt iMinCommittedSize;
+		TInt iUnusedPages;
+		TInt iCommittedFreeSpace;
+		// Heap-only stats
+		TInt iHeapFreeCellCount;
+		// Hybrid-only stats
+		TInt iDlaAllocsSize;
+		TInt iDlaAllocsCount;
+		TInt iDlaFreeSize;
+		TInt iDlaFreeCount;
+		TInt iSlabAllocsSize;
+		TInt iSlabAllocsCount;
+		TInt iPageAllocsSize;
+		TInt iPageAllocsCount;
+		TInt iSlabFreeCellSize;
+		TInt iSlabFreeCellCount;
+		TInt iSlabFreeSlabSize;
+		TInt iSlabFreeSlabCount;
+		};
+	}
+
+const TInt KTempBitmapSize = 256; // KMaxSlabPayload / mincellsize, technically. Close enough.
+
+#ifdef __KERNEL_MODE__
+
+TInt RAllocatorHelper::OpenKernelHeap()
+	{
+	_LIT(KName, "SvHeap");
+	NKern::ThreadEnterCS();
+	DObjectCon* chunkContainer = Kern::Containers()[EChunk];
+	chunkContainer->Wait();
+	const TInt chunkCount = chunkContainer->Count();
+	DChunk* foundChunk = NULL;
+	for(TInt i=0; i<chunkCount; i++)
+		{
+		DChunk* chunk = (DChunk*)(*chunkContainer)[i];
+		if (chunk->NameBuf() && chunk->NameBuf()->Find(KName) != KErrNotFound)
+			{
+			// Found it. No need to open it, we can be fairly confident the kernel heap isn't going to disappear from under us
+			foundChunk = chunk;
+			break;
+			}
+		}
+	iChunk = foundChunk;
+    chunkContainer->Signal();
+#ifdef __WINS__
+	TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
+#else
+	// Copied from P::KernelInfo
+	const TRomHeader& romHdr=Epoc::RomHeader();
+	const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
+	const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
+	TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
+	TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
+	TInt err = OpenChunkHeap(heap, 0); // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
+
+#endif
+	if (!err) err = FinishConstruction();
+	NKern::ThreadLeaveCS();
+	return err;
+	}
+
+#else
+
+HUEXPORT_C TInt RAllocatorHelper::Open(RAllocator* aAllocator)
+	{
+	iAllocatorAddress = (TLinAddr)aAllocator;
+	TInt udeb = EuserIsUdeb();
+	if (udeb < 0) return udeb; // error
+
+	TInt err = IdentifyAllocatorType(udeb);
+	if (!err)
+		{
+		err = FinishConstruction(); // Allocate everything up front
+		}
+	if (!err)
+		{
+		// We always stealth our own allocations, again to avoid tripping up allocator checks
+		SetCellNestingLevel(iInfo, -1);
+		SetCellNestingLevel(iTempSlabBitmap, -1);
+		SetCellNestingLevel(iPageCache, -1);
+		}
+	return err;
+	}
+
+#endif
+
+TInt RAllocatorHelper::FinishConstruction()
+	{
+	TInt err = KErrNone;
+	KERN_ENTER_CS();
+	if (!iInfo)
+		{
+		iInfo = new THeapInfo;
+		if (!iInfo) err = KErrNoMemory;
+		}
+	if (!err && !iTempSlabBitmap)
+		{
+		iTempSlabBitmap = (TUint8*)MEM::Alloc(KTempBitmapSize);
+		if (!iTempSlabBitmap) err = KErrNoMemory;
+		}
+	if (!err && !iPageCache)
+		{
+		iPageCache = MEM::Alloc(KPageSize);
+		if (!iPageCache) err = KErrNoMemory;
+		}
+
+	if (err)
+		{
+		delete iInfo;
+		iInfo = NULL;
+		MEM::Free(iTempSlabBitmap);
+		iTempSlabBitmap = NULL;
+		MEM::Free(iPageCache);
+		iPageCache = NULL;
+		}
+	KERN_LEAVE_CS();
+	return err;
+	}
+
+TInt RAllocatorHelper::ReadWord(TLinAddr aLocation, TUint32& aResult) const
+	{
+	// Check if we can satisfy the read from the cache
+	if (aLocation >= iPageCacheAddr)
+		{
+		TUint offset = aLocation - iPageCacheAddr;
+		if (offset < KPageSize)
+			{
+			aResult = ((TUint32*)iPageCache)[offset >> 2];
+			return KErrNone;
+			}
+		}
+
+	// If we reach here, not in page cache. Try and read in the new page
+	if (iPageCache)
+		{
+		TLinAddr pageAddr = aLocation & ~(KPageSize-1);
+		TInt err = ReadData(pageAddr, iPageCache, KPageSize);
+		if (!err)
+			{
+			iPageCacheAddr = pageAddr;
+			aResult = ((TUint32*)iPageCache)[(aLocation - iPageCacheAddr) >> 2];
+			return KErrNone;
+			}
+		}
+
+	// All else fails, try just reading it uncached
+	return ReadData(aLocation, &aResult, sizeof(TUint32));
+	}
+
+TInt RAllocatorHelper::ReadByte(TLinAddr aLocation, TUint8& aResult) const
+	{
+	// Like ReadWord but 8-bit
+
+	// Check if we can satisfy the read from the cache
+	if (aLocation >= iPageCacheAddr)
+		{
+		TUint offset = aLocation - iPageCacheAddr;
+		if (offset < KPageSize)
+			{
+			aResult = ((TUint8*)iPageCache)[offset];
+			return KErrNone;
+			}
+		}
+
+	// If we reach here, not in page cache. Try and read in the new page
+	if (iPageCache)
+		{
+		TLinAddr pageAddr = aLocation & ~(KPageSize-1);
+		TInt err = ReadData(pageAddr, iPageCache, KPageSize);
+		if (!err)
+			{
+			iPageCacheAddr = pageAddr;
+			aResult = ((TUint8*)iPageCache)[(aLocation - iPageCacheAddr)];
+			return KErrNone;
+			}
+		}
+
+	// All else fails, try just reading it uncached
+	return ReadData(aLocation, &aResult, sizeof(TUint8));
+	}
+
+
+TInt RAllocatorHelper::WriteWord(TLinAddr aLocation, TUint32 aWord)
+	{
+	// Invalidate the page cache if necessary
+	if (aLocation >= iPageCacheAddr && aLocation - iPageCacheAddr < KPageSize)
+		{
+		iPageCacheAddr = 0;
+		}
+
+	return WriteData(aLocation, &aWord, sizeof(TUint32));
+	}
+
+TInt RAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
+	{
+	// RAllocatorHelper base class impl is for allocators in same address space, so just copy it
+	memcpy(aResult, (const TAny*)aLocation, aSize);
+	return KErrNone;
+	}
+
+TInt RAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
+	{
+	memcpy((TAny*)aLocation, aData, aSize);
+	return KErrNone;
+	}
+
+#ifdef __KERNEL_MODE__
+
+LtkUtils::RKernelSideAllocatorHelper::RKernelSideAllocatorHelper()
+	: iThread(NULL)
+	{}
+
+void LtkUtils::RKernelSideAllocatorHelper::Close()
+	{
+	NKern::ThreadEnterCS();
+	if (iThread)
+		{
+		iThread->Close(NULL);
+		}
+	iThread = NULL;
+	RAllocatorHelper::Close();
+	NKern::ThreadLeaveCS();
+	}
+
+TInt LtkUtils::RKernelSideAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
+	{
+	return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize);
+	}
+
+TInt LtkUtils::RKernelSideAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
+	{
+	return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize);
+	}
+
+TInt LtkUtils::RKernelSideAllocatorHelper::TryLock()
+	{
+	return KErrNotSupported;
+	}
+
+void LtkUtils::RKernelSideAllocatorHelper::TryUnlock()
+	{
+	// Not supported
+	}
+
+TInt LtkUtils::RKernelSideAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
+	{
+	NKern::ThreadEnterCS();
+	DObjectCon* threads = Kern::Containers()[EThread];
+	threads->Wait();
+	iThread = Kern::ThreadFromId(aThreadId);
+	if (iThread && iThread->Open() != KErrNone)
+		{
+		// Failed to open
+		iThread = NULL;
+		}
+	threads->Signal();
+	NKern::ThreadLeaveCS();
+	if (!iThread) return KErrNotFound;
+	iAllocatorAddress = aAllocatorAddress;
+	TInt err = IdentifyAllocatorType(aEuserIsUdeb);
+	if (err) Close();
+	return err;
+	}
+
+#endif // __KERNEL_MODE__
+
+TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
+	{
+	iAllocatorAddress = aChunkBase;
+#ifdef __KERNEL_MODE__
+	// Must be in CS
+	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
+	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
+#else
+	// Assumes the chunk isn't the kernel heap. It's not a good idea to try messing with the kernel heap from user side...
+	TInt udeb = EuserIsUdeb();
+	if (udeb < 0) return udeb; // error
+#endif
+
+	TInt err = IdentifyAllocatorType(udeb);
+	if (err == KErrNone && iAllocatorType == EAllocator)
+		{
+		// We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator*
+		err = KErrNotFound;
+		}
+	if (err)
+		{
+		TInt oldErr = err;
+		TAllocatorType oldType = iAllocatorType;
+		// Try middle of chunk, in case it's an RHybridHeap
+		iAllocatorAddress += aChunkMaxSize / 2;
+		err = IdentifyAllocatorType(udeb);
+		if (err || iAllocatorType == EAllocator)
+			{
+			// No better than before
+			iAllocatorAddress = aChunkBase;
+			iAllocatorType = oldType;
+			err = oldErr;
+			}
+		}
+#ifdef __KERNEL_MODE__
+	if (err == KErrNone)
+		{
+		// Now we know the allocator, we can figure out the udeb-ness
+		RAllocator* kernelAllocator = reinterpret_cast<RAllocator*>(iAllocatorAddress);
+		kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)9999, (TAny*)0); // Use an invalid fail reason - this should have no effect on the operation of the heap
+		TInt err = kernelAllocator->DebugFunction(7, NULL, NULL); // 7 is RAllocator::TAllocDebugOp::EGetFail
+		if (err == 9999)
+			{
+			// udeb new
+			udeb = ETrue;
+			}
+		else if (err == KErrNotSupported)
+			{
+			// Old heap - fall back to slightly nasty non-thread-safe method
+			kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::EFailNext, (TAny*)1);
+			TAny* res = Kern::Alloc(4);
+			if (res) udeb = ETrue;
+			Kern::Free(res);
+			}
+		else
+			{
+			// it's new urel
+			}
+
+		// Put everything back
+		kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::ENone, (TAny*)0);
+		// And update the type now we know the udeb-ness for certain
+		err = IdentifyAllocatorType(udeb);
+		}
+#endif
+	return err;
+	}
+
+
+// The guts of RAllocatorHelper
+
+enum TWhatToGet
+	{
+	ECommitted = 1,
+	EAllocated = 2,
+	ECount = 4,
+	EMaxSize = 8,
+	EUnusedPages = 16,
+	ECommittedFreeSpace = 32,
+	EMinSize = 64,
+	EHybridStats = 128,
+	};
+
+class RHackAllocator : public RAllocator
+	{
+public:
+	using RAllocator::iHandles;
+	using RAllocator::iTotalAllocSize;
+	using RAllocator::iCellCount;
+	};
+
+class RHackHeap : public RHeap
+	{
+public:
+	// Careful, only allowed to use things that are still in the new RHeap, and are still in the same place
+	using RHeap::iMaxLength;
+	using RHeap::iChunkHandle;
+	using RHeap::iLock;
+	using RHeap::iBase;
+	using RHeap::iAlign;
+	using RHeap::iTop;
+	};
+
+const TInt KChunkSizeOffset = 30*4;
+const TInt KPageMapOffset = 141*4;
+//const TInt KDlOnlyOffset = 33*4;
+const TInt KMallocStateOffset = 34*4;
+const TInt KMallocStateTopSizeOffset = 3*4;
+const TInt KMallocStateTopOffset = 5*4;
+const TInt KMallocStateSegOffset = 105*4;
+const TInt KUserHybridHeapSize = 186*4;
+const TInt KSparePageOffset = 167*4;
+const TInt KPartialPageOffset = 165*4;
+const TInt KFullSlabOffset = 166*4;
+const TInt KSlabAllocOffset = 172*4;
+const TInt KSlabParentOffset = 1*4;
+const TInt KSlabChild1Offset = 2*4;
+const TInt KSlabChild2Offset = 3*4;
+const TInt KSlabPayloadOffset = 4*4;
+const TInt KSlabsetSize = 4;
+
+#ifdef TEST_HYBRIDHEAP_ASSERTS
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iChunkSize) == KChunkSizeOffset);
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iPageMap) == KPageMapOffset);
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iGlobalMallocState) == KMallocStateOffset);
+__ASSERT_COMPILE(sizeof(malloc_state) == 107*4);
+__ASSERT_COMPILE(_FOFF(malloc_state, iTopSize) == KMallocStateTopSizeOffset);
+__ASSERT_COMPILE(_FOFF(malloc_state, iTop) == KMallocStateTopOffset);
+__ASSERT_COMPILE(_FOFF(malloc_state, iSeg) == KMallocStateSegOffset);
+__ASSERT_COMPILE(sizeof(RHybridHeap) == KUserHybridHeapSize);
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iSparePage) == KSparePageOffset);
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iPartialPage) == KPartialPageOffset);
+__ASSERT_COMPILE(_FOFF(RHybridHeap, iSlabAlloc) == KSlabAllocOffset);
+__ASSERT_COMPILE(_FOFF(slab, iParent) == KSlabParentOffset);
+__ASSERT_COMPILE(_FOFF(slab, iChild1) == KSlabChild1Offset);
+__ASSERT_COMPILE(_FOFF(slab, iChild2) == KSlabChild2Offset);
+__ASSERT_COMPILE(_FOFF(slab, iPayload) == KSlabPayloadOffset);
+__ASSERT_COMPILE(sizeof(slabset) == KSlabsetSize);
+#endif
+
+TInt RAllocatorHelper::TryLock()
+	{
+#ifdef __KERNEL_MODE__
+	NKern::ThreadEnterCS();
+	DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock));
+	if (m) Kern::MutexWait(*m);
+	return KErrNone;
+#else
+	if (iAllocatorType != EUnknown && iAllocatorType != EAllocator)
+		{
+		RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
+		lock.Wait();
+		return KErrNone;
+		}
+	return KErrNotSupported;
+#endif
+	}
+
+void RAllocatorHelper::TryUnlock()
+	{
+#ifdef __KERNEL_MODE__
+	DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock));
+	if (m) Kern::MutexSignal(*m);
+	NKern::ThreadLeaveCS();
+#else
+	if (iAllocatorType != EUnknown && iAllocatorType != EAllocator)
+		{
+		RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
+		lock.Signal();
+		}
+#endif
+	}
+
+HUEXPORT_C void RAllocatorHelper::Close()
+	{
+	KERN_ENTER_CS();
+	iAllocatorType = EUnknown;
+	iAllocatorAddress = 0;
+	delete iInfo;
+	iInfo = NULL;
+	iValidInfo = 0;
+	MEM::Free(iTempSlabBitmap);
+	iTempSlabBitmap = NULL;
+	MEM::Free(iPageCache);
+	iPageCache = NULL;
+	iPageCacheAddr = 0;
+	KERN_LEAVE_CS();
+	}
+
+TInt RAllocatorHelper::IdentifyAllocatorType(TBool aAllocatorIsUdeb)
+	{
+	iAllocatorType = EUnknown;
+
+	TUint32 handlesPtr = 0;
+	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iHandles), handlesPtr);
+
+	if (err) return err;
+	if (handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle) || handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iLock))
+		{
+		// It's an RHeap of some kind - I doubt any other RAllocator subclass will use iHandles in this way
+		TUint32 base = 0;
+		err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base);
+		if (err) return err;
+		TInt objsize = (TInt)base - (TInt)iAllocatorAddress;
+		if (objsize <= 32*4)
+			{
+			// Old RHeap
+			iAllocatorType = aAllocatorIsUdeb ? EUdebOldRHeap : EUrelOldRHeap;
+			}
+		else
+			{
+			// new hybrid heap - bigger than the old one. Likewise figure out if udeb or urel.
+			iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeap : EUrelHybridHeap;
+			}
+		}
+	else
+		{
+		iAllocatorType = EAllocator;
+		}
+	return KErrNone;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::SetCellNestingLevel(TAny* aCell, TInt aNestingLevel)
+	{
+	TInt err = KErrNone;
+
+	switch (iAllocatorType)
+		{
+		case EUdebOldRHeap:
+		case EUdebHybridHeap:
+			// By this reckoning, they're in the same place amazingly
+			{
+			TLinAddr nestingAddr = (TLinAddr)aCell - 8;
+			err = WriteWord(nestingAddr, aNestingLevel);
+			break;
+			}
+		default:
+			break;
+		}
+	return err;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel)
+	{
+	switch (iAllocatorType)
+		{
+		case EUdebOldRHeap:
+		case EUdebHybridHeap:
+			// By this reckoning, they're in the same place amazingly
+			{
+			TLinAddr nestingAddr = (TLinAddr)aCell - 8;
+			return ReadWord(nestingAddr, (TUint32&)aNestingLevel);
+			}
+		default:
+			return KErrNotSupported;
+		}
+	}
+
+TInt RAllocatorHelper::RefreshDetails(TUint aMask)
+	{
+	TInt err = FinishConstruction();
+	if (err) return err;
+
+	// Invalidate the page cache
+	iPageCacheAddr = 0;
+
+	TryLock();
+	err = DoRefreshDetails(aMask);
+	TryUnlock();
+	return err;
+	}
+
+const TInt KHeapWalkStatsForOldHeap = (EUnusedPages|ECommittedFreeSpace);
+const TInt KHeapWalkStatsForNewHeap = (EAllocated|ECount|EUnusedPages|ECommittedFreeSpace|EHybridStats);
+
+TInt RAllocatorHelper::DoRefreshDetails(TUint aMask)
+	{
+	TInt err = KErrNotSupported;
+	switch (iAllocatorType)
+		{
+		case EUrelOldRHeap:
+		case EUdebOldRHeap:
+			{
+			if (aMask & ECommitted)
+				{
+				// The old RHeap::Size() used to use iTop - iBase, which was effectively chunkSize - sizeof(RHeap)
+				// I think that for CommittedSize we should include the size of the heap object, just as it includes
+				// the size of heap cell metadata and overhead. Plus it makes sure the committedsize is a multiple of the page size
+				TUint32 top = 0;
+				//TUint32 base = 0;
+				//err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base);
+				//if (err) return err;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top);
+				if (err) return err;
+
+				//iInfo->iCommittedSize = top - base;
+				iInfo->iCommittedSize = top - iAllocatorAddress;
+				iValidInfo |= ECommitted;
+				}
+			if (aMask & EAllocated)
+				{
+				TUint32 allocSize = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), allocSize);
+				if (err) return err;
+				iInfo->iAllocatedSize = allocSize;
+				iValidInfo |= EAllocated;
+				}
+			if (aMask & ECount)
+				{
+				TUint32 count = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), count);
+				if (err) return err;
+				iInfo->iAllocationCount = count;
+				iValidInfo |= ECount;
+				}
+			if (aMask & EMaxSize)
+				{
+				TUint32 maxlen = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
+				if (err) return err;
+				iInfo->iMaxCommittedSize = maxlen;
+				iValidInfo |= EMaxSize;
+				}
+			if (aMask & EMinSize)
+				{
+				TUint32 minlen = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength) - 4, minlen); // This isn't a typo! iMinLength is 4 bytes before iMaxLength, on old heap ONLY
+				if (err) return err;
+				iInfo->iMinCommittedSize = minlen;
+				iValidInfo |= EMinSize;
+				}
+			if (aMask & KHeapWalkStatsForOldHeap)
+				{
+				// Need a heap walk
+				iInfo->ClearStats();
+				iValidInfo = 0;
+				err = DoWalk(&WalkForStats, NULL);
+				if (err == KErrNone) iValidInfo |= KHeapWalkStatsForOldHeap;
+				}
+			return err;
+			}
+		case EUrelHybridHeap:
+		case EUdebHybridHeap:
+			{
+			TBool needWalk = EFalse;
+			if (aMask & ECommitted)
+				{
+				// RAllocator::Size uses iChunkSize - sizeof(RHybridHeap);
+				// We can't do exactly the same, because we can't calculate sizeof(RHybridHeap), only ROUND_UP(sizeof(RHybridHeap), iAlign)
+				// And if fact we don't bother and just use iChunkSize
+				TUint32 chunkSize = 0;
+				err = ReadWord(iAllocatorAddress + KChunkSizeOffset, chunkSize);
+				if (err) return err;
+				//TUint32 baseAddr = 0;
+				//err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), baseAddr);
+				//if (err) return err;
+				iInfo->iCommittedSize = chunkSize; // - (baseAddr - iAllocatorAddress);
+				iValidInfo |= ECommitted;
+				}
+			if (aMask & (EAllocated|ECount))
+				{
+				if (iAllocatorType == EUdebHybridHeap)
+					{
+					// Easy, just get them from the counter
+					TUint32 totalAlloc = 0;
+					err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), totalAlloc);
+					if (err) return err;
+					iInfo->iAllocatedSize = totalAlloc;
+					iValidInfo |= EAllocated;
+
+					TUint32 cellCount = 0;
+					err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), cellCount);
+					if (err) return err;
+					iInfo->iAllocationCount = cellCount;
+					iValidInfo |= ECount;
+					}
+				else
+					{
+					// A heap walk is needed
+					needWalk = ETrue;
+					}
+				}
+			if (aMask & EMaxSize)
+				{
+				TUint32 maxlen = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
+				if (err) return err;
+				iInfo->iMaxCommittedSize = maxlen;
+				iValidInfo |= EMaxSize;
+				}
+			if (aMask & EMinSize)
+				{
+				TUint32 minlen = 0;
+				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4*4, minlen); // iMinLength is in different place to old RHeap
+				if (err) return err;
+				iInfo->iMinCommittedSize = minlen;
+				iValidInfo |= EMinSize;
+				}
+			if (aMask & (EUnusedPages|ECommittedFreeSpace|EHybridStats))
+				{
+				// EAllocated and ECount have already been taken care of above
+				needWalk = ETrue;
+				}
+
+			if (needWalk)
+				{
+				iInfo->ClearStats();
+				iValidInfo = 0;
+				err = DoWalk(&WalkForStats, NULL);
+				if (err == KErrNone) iValidInfo |= KHeapWalkStatsForNewHeap;
+				}
+			return err;
+			}
+		default:
+			return KErrNotSupported;
+		}
+	}
+
+TInt RAllocatorHelper::CheckValid(TUint aMask)
+	{
+	if ((iValidInfo & aMask) == aMask)
+		{
+		return KErrNone;
+		}
+	else
+		{
+		return RefreshDetails(aMask);
+		}
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::CommittedSize()
+	{
+	TInt err = CheckValid(ECommitted);
+	if (err) return err;
+	return iInfo->iCommittedSize;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::AllocatedSize()
+	{
+	TInt err = CheckValid(EAllocated);
+	if (err) return err;
+	return iInfo->iAllocatedSize;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::AllocationCount()
+	{
+	TInt err = CheckValid(ECount);
+	if (err) return err;
+	return iInfo->iAllocationCount;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::RefreshDetails()
+	{
+	return RefreshDetails(iValidInfo);
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::MaxCommittedSize()
+	{
+	TInt err = CheckValid(EMaxSize);
+	if (err) return err;
+	return iInfo->iMaxCommittedSize;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::MinCommittedSize()
+	{
+	TInt err = CheckValid(EMinSize);
+	if (err) return err;
+	return iInfo->iMinCommittedSize;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::AllocCountForCell(TAny* aCell) const
+	{
+	TUint32 allocCount = 0;
+	switch (iAllocatorType)
+		{
+		case EUdebOldRHeap:
+		case EUdebHybridHeap: // Both are in the same place, amazingly
+			{
+			TLinAddr allocCountAddr = (TLinAddr)aCell - 4;
+			TInt err = ReadWord(allocCountAddr, allocCount);
+			if (err) return err;
+			return (TInt)allocCount;
+			}
+		default:
+			return KErrNotSupported;
+		}
+	}
+
+struct SContext3
+	{
+	RAllocatorHelper::TWalkFunc3 iOrigWalkFn;
+	TAny* iOrigContext;
+	};
+
+TBool RAllocatorHelper::DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
+	{
+	WalkForStats(aHelper, NULL, aCellType, aCellPtr, aCellLength);
+	SContext3* context = static_cast<SContext3*>(aContext);
+	return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, aCellType, aCellPtr, aCellLength);
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc3 aCallbackFn, TAny* aContext)
+	{
+	// Might as well take the opportunity of updating our stats at the same time as walking the heap for the client
+	SContext3 context = { aCallbackFn, aContext };
+
+	TInt err = FinishConstruction(); // In case this hasn't been done yet
+	if (err) return err;
+
+	TryLock();
+	err = DoWalk(&DispatchClientWalkCallback, &context);
+	TryUnlock();
+	return err;
+	}
+
+TInt RAllocatorHelper::DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
+	{
+	TInt err = KErrNotSupported;
+	switch (iAllocatorType)
+		{
+		case EUdebOldRHeap:
+		case EUrelOldRHeap:
+			err = OldSkoolWalk(aCallbackFn, aContext);
+			break;
+		case EUrelHybridHeap:
+		case EUdebHybridHeap:
+			err = NewHotnessWalk(aCallbackFn, aContext);
+			break;
+		default:
+			err = KErrNotSupported;
+			break;
+		}
+	return err;
+	}
+
+struct SContext
+	{
+	RAllocatorHelper::TWalkFunc iOrigWalkFn;
+	TAny* iOrigContext;
+	};
+
+struct SContext2
+	{
+	RAllocatorHelper::TWalkFunc2 iOrigWalkFn;
+	TAny* iOrigContext;
+	};
+
+#define New2Old(aNew) (((aNew)&RAllocatorHelper::EAllocationMask) ? RAllocatorHelper::EAllocation : ((aNew)&RAllocatorHelper::EFreeMask) ? RAllocatorHelper::EFreeSpace : RAllocatorHelper::EBadness)
+
+TBool DispatchOldTWalkFuncCallback(RAllocatorHelper& /*aHelper*/, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
+	{
+	SContext* context = static_cast<SContext*>(aContext);
+	return (*context->iOrigWalkFn)(context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength);
+	}
+
+TBool DispatchOldTWalk2FuncCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
+	{
+	SContext2* context = static_cast<SContext2*>(aContext);
+	return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength);
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc aCallbackFn, TAny* aContext)
+	{
+	// For backwards compatability insert a compatability callback to map between the different types of callback that clients requested
+	SContext context = { aCallbackFn, aContext };
+	return Walk(&DispatchOldTWalkFuncCallback, &context);
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc2 aCallbackFn, TAny* aContext)
+	{
+	SContext2 context = { aCallbackFn, aContext };
+	return Walk(&DispatchOldTWalk2FuncCallback, &context);
+	}
+
+
+TInt RAllocatorHelper::OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
+	{
+	TLinAddr pC = 0;
+	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), pC); // pC = iBase; // allocated cells
+	if (err) return err;
+	TLinAddr pF = iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 3*4; // pF = &iFree; // free cells
+
+	TLinAddr top = 0;
+	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top);
+	if (err) return err;
+	const TInt KAllocatedCellHeaderSize = iAllocatorType == EUdebOldRHeap ? 12 : 4;
+	TInt minCell = 0;
+	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4, (TUint32&)minCell);
+	if (err) return err;
+	TInt align = 0;
+	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign), (TUint32&)align);
+	if (err) return err;
+
+	FOREVER
+		{
+		err = ReadWord(pF+4, pF); // pF = pF->next; // next free cell
+		if (err) return err;
+		TLinAddr pFnext = 0;
+		if (pF) err = ReadWord(pF + 4, pFnext);
+		if (err) return err;
+
+		if (!pF)
+			{
+			pF = top; // to make size checking work
+			}
+		else if (pF>=top || (pFnext && pFnext<=pF) )
+			{
+			// free cell pointer off the end or going backwards
+			//Unlock();
+			(*aCallbackFn)(*this, aContext, EHeapBadFreeCellAddress, pF, 0);
+			return KErrCorrupt;
+			}
+		else
+			{
+			TInt l; // = pF->len
+			err = ReadWord(pF, (TUint32&)l);
+			if (err) return err;
+			if (l<minCell || (l & (align-1)))
+				{
+				// free cell length invalid
+				//Unlock();
+				(*aCallbackFn)(*this, aContext, EHeapBadFreeCellSize, pF, l);
+				return KErrCorrupt;
+				}
+			}
+		while (pC!=pF)				// walk allocated cells up to next free cell
+			{
+			TInt l; // pC->len;
+			err = ReadWord(pC, (TUint32&)l);
+			if (err) return err;
+			if (l<minCell || (l & (align-1)))
+				{
+				// allocated cell length invalid
+				//Unlock();
+				(*aCallbackFn)(*this, aContext, EHeapBadAllocatedCellSize, pC, l);
+				return KErrCorrupt;
+				}
+			TBool shouldContinue = (*aCallbackFn)(*this, aContext, EHeapAllocation, pC + KAllocatedCellHeaderSize, l - KAllocatedCellHeaderSize);
+			if (!shouldContinue) return KErrNone;
+			
+			//SCell* pN = __NEXT_CELL(pC);
+			TLinAddr pN = pC + l;
+			if (pN > pF)
+				{
+				// cell overlaps next free cell
+				//Unlock();
+				(*aCallbackFn)(*this, aContext, EHeapBadAllocatedCellAddress, pC, l);
+				return KErrCorrupt;
+				}
+			pC = pN;
+			}
+		if (pF == top)
+			break;		// reached end of heap
+		TInt pFlen = 0;
+		err = ReadWord(pF, (TUint32&)pFlen);
+		if (err) return err;
+		pC = pF + pFlen; // pC = __NEXT_CELL(pF);	// step to next allocated cell
+		TBool shouldContinue = (*aCallbackFn)(*this, aContext, EHeapFreeCell, pF, pFlen);
+		if (!shouldContinue) return KErrNone;
+		}
+	return KErrNone;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::CountUnusedPages()
+	{
+	TInt err = CheckValid(EUnusedPages);
+	if (err) return err;
+	return iInfo->iUnusedPages;
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::CommittedFreeSpace()
+	{
+	TInt err = CheckValid(ECommittedFreeSpace);
+	if (err) return err;
+	return iInfo->iCommittedFreeSpace;
+	}
+
+#define ROUND_DOWN(val, pow2) ((val) & ~((pow2)-1))
+#define ROUND_UP(val, pow2) ROUND_DOWN((val) + (pow2) - 1, (pow2))
+
+HUEXPORT_C TLinAddr RAllocatorHelper::AllocatorAddress() const
+	{
+	return iAllocatorAddress;
+	}
+
+TBool RAllocatorHelper::WalkForStats(RAllocatorHelper& aSelf, TAny* /*aContext*/, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength)
+	{
+	//ASSERT(aCellLength >= 0);
+	THeapInfo& info = *aSelf.iInfo;
+
+	TInt pagesSpanned = 0; // The number of pages that fit entirely inside the payload of this cell
+	if ((TUint)aCellLength > KPageSize)
+		{
+		TLinAddr nextPageAlignedAddr = ROUND_UP(aCellPtr, KPageSize);
+		pagesSpanned = ROUND_DOWN(aCellPtr + aCellLength - nextPageAlignedAddr, KPageSize) / KPageSize;
+		}
+
+	if (aSelf.iAllocatorType == EUrelOldRHeap || aSelf.iAllocatorType == EUdebOldRHeap)
+		{
+		if (aType & EFreeMask)
+			{
+			info.iUnusedPages += pagesSpanned;
+			info.iCommittedFreeSpace += aCellLength;
+			info.iHeapFreeCellCount++;
+			}
+		}
+	else
+		{
+		if (aType & EAllocationMask)
+			{
+			info.iAllocatedSize += aCellLength;
+			info.iAllocationCount++;
+			}
+		else if (aType & EFreeMask)
+			{
+			// I *think* that DLA will decommit pages from inside free cells...
+			TInt committedLen = aCellLength - (pagesSpanned * KPageSize);
+			info.iCommittedFreeSpace += committedLen;
+			}
+
+		switch (aType)
+			{
+			case EDlaAllocation:
+				info.iDlaAllocsSize += aCellLength;
+				info.iDlaAllocsCount++;
+				break;
+			case EPageAllocation:
+				info.iPageAllocsSize += aCellLength;
+				info.iPageAllocsCount++;
+				break;
+			case ESlabAllocation:
+				info.iSlabAllocsSize += aCellLength;
+				info.iSlabAllocsCount++;
+				break;
+			case EDlaFreeCell:
+				info.iDlaFreeSize += aCellLength;
+				info.iDlaFreeCount++;
+				break;
+			case ESlabFreeCell:
+				info.iSlabFreeCellSize += aCellLength;
+				info.iSlabFreeCellCount++;
+				break;
+			case ESlabFreeSlab:
+				info.iSlabFreeSlabSize += aCellLength;
+				info.iSlabFreeSlabCount++;
+				break;
+			default:
+				break;
+			}
+		}
+
+	return ETrue;
+	}
+
+#define PAGESHIFT 12
+
+TUint RAllocatorHelper::PageMapOperatorBrackets(unsigned ix, TInt& err) const
+	{
+	//return 1U&(iBase[ix>>3] >> (ix&7));
+	TUint32 basePtr = 0;
+	err = ReadWord(iAllocatorAddress + KPageMapOffset, basePtr);
+	if (err) return 0;
+
+	TUint8 res = 0;
+	err = ReadByte(basePtr + (ix >> 3), res);
+	if (err) return 0;
+
+	return 1U&(res >> (ix&7));
+	}
+
+
+TInt RAllocatorHelper::PageMapFind(TUint start, TUint bit, TInt& err)
+	{
+	TUint32 iNbits = 0;
+	err = ReadWord(iAllocatorAddress + KPageMapOffset + 4, iNbits);
+	if (err) return 0;
+
+	if (start<iNbits) do
+		{
+		//if ((*this)[start]==bit)
+		if (PageMapOperatorBrackets(start, err) == bit || err)
+			return start;
+		} while (++start<iNbits);
+	return -1;
+	}
+
+TUint RAllocatorHelper::PagedDecode(TUint pos, TInt& err)
+	{
+	unsigned bits = PageMapBits(pos,2,err);
+	if (err) return 0;
+	bits >>= 1;
+	if (bits == 0)
+		return 1;
+	bits = PageMapBits(pos+2,2,err);
+	if (err) return 0;
+	if ((bits & 1) == 0)
+		return 2 + (bits>>1);
+	else if ((bits>>1) == 0)
+		{
+		return PageMapBits(pos+4, 4,err);
+		}
+	else
+		{
+		return PageMapBits(pos+4, 18,err);
+		}
+	}
+
+TUint RAllocatorHelper::PageMapBits(unsigned ix, unsigned len, TInt& err)
+	{
+	int l=len;
+	unsigned val=0;
+	unsigned bit=0;
+	while (--l>=0)
+		{
+		//val |= (*this)[ix++]<<bit++;
+		val |= PageMapOperatorBrackets(ix++, err) << bit++;
+		if (err) return 0;
+		}
+	return val;
+	}
+
+enum TSlabType { ESlabFullInfo, ESlabPartialInfo, ESlabEmptyInfo };
+
+#ifndef TEST_HYBRIDHEAP_ASSERTS
+#define MAXSLABSIZE		56
+#define	SLABSHIFT		10
+#define	SLABSIZE		(1 << SLABSHIFT)
+const TInt KMaxSlabPayload = SLABSIZE - KSlabPayloadOffset;
+#endif
+
+TInt RAllocatorHelper::NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
+	{
+	// RHybridHeap does paged, slab then DLA, so that's what we do too
+	// Remember Kernel RHybridHeaps don't even have the page and slab members
+
+	TUint32 basePtr;
+	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), basePtr);
+	if (err) return err;
+	if (basePtr < iAllocatorAddress + KUserHybridHeapSize)
+		{
+		// Must be a kernel one - don't do page and slab
+		}
+	else
+		{
+		// Paged
+		TUint32 membase = 0;
+		err = ReadWord(iAllocatorAddress + KPageMapOffset + 8, membase);
+		if (err) return err;
+
+		TBool shouldContinue = ETrue;
+		for (int ix = 0;(ix = PageMapFind(ix,1,err)) >= 0 && err == KErrNone;)
+			{
+			int npage = PagedDecode(ix, err);
+			if (err) return err;
+			// Introduce paged buffer to the walk function 
+			TLinAddr bfr = membase + (1 << (PAGESHIFT-1))*ix;
+			int len = npage << PAGESHIFT;
+			if ( (TUint)len > KPageSize )
+				{ // If buffer is not larger than one page it must be a slab page mapped into bitmap
+				if (iAllocatorType == EUdebHybridHeap)
+					{
+					bfr += 8;
+					len -= 8;
+					}
+				shouldContinue = (*aCallbackFn)(*this, aContext, EPageAllocation, bfr, len);
+				if (!shouldContinue) return KErrNone;
+				}
+			ix += (npage<<1);
+			}
+		if (err) return err;
+
+		// Slab
+		TUint32 sparePage = 0;
+		err = ReadWord(iAllocatorAddress + KSparePageOffset, sparePage);
+		if (err) return err;
+		if (sparePage)
+			{
+			//Walk(wi, iSparePage, iPageSize, EGoodFreeCell, ESlabSpare); // Introduce Slab spare page to the walk function 
+			// This counts as 4 spare slabs
+			for (TInt i = 0; i < 4; i++)
+				{
+				shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, sparePage + SLABSIZE*i, SLABSIZE);
+				if (!shouldContinue) return KErrNone;
+				}
+			}
+
+		//TreeWalk(&iFullSlab, &SlabFullInfo, i, wi);
+		TInt err = TreeWalk(iAllocatorAddress + KFullSlabOffset, ESlabFullInfo, aCallbackFn, aContext, shouldContinue);
+		if (err || !shouldContinue) return err;
+		for (int ix = 0; ix < (MAXSLABSIZE>>2); ++ix)
+			{
+			TUint32 partialAddr = iAllocatorAddress + KSlabAllocOffset + ix*KSlabsetSize;
+			//TreeWalk(&iSlabAlloc[ix].iPartial, &SlabPartialInfo, i, wi);
+			err = TreeWalk(partialAddr, ESlabPartialInfo, aCallbackFn, aContext, shouldContinue);
+			if (err || !shouldContinue) return err;
+			}
+		//TreeWalk(&iPartialPage, &SlabEmptyInfo, i, wi);
+		TreeWalk(iAllocatorAddress + KPartialPageOffset, ESlabEmptyInfo, aCallbackFn, aContext, shouldContinue);
+		}
+
+	// DLA
+#define CHUNK_OVERHEAD (sizeof(TUint))
+#define CHUNK_ALIGN_MASK (7) 
+#define CHUNK2MEM(p)        ((TLinAddr)(p) + 8)
+#define MEM2CHUNK(mem)      ((TLinAddr)(p) - 8)
+/* chunk associated with aligned address A */
+#define ALIGN_OFFSET(A)\
+	((((TLinAddr)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
+	((8 - ((TLinAddr)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
+#define ALIGN_AS_CHUNK(A)   ((A) + ALIGN_OFFSET(CHUNK2MEM(A)))
+#define CINUSE_BIT 2
+#define INUSE_BITS 3
+
+	TUint32 topSize = 0;
+	err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopSizeOffset, topSize);
+	if (err) return err;
+
+	TUint32 top = 0;
+	err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopOffset, top);
+	if (err) return err;
+
+	TInt max = ((topSize-1) & ~CHUNK_ALIGN_MASK) - CHUNK_OVERHEAD;
+	if ( max < 0 )
+		max = 0;
+	
+	TBool shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, top, max);
+	if (!shouldContinue) return KErrNone;
+	
+	TUint32 mallocStateSegBase = 0;
+	err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateSegOffset, mallocStateSegBase);
+	if (err) return err;
+
+	for (TLinAddr q = ALIGN_AS_CHUNK(mallocStateSegBase); q != top; /*q = NEXT_CHUNK(q)*/)
+		{
+		TUint32 qhead = 0;
+		err = ReadWord(q + 4, qhead);
+		if (err) return err;
+		//TInt sz = CHUNKSIZE(q);
+		TInt sz = qhead & ~(INUSE_BITS);
+		if (!(qhead & CINUSE_BIT))
+			{
+			//Walk(wi, CHUNK2MEM(q), sz, EGoodFreeCell, EDougLeaAllocator); // Introduce DL free buffer to the walk function 
+			shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, CHUNK2MEM(q), sz);
+			if (!shouldContinue) return KErrNone;
+			}
+		else
+			{
+			//Walk(wi, CHUNK2MEM(q), (sz- CHUNK_OVERHEAD), EGoodAllocatedCell, EDougLeaAllocator); // Introduce DL allocated buffer to the walk function 
+			TLinAddr addr = CHUNK2MEM(q);
+			TInt size = sz - CHUNK_OVERHEAD;
+			if (iAllocatorType == EUdebHybridHeap)
+				{
+				size -= 8;
+				addr += 8;
+				}
+			shouldContinue = (*aCallbackFn)(*this, aContext, EDlaAllocation, addr, size);
+			if (!shouldContinue) return KErrNone;
+			}
+		// This is q = NEXT_CHUNK(q) expanded
+		q = q + sz;
+		}
+	return KErrNone;
+	}
+
+TInt RAllocatorHelper::TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue)
+	{
+	const TSlabType type = (TSlabType)aSlabType;
+
+	TUint32 s = 0;
+	TInt err = ReadWord(aSlabRoot, s);
+	if (err) return err;
+	//slab* s = *root;
+	if (!s)
+		return KErrNone;
+	
+	for (;;)
+		{
+		//slab* c;
+		//while ((c = s->iChild1) != 0)
+		//	s = c;		// walk down left side to end
+		TUint32 c;
+		for(;;)
+			{
+			err = ReadWord(s + KSlabChild1Offset, c);
+			if (err) return err;
+			if (c == 0) break;
+			else s = c;
+			}
+		for (;;)
+			{
+			//TODOf(s, i, wi);
+			//TODO __HEAP_CORRUPTED_TEST_STATIC
+			TUint32 h;
+			err = ReadWord(s, h); // = aSlab->iHeader;
+			if (err) return err;
+			TUint32 size = (h&0x0003f000)>>12; //SlabHeaderSize(h);
+			TUint debugheadersize = 0;
+			if (iAllocatorType == EUdebHybridHeap) debugheadersize = 8;
+			TUint32 usedCount = (((h&0x0ffc0000)>>18) + 4) / size; // (SlabHeaderUsedm4(h) + 4) / size;
+			switch (type)
+				{
+				case ESlabFullInfo:
+					{
+					TUint32 count = usedCount;
+					TUint32 i = 0;
+					while ( i < count )
+						{
+						TUint32 addr = s + KSlabPayloadOffset + i*size; //&aSlab->iPayload[i*size];
+						shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize);
+						if (!shouldContinue) return KErrNone;
+						i++;
+						}
+					break;
+					}
+				case ESlabPartialInfo:
+					{
+					//TODO __HEAP_CORRUPTED_TEST_STATIC
+					TUint32 count = KMaxSlabPayload / size;
+					TUint32 freeOffset = (h & 0xff) << 2;
+					if (freeOffset == 0)
+						{
+						// TODO Shouldn't happen for a slab on the partial list
+						}
+					memset(iTempSlabBitmap, 1, KTempBitmapSize); // Everything defaults to in use
+					TUint wildernessCount = count - usedCount;
+					while (freeOffset)
+						{
+						wildernessCount--;
+						TInt idx = (freeOffset-KSlabPayloadOffset)/size;
+						LOG("iTempSlabBitmap freeOffset %d index %d", freeOffset, idx);
+						iTempSlabBitmap[idx] = 0; // Mark it as free
+
+						TUint32 addr = s + freeOffset;
+						TUint8 nextCell = 0;
+						err = ReadByte(addr, nextCell);
+						if (err) return err;
+						freeOffset = ((TUint32)nextCell) << 2;
+						}
+					memset(iTempSlabBitmap + count - wildernessCount, 0, wildernessCount); // Mark the wilderness as free
+					for (TInt i = 0; i < count; i++)
+						{
+						TLinAddr addr = s + KSlabPayloadOffset + i*size;
+						if (iTempSlabBitmap[i])
+							{
+							// In use
+							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize);
+							}
+						else
+							{
+							// Free
+							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeCell, addr, size);
+							}
+						if (!shouldContinue) return KErrNone;
+						}
+					break;
+					}
+				case ESlabEmptyInfo:
+					{
+					// Check which slabs of this page are empty
+					TUint32 pageAddr = ROUND_DOWN(s, KPageSize);
+					TUint32 headerForPage = 0;
+					err = ReadWord(pageAddr, headerForPage);
+					if (err) return err;
+					TUint32 slabHeaderPageMap = (headerForPage & 0x00000f00)>>8; // SlabHeaderPagemap(unsigned h)
+					for (TInt slabIdx = 0; slabIdx < 4; slabIdx++)
+						{
+						if (slabHeaderPageMap & (1<<slabIdx))
+							{
+							TUint32 addr = pageAddr + SLABSIZE*slabIdx + KSlabPayloadOffset; //&aSlab->iPayload[i*size];
+							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, addr, KMaxSlabPayload);
+							if (!shouldContinue) return KErrNone;
+							}
+						}
+					break;
+					}
+				}
+
+			//c = s->iChild2;
+			err = ReadWord(s + KSlabChild2Offset, c);
+			if (err) return err;
+
+			if (c)
+				{	// one step down right side, now try and walk down left
+				s = c;
+				break;
+				}
+			for (;;)
+				{	// loop to walk up right side
+				TUint32 pp = 0;
+				err = ReadWord(s + KSlabParentOffset, pp);
+				if (err) return err;
+				//slab** pp = s->iParent;
+				if (pp == aSlabRoot)
+					return KErrNone;
+#define SlabFor(x) ROUND_DOWN(x, SLABSIZE)
+				s = SlabFor(pp);
+				//if (pp == &s->iChild1)
+				if (pp == s + KSlabChild1Offset)
+					break;
+				}
+			}
+		}
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::SizeForCellType(TExtendedCellType aType)
+	{
+	if (aType & EBadnessMask) return KErrArgument;
+	if (aType == EAllocationMask) return AllocatedSize();
+
+	if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap)
+		{
+		switch (aType)
+			{
+			case EHeapAllocation:
+				return AllocatedSize();
+			case EHeapFreeCell:
+			case EFreeMask:
+				return CommittedFreeSpace();
+			default:
+				return KErrNotSupported;
+			}
+		}
+	else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap)
+		{
+		TInt err = CheckValid(EHybridStats);
+		if (err) return err;
+
+		switch (aType)
+			{
+			case EHeapAllocation:
+			case EHeapFreeCell:
+				return KErrNotSupported;
+			case EDlaAllocation:
+				return iInfo->iDlaAllocsSize;
+			case EPageAllocation:
+				return iInfo->iPageAllocsSize;
+			case ESlabAllocation:
+				return iInfo->iSlabAllocsSize;
+			case EDlaFreeCell:
+				return iInfo->iDlaFreeSize;
+			case ESlabFreeCell:
+				return iInfo->iSlabFreeCellSize;
+			case ESlabFreeSlab:
+				return iInfo->iSlabFreeSlabSize;
+			case EFreeMask:
+				// Note this isn't the same as asking for CommittedFreeSpace(). SizeForCellType(EFreeMask) may include decommitted pages that lie inside a free cell
+				return iInfo->iDlaFreeSize + iInfo->iSlabFreeCellSize + iInfo->iSlabFreeSlabSize;
+			default:
+				return KErrNotSupported;
+			}
+		}
+	else
+		{
+		return KErrNotSupported;
+		}
+	}
+
+HUEXPORT_C TInt RAllocatorHelper::CountForCellType(TExtendedCellType aType)
+	{
+	if (aType & EBadnessMask) return KErrArgument;
+	if (aType == EAllocationMask) return AllocationCount();
+
+	if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap)
+		{
+		switch (aType)
+			{
+			case EHeapAllocation:
+				return AllocationCount();
+			case EHeapFreeCell:
+			case EFreeMask:
+				{
+				TInt err = CheckValid(ECommittedFreeSpace);
+				if (err) return err;
+				return iInfo->iHeapFreeCellCount;
+				}
+			default:
+				return KErrNotSupported;
+			}
+		}
+	else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap)
+		{
+		TInt err = CheckValid(EHybridStats);
+		if (err) return err;
+
+		switch (aType)
+			{
+			case EHeapAllocation:
+			case EHeapFreeCell:
+				return KErrNotSupported;
+			case EDlaAllocation:
+				return iInfo->iDlaAllocsCount;
+			case EPageAllocation:
+				return iInfo->iPageAllocsCount;
+			case ESlabAllocation:
+				return iInfo->iSlabAllocsCount;
+			case EDlaFreeCell:
+				return iInfo->iDlaFreeCount;
+			case ESlabFreeCell:
+				return iInfo->iSlabFreeCellCount;
+			case ESlabFreeSlab:
+				return iInfo->iSlabFreeSlabCount;
+			case EFreeMask:
+				// This isn't a hugely meaningful value, but if that's what they asked for...
+				return iInfo->iDlaFreeCount + iInfo->iSlabFreeCellCount + iInfo->iSlabFreeSlabCount;
+			default:
+				return KErrNotSupported;
+			}
+		}
+	else
+		{
+		return KErrNotSupported;
+		}
+	}
+
+HUEXPORT_C TBool LtkUtils::RAllocatorHelper::AllocatorIsUdeb() const
+	{
+	return iAllocatorType == EUdebOldRHeap || iAllocatorType == EUdebHybridHeap;
+	}
+
+
+HUEXPORT_C const TDesC& LtkUtils::RAllocatorHelper::Description() const
+	{
+	_LIT(KRHeap, "RHeap");
+	_LIT(KRHybridHeap, "RHybridHeap");
+	_LIT(KUnknown, "Unknown");
+	switch (iAllocatorType)
+		{
+		case EUrelOldRHeap:
+		case EUdebOldRHeap:
+			return KRHeap;
+		case EUrelHybridHeap:
+		case EUdebHybridHeap:
+			return KRHybridHeap;
+		case EAllocator:
+		case EUnknown:
+		default:
+			return KUnknown;
+		}
+	}
+
+#ifdef __KERNEL_MODE__
+
+DChunk* LtkUtils::RAllocatorHelper::OpenUnderlyingChunk()
+	{
+	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
+	TInt err = iChunk->Open();
+	if (err) return NULL;
+	return iChunk;
+	}
+
+DChunk* LtkUtils::RKernelSideAllocatorHelper::OpenUnderlyingChunk()
+	{
+	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
+	// Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
+	// It is for this reason that iChunk is private, to remove temptation
+	
+	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
+	TUint32 chunkHandle = 0;
+	TInt err = ReadData(iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle), &chunkHandle, sizeof(TUint32));
+	if (err) return NULL;
+
+	NKern::LockSystem();
+	DChunk* result = (DChunk*)Kern::ObjectFromHandle(iThread, chunkHandle, EChunk);
+	if (result && result->Open() != KErrNone)
+		{
+		result = NULL;
+		}
+	NKern::UnlockSystem();
+	return result;
+	}
+
+LtkUtils::RAllocatorHelper::TType LtkUtils::RAllocatorHelper::GetType() const
+	{
+	switch (iAllocatorType)
+		{
+		case EUrelOldRHeap:
+		case EUdebOldRHeap:
+			return ETypeRHeap;
+		case EUrelHybridHeap:
+		case EUdebHybridHeap:
+			return ETypeRHybridHeap;
+		case EAllocator:
+		case EUnknown:
+		default:
+			return ETypeUnknown;
+		}
+	}
+
+#else
+
+TInt LtkUtils::RAllocatorHelper::EuserIsUdeb()
+	{
+	TAny* buf = User::Alloc(4096);
+	if (!buf) return KErrNoMemory;
+	RAllocator* dummyHeap = UserHeap::FixedHeap(buf, 4096, 4, ETrue);
+	if (!dummyHeap) return KErrNoMemory; // Don't think this can happen
+
+	dummyHeap->__DbgSetAllocFail(RAllocator::EFailNext, 1);
+	TAny* ptr = dummyHeap->Alloc(4);
+	// Because we specified singleThreaded=ETrue we can allow dummyHeap to just go out of scope here
+	User::Free(buf);
+
+	if (ptr)
+		{
+		// Clearly the __DbgSetAllocFail had no effect so we must be urel
+		// We don't need to free ptr because it came from the dummy heap
+		return EFalse;
+		}
+	else
+		{
+		return ETrue;
+		}
+	}
+
+#ifndef STANDALONE_ALLOCHELPER
+
+#include <fshell/ltkutils.h>
+HUEXPORT_C void LtkUtils::MakeHeapCellInvisible(TAny* aCell)
+	{
+	RAllocatorHelper helper;
+	TInt err = helper.Open(&User::Allocator());
+	if (err == KErrNone)
+		{
+		helper.SetCellNestingLevel(aCell, -1);
+		helper.Close();
+		}
+	}
+#endif // STANDALONE_ALLOCHELPER
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Shared/heaputils.h	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,216 @@
+// heaputils.h
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+
+#ifndef FSHELL_HEAP_UTILS_H
+#define FSHELL_HEAP_UTILS_H
+
+#include <e32cmn.h>
+
+#ifdef __KERNEL_MODE__
+class DThread;
+class DChunk;
+#else
+class RMemoryAccess;
+#endif // __KERNEL_MODE__
+
+#if defined(STANDALONE_ALLOCHELPER) || defined(__KERNEL_MODE__)
+#define HUIMPORT_C
+#define HUCLASS(x) NONSHARABLE_CLASS(x)
+#else
+#define HUIMPORT_C IMPORT_C
+#define HUCLASS(x) class x
+#endif
+
+namespace LtkUtils
+	{
+
+class THeapInfo;
+	
+HUCLASS(RAllocatorHelper) // class RAllocatorHelper
+	{
+public:
+	HUIMPORT_C RAllocatorHelper();
+#ifdef __KERNEL_MODE__
+	TInt OpenKernelHeap();
+#else
+	HUIMPORT_C TInt Open(RAllocator* aAllocator);
+#endif
+	HUIMPORT_C TInt SetCellNestingLevel(TAny* aCell, TInt aNestingLevel);
+	HUIMPORT_C TInt GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel);
+	HUIMPORT_C TInt AllocCountForCell(TAny* aCell) const;
+	HUIMPORT_C TLinAddr AllocatorAddress() const;
+	HUIMPORT_C TInt RefreshDetails();
+	
+	HUIMPORT_C TInt CommittedSize();
+	HUIMPORT_C TInt AllocatedSize();
+	HUIMPORT_C TInt AllocationCount();
+	HUIMPORT_C TInt MaxCommittedSize();
+	HUIMPORT_C TInt MinCommittedSize();
+	HUIMPORT_C TInt CountUnusedPages();
+	HUIMPORT_C TInt CommittedFreeSpace();
+
+	enum TCellType
+		{
+		EAllocation, EFreeSpace, EBadness
+		};
+
+	enum TExtendedCellType
+		{
+		EAllocationMask = 0xFF,
+		EFreeMask = 0xFF00,
+		EBadnessMask = 0xFF000000,
+
+		EHeapAllocation = 1,
+		EDlaAllocation = 2,
+		EPageAllocation = 3,
+		ESlabAllocation = 4,
+		
+		EHeapFreeCell = 0x0100,
+		EDlaFreeCell = 0x0200,
+		// There is nothing 'free' in the page allocator
+		ESlabFreeCell = 0x0300, // Used to track free cells in partially-filled slabs
+		ESlabFreeSlab = 0x0400, // Used to track entirely empty slabs (that don't have a specific cell size)
+
+		EHeapBadFreeCellAddress = 0x01000000,
+		EHeapBadFreeCellSize = 0x02000000,
+		EHeapBadAllocatedCellSize = 0x03000000,
+		EHeapBadAllocatedCellAddress = 0x04000000,
+		};
+			
+	// TBool WalkFunc(TAny* aContext, TCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
+	// aCellPtr points to the start of the cell payload for allocated cells (unlike RHeap's walker, which points to the cell header)
+	// aCellLength is the payload length, ie what AllocLen(aCellPtr) would return
+	// return ETrue to continue walking, EFalse to stop the walk
+	typedef TBool (*TWalkFunc)(TAny*, TCellType, TLinAddr, TInt);
+	typedef TBool (*TWalkFunc2)(RAllocatorHelper&, TAny*, TCellType, TLinAddr, TInt);
+	typedef TBool (*TWalkFunc3)(RAllocatorHelper&, TAny*, TExtendedCellType, TLinAddr, TInt);
+	HUIMPORT_C TInt Walk(TWalkFunc aCallbackFn, TAny* aContext);
+	HUIMPORT_C TInt Walk(TWalkFunc2 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you the RAllocatorHelper pointer too
+	HUIMPORT_C TInt Walk(TWalkFunc3 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you more details about the allocation type
+	HUIMPORT_C TInt SizeForCellType(TExtendedCellType aType);
+	HUIMPORT_C TInt CountForCellType(TExtendedCellType aType);
+	HUIMPORT_C TBool AllocatorIsUdeb() const;
+	HUIMPORT_C const TDesC& Description() const;
+	HUIMPORT_C virtual void Close();
+
+#ifdef __KERNEL_MODE__
+	virtual DChunk* OpenUnderlyingChunk(); // Must be in CS
+	enum TType
+		{
+		ETypeUnknown,
+		ETypeRHeap,
+		ETypeRHybridHeap,
+		};
+	TType GetType() const; // This is for information only, nothing should care about the return value
+#endif
+
+protected:
+	TInt FinishConstruction();
+	TInt IdentifyAllocatorType(TBool aAllocatorIsUdeb);
+	TInt OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize);
+#ifndef __KERNEL_MODE__
+	static TInt EuserIsUdeb();
+#endif
+	virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
+	virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
+	virtual TInt TryLock();
+	virtual void TryUnlock();
+
+private:
+	TInt ReadWord(TLinAddr aLocation, TUint32& aResult) const;
+	TInt ReadByte(TLinAddr aLocation, TUint8& aResult) const;
+	TInt WriteWord(TLinAddr aLocation, TUint32 aWord);
+	TInt RefreshDetails(TUint aMask);
+	TInt DoRefreshDetails(TUint aMask);
+	TInt CheckValid(TUint aMask);
+	TInt DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
+	TInt OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
+	TInt NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
+	static TBool DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength);
+	static TBool WalkForStats(RAllocatorHelper& aSelf, TAny* aContext, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength);
+	TUint PageMapOperatorBrackets(unsigned ix, TInt& err) const;
+	TInt PageMapFind(TUint start, TUint bit, TInt& err);
+	TUint PageMapBits(unsigned ix, unsigned len, TInt& err);
+	TUint PagedDecode(TUint pos, TInt& err);
+	TInt TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue);
+protected:
+	TLinAddr iAllocatorAddress;
+	enum TAllocatorType
+		{
+		EUnknown,
+		EAllocator,
+		EUrelOldRHeap,
+		EUdebOldRHeap,
+		EUrelHybridHeap,
+		EUdebHybridHeap,
+		};
+	TAllocatorType iAllocatorType;
+private:
+	THeapInfo* iInfo;
+	TUint iValidInfo;
+	TUint8* iTempSlabBitmap;
+	mutable TAny* iPageCache;
+	mutable TLinAddr iPageCacheAddr;
+#ifdef __KERNEL_MODE__
+	DChunk* iChunk;
+	//TUint iSpare[0];
+#else
+	TUint iSpare[1];
+#endif
+	};
+
+#ifdef __KERNEL_MODE__
+
+class RKernelSideAllocatorHelper : public RAllocatorHelper
+	{
+public:
+	RKernelSideAllocatorHelper();
+	TInt OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb);
+	virtual DChunk* OpenUnderlyingChunk(); // Must be in CS
+	virtual void Close();
+
+protected:
+	virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
+	virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
+	virtual TInt TryLock();
+	virtual void TryUnlock();
+private:
+	DThread* iThread;
+	};
+
+#else
+
+class RProxyAllocatorHelper : public RAllocatorHelper
+	{
+public:
+	HUIMPORT_C RProxyAllocatorHelper();
+	HUIMPORT_C TInt Open(RMemoryAccess& aMem, TUint aThreadId);
+	HUIMPORT_C TInt OpenChunkHeap(RMemoryAccess& aMem, TAny* aDChunkPtr);
+	HUIMPORT_C virtual void Close();
+
+protected:
+	virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
+	virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
+	virtual TInt TryLock();
+	virtual void TryUnlock();
+
+private:
+	RMemoryAccess* iMemoryAccess;
+	TUint iThreadId;
+	};
+
+#endif // __KERNEL_MODE__
+
+	} // namespace LtkUtils
+
+#endif
--- a/memspy/Driver/User/Include/RBuildQueryableHeap.h	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#ifndef RBUILDQUERYABLEHEAP_H
-#define RBUILDQUERYABLEHEAP_H
-
-// System includes
-#include <e32cmn.h>
-
-// User includes
-#include <memspy/driver/memspydriverenumerationsshared.h>
-
-
-class RBuildQueryableHeap : public RHeap
-    {
-public: // API
-    TBool IsDebugEUser() const;
-    TInt CellHeaderSize( TMemSpyDriverCellType aType ) const;
-    };
-
-
-
-#endif
--- a/memspy/Driver/User/Source/MemSpyDriverClient.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/User/Source/MemSpyDriverClient.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -22,11 +22,11 @@
 
 // User includes
 #include "MemSpyDriverOpCodes.h"
-#include "RBuildQueryableHeap.h"
 #include <memspy/driver/memspydriverconstants.h>
 #include <memspy/driver/memspydriverobjectsshared.h>
 #include "MemSpyDriverStreamReaderImp.h"
 #include "MemSpyDriverObjectsInternal.h"
+#include "heaputils.h"
 
 // Constants
 const TInt KMemSpyClientBufferGrowSize = 0x1000 * 8; // 32kb
@@ -511,7 +511,7 @@
             TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
             TMemSpyHeapMetaDataRHeap& metaData = rHeapInfo.MetaData();
             metaData.SetVTable( RHeapVTable() );
-            metaData.SetClassSize( sizeof( RHeap ) );
+            //metaData.SetClassSize( sizeof( RHeap ) );
             }
         }
     else if ( r == KErrNotSupported )
@@ -523,9 +523,14 @@
 	return r;
     }
 
+EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray< TMemSpyDriverFreeCell >& aFreeCells )
+	{
+	return GetHeapInfoUser(aInfo, aTid, aFreeCells, EFalse);
+	}
 
-EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray< TMemSpyDriverFreeCell >& aFreeCells )
-    {
+// For the record I don't think this function should be exported, but since the one above was I'm going with the flow. -TomS
+EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser(TMemSpyHeapInfo& aInfo, TUint aTid, RArray<TMemSpyDriverCell>& aCells, TBool aCollectAllocatedCellsAsWellAsFree)
+	{
     TMemSpyDriverInternalHeapRequestParameters params;
     //
     params.iTid = aTid;
@@ -533,8 +538,10 @@
     params.iDebugAllocator = DebugEUser();
     params.iMasterInfo = &aInfo;
     params.iBuildFreeCellList = ETrue;
+	params.iBuildAllocCellList = aCollectAllocatedCellsAsWellAsFree;
+
     //
-    aFreeCells.Reset();
+    aCells.Reset();
     ResetStreamBuffer();
 	TInt r = DoControl( EMemSpyDriverOpCodeHeapInfoGetUser, &params );
 	//
@@ -548,7 +555,7 @@
             TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
             TMemSpyHeapMetaDataRHeap& metaData = rHeapInfo.MetaData();
             metaData.SetVTable( RHeapVTable() );
-            metaData.SetClassSize( sizeof( RHeap ) );
+            //metaData.SetClassSize( sizeof( RHeap ) );
             }
 
         // Resize transfer buffer to make room for free cells. We only make the buffer
@@ -561,10 +568,10 @@
         // Now fetch the heap data
         if  ( r == KErrNone )
             {
-            r = DoControl( EMemSpyDriverOpCodeHeapInfoFetchFreeCells, &iBuffer );
+            r = DoControl( EMemSpyDriverOpCodeHeapInfoFetchCellList, &iBuffer );
             if  ( r == KErrNone )
                 {
-                TRAP( r, ReadHeapInfoFreeCellsFromXferBufferL( aFreeCells ) );
+                TRAP( r, ReadHeapInfoFreeCellsFromXferBufferL( aCells ) );
                 }
             }
         }
@@ -663,6 +670,7 @@
     params.iDes = &aDest;
     params.iChecksum = aFreeCellChecksum;
     params.iRemaining = -1;
+	params.iReadAddress = 0;
     aDest.Zero();
     //
 	TInt r = DoControl( EMemSpyDriverOpCodeHeapDataGetUser, &params, NULL );
@@ -688,6 +696,7 @@
     params.iDes = &aDest;
     params.iChecksum = 0;
     params.iRemaining = aAmountRemaining;
+	params.iReadAddress = aReadAddress;
     aDest.Zero();
     //
 	TInt r = DoControl( EMemSpyDriverOpCodeHeapDataGetUser, &params, NULL );
@@ -790,7 +799,7 @@
 
 EXPORT_C TInt RMemSpyDriverClient::WalkHeapNextCell( TUint aTid, TMemSpyDriverCellType& aCellType, TAny*& aCellAddress, TInt& aLength, TInt& aNestingLevel, TInt& aAllocNumber, TInt& aCellHeaderSize, TAny*& aCellPayloadAddress )
     {
-    aCellType = EMemSpyDriverGoodAllocatedCell;
+    aCellType = EMemSpyDriverBadCellMask;
     aCellAddress = NULL;
     aLength = 0;
     aNestingLevel = 0;
@@ -803,14 +812,11 @@
     //
 	if  ( r == KErrNone )
 	    {
-        RBuildQueryableHeap* heap = static_cast< RBuildQueryableHeap* >( &User::Allocator() );
-        //
         aCellType = (TMemSpyDriverCellType) params.iCellType;
         aCellAddress = params.iCellAddress;
         aLength = params.iLength;
         aNestingLevel = params.iNestingLevel;
         aAllocNumber = params.iAllocNumber;
-        aCellHeaderSize = heap->CellHeaderSize( aCellType );
         aCellPayloadAddress = ((TUint8*) aCellAddress) + aCellHeaderSize;
         }
     //
@@ -839,7 +845,7 @@
 
 EXPORT_C TInt RMemSpyDriverClient::WalkHeapGetCellInfo( TAny*& aCellAddress, TMemSpyDriverCellType& aCellType, TInt& aLength, TInt& aNestingLevel, TInt& aAllocNumber, TInt& aCellHeaderSize, TAny*& aCellPayloadAddress )
     {
-    aCellType = EMemSpyDriverGoodAllocatedCell;
+    aCellType = EMemSpyDriverBadCellMask;
     aLength = 0;
     aNestingLevel = 0;
     aAllocNumber = 0;
@@ -851,14 +857,11 @@
     //
 	if  ( r == KErrNone )
 	    {
-        RBuildQueryableHeap* heap = static_cast< RBuildQueryableHeap* >( &User::Allocator() );
-        //
         aCellAddress = params.iCellAddress;
         aCellType = (TMemSpyDriverCellType) params.iCellType;
         aLength = params.iLength;
         aNestingLevel = params.iNestingLevel;
         aAllocNumber = params.iAllocNumber;
-        aCellHeaderSize = heap->CellHeaderSize( aCellType );
         aCellPayloadAddress = ((TUint8*) aCellAddress) + aCellHeaderSize;
         }
     //
@@ -1401,10 +1404,15 @@
 
 TBool RMemSpyDriverClient::DebugEUser()
     {
-    RHeap* heap = static_cast< RHeap* >( &User::Allocator() );
-    RBuildQueryableHeap* queryHeap = static_cast< RBuildQueryableHeap* >( heap );
-    const TBool isDebugEUser = queryHeap->IsDebugEUser();
-    return isDebugEUser;
+	LtkUtils::RAllocatorHelper allocHelper;
+	TBool result = EFalse;
+	TInt err = allocHelper.Open(&User::Allocator());
+	if (!err)
+		{
+		result = allocHelper.AllocatorIsUdeb();
+		allocHelper.Close();
+		}
+	return result;
     }
 
 
@@ -1435,7 +1443,7 @@
         for( TInt i=0; i<count; i++ )
             {
             TMemSpyDriverFreeCell entry;
-            entry.iType = stream.ReadInt32L();
+            entry.iType = (TMemSpyDriverCellType)stream.ReadInt32L();
             entry.iAddress = reinterpret_cast< TAny* >( stream.ReadUint32L() );
             entry.iLength = stream.ReadInt32L();
             aFreeCells.AppendL( entry );
@@ -1462,10 +1470,11 @@
     {
 #if defined( _DEBUG ) && !defined( __WINS__ )
     const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
-    const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
+    //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
     const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
     const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
 
+	/*
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RAllocator                                      -");
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
@@ -1501,6 +1510,7 @@
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RHeap::iRand:                   %d", rHeapObjectData.iRand);
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RHeap::iTestData:               0x%08x", rHeapObjectData.iTestData);
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - ");
+	*/
 
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Stats (Free)                                    -");
@@ -1524,12 +1534,6 @@
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - ");
 
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Stats (Common)                                  -");
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - total cell count:               %d", rHeapStats.StatsCommon().TotalCellCount());
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - ");
-
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Misc. Info                                      -");
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------");
     const TPtrC chunkName( rHeapMetaData.ChunkName() );
@@ -1542,8 +1546,8 @@
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - user thread:                    %d", rHeapMetaData.IsUserThread() );
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - thread id:                      %d", aInfo.Tid() );
     RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - process id:                     %d", aInfo.Pid() );
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree());
-    RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated());
+    //RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (free):        %d", rHeapMetaData.HeaderSizeFree());
+    //RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (alloc):       %d", rHeapMetaData.HeaderSizeAllocated());
 #else
     (void) aInfo;
 #endif
--- a/memspy/Driver/User/Source/RBuildQueryableHeap.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include "RBuildQueryableHeap.h"
-
-// System includes
-#include <e32std.h>
-#include <e32debug.h>
-
-
-TBool RBuildQueryableHeap::IsDebugEUser() const
-    {
-    User::__DbgSetAllocFail( FALSE, RAllocator::EFailNext, 1);
-
-    TInt* cell = new TInt();
-#if defined(_DEBUG) && !defined( __WINS__ )
-    RDebug::Printf("RBuildQueryableHeap::IsDebugEUser() - cell: 0x%08x", cell);
-#endif
-
-    const TBool debugEUser = ( cell == NULL );
-#if defined(_DEBUG) && !defined( __WINS__ )
-    RDebug::Printf("RBuildQueryableHeap::IsDebugEUser() - debugEUser: %d", debugEUser);
-#endif
-
-    delete cell;
-    //
-    return debugEUser;
-    }
-
-
-TInt RBuildQueryableHeap::CellHeaderSize( TMemSpyDriverCellType aType ) const
-    {
-	TInt size = 0;
-	//
-	switch( aType )
-	{
-	case EMemSpyDriverGoodAllocatedCell:
-	case EMemSpyDriverBadAllocatedCellSize:
-	case EMemSpyDriverBadAllocatedCellAddress:
-		{
-		size = sizeof( TInt ); // Allocated UREL cells contain just a length
-		if  ( IsDebugEUser() )
-			{
-			size = sizeof( RHeap::SDebugCell );
-			}
-		break;
-		}
-	case EMemSpyDriverGoodFreeCell:
-	case EMemSpyDriverBadFreeCellAddress:
-	case EMemSpyDriverBadFreeCellSize:
-		size = EFreeCellSize;
-		break;
-	default:
-		break;
-	}
-    //
-    return size;
-    }
-
--- a/memspy/Driver/eabi/memspydriverclientu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/eabi/memspydriverclientu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -67,4 +67,5 @@
 	_ZN22RMemSpyMemStreamReader5ReadLER6TDes16 @ 66 NONAME
 	_ZN19RMemSpyDriverClient26GetCondVarSuspendedThreadsEPvPS0_Ri @ 67 NONAME
 	_ZN19RMemSpyDriverClient29GetCondVarSuspendedThreadInfoEPvR39TMemSpyDriverCondVarSuspendedThreadInfo @ 68 NONAME
+	_ZN19RMemSpyDriverClient15GetHeapInfoUserER15TMemSpyHeapInfojR6RArrayI21TMemSpyDriverFreeCellEi @ 69 NONAME
 
--- a/memspy/Driver/group/MemSpyDriver.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/group/MemSpyDriver.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -69,6 +69,11 @@
 USERINCLUDE     ../Kernel/Include
 USERINCLUDE     ../Kernel/Include/SubChannels
 
+// New Allocator support
+MACRO			STANDALONE_ALLOCHELPER
+SOURCEPATH      ../Shared
+SOURCE          heaputils.cpp
+
 OS_LAYER_KERNEL_SYSTEMINCLUDE
 
 START WINS
--- a/memspy/Driver/group/MemSpyDriverClient.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Driver/group/MemSpyDriverClient.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -29,7 +29,6 @@
 
 SOURCEPATH				../User/Source
 SOURCE					MemSpyDriverClient.cpp
-SOURCE					RBuildQueryableHeap.cpp
 SOURCE					MemSpyDriverStreamReader.cpp
 SOURCE					MemSpyDriverStreamReaderImp.cpp
 
@@ -40,6 +39,10 @@
 
 LIBRARY					euser.lib efsrv.lib
 
+// New Allocator support
+MACRO			STANDALONE_ALLOCHELPER
+SOURCEPATH      ../Shared
+SOURCE          heaputils.cpp
 
 
 
--- a/memspy/Engine/BWINS/MemSpyEngineu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/BWINS/MemSpyEngineu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -411,4 +411,17 @@
 	?NewHeapRawInfo@CMemSpyEngineHelperHeap@@QAE?AVTMemSpyHeapData@@ABVTMemSpyHeapInfo@@@Z @ 410 NONAME ; class TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo(class TMemSpyHeapInfo const &)
 	?ItemsCount@CMemSpyEngineGenericKernelObjectList@@QBEHXZ @ 411 NONAME ; int CMemSpyEngineGenericKernelObjectList::ItemsCount(void) const
 	?Priority@CMemSpyThread@@QBE?AW4TThreadPriority@@XZ @ 412 NONAME ; enum TThreadPriority CMemSpyThread::Priority(void) const
+	?NewL@CMemSpyEngine@@SAPAV1@AAVRFs@@H@Z @ 413 NONAME ; class CMemSpyEngine * CMemSpyEngine::NewL(class RFs &, int)
+	?Value@CMemSpyThreadInfoItemBase@@QBE?AVTPtrC16@@H@Z @ 414 NONAME ; class TPtrC16 CMemSpyThreadInfoItemBase::Value(int) const
+	?ExitType@CMemSpyProcess@@QBE?AW4TExitType@@XZ @ 415 NONAME ; enum TExitType CMemSpyProcess::ExitType(void) const
+	?ExitCategory@CMemSpyProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 416 NONAME ; class TBuf<16> CMemSpyProcess::ExitCategory(void) const
+	?Priority@CMemSpyProcess@@QBE?AW4TProcessPriority@@XZ @ 417 NONAME ; enum TProcessPriority CMemSpyProcess::Priority(void) const
+	?Caption@CMemSpyThreadInfoItemBase@@QBE?AVTPtrC16@@H@Z @ 418 NONAME ; class TPtrC16 CMemSpyThreadInfoItemBase::Caption(int) const
+	?ExitReason@CMemSpyProcess@@QBEHXZ @ 419 NONAME ; int CMemSpyProcess::ExitReason(void) const
+	?NewL@CMemSpyEngineSinkMetaData@@SAPAV1@ABVTDesC16@@000HHABVTTime@@@Z @ 420 NONAME ; class CMemSpyEngineSinkMetaData * CMemSpyEngineSinkMetaData::NewL(class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, int, int, class TTime const &)
+	?InstallDebugSinkL@CMemSpyEngine@@QAEXXZ @ 421 NONAME ; void CMemSpyEngine::InstallDebugSinkL(void)
+	?NewL@CMemSpyEngineSinkMetaData@@SAPAV1@ABVTDesC16@@000HH@Z @ 422 NONAME ; class CMemSpyEngineSinkMetaData * CMemSpyEngineSinkMetaData::NewL(class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, int, int)
+	?InstallFileSinkL@CMemSpyEngine@@QAEXABVTDesC16@@@Z @ 423 NONAME ; void CMemSpyEngine::InstallFileSinkL(class TDesC16 const &)
+	?CheckForChangesNowL@CMemSpyEngineHelperSysMemTracker@@QAEXXZ @ 424 NONAME ; void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL(void)
+	?GetHeapInfoUserL@CMemSpyEngineHelperHeap@@QAEXABVTProcessId@@ABVTThreadId@@AAVTMemSpyHeapInfo@@PAV?$RArray@VTMemSpyDriverFreeCell@@@@H@Z @ 425 NONAME ; void CMemSpyEngineHelperHeap::GetHeapInfoUserL(class TProcessId const &, class TThreadId const &, class TMemSpyHeapInfo &, class RArray<class TMemSpyDriverFreeCell> *, int)
 
--- a/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h	Thu Jul 22 16:50:07 2010 +0100
@@ -23,17 +23,36 @@
 
 // User includes
 #include <memspyengineclientinterface.h>
+#include <memspy/engine/memspydevicewideoperations.h>
 
 // Classes referenced
 class CMemSpyEngine;
+class CMemSpyDwOperationTracker;
 
-
+NONSHARABLE_CLASS( CShutdown ) : public CTimer
+    {
+    enum {KMyShutdownDelay=10 * 1000000};       // 10s
+public:
+    inline CShutdown();
+    inline void ConstructL();
+    inline void Start();
+private:
+    void RunL();
+    };
 
 NONSHARABLE_CLASS( CMemSpyEngineServer ) : public CServer2
     {
 public:
     static CMemSpyEngineServer* NewL( CMemSpyEngine& aEngine );
     ~CMemSpyEngineServer();
+    
+    CMemSpyDwOperationTracker* CurrentOperationTracker() const { return iCurrentOperationTracker; }
+    void SetCurrentOperationTracker(CMemSpyDwOperationTracker* aTracker) { iCurrentOperationTracker = aTracker; }
+    
+    CMemSpyEngine& Engine() { return iEngine; } 
+    
+    void AddSession(TBool aCliRequest);
+    void DropSession(TBool aCliRequest);
 
 private:
     CMemSpyEngineServer( CMemSpyEngine& aEngine );
@@ -44,6 +63,12 @@
 
 private:
     CMemSpyEngine& iEngine;
+    CMemSpyDwOperationTracker* iCurrentOperationTracker;
+    
+    TInt iSessionCount;
+    TBool iCliConnected;
+    
+    CShutdown iShutdown;
     };
 
 
@@ -53,7 +78,9 @@
 public:
 	static CMemSpyEngineSession* NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage );
 	~CMemSpyEngineSession();
-
+	
+	void CreateL();
+	
 private:
 	CMemSpyEngineSession( CMemSpyEngine& aEngine );
 	void ConstructL( const RMessage2& aMessage );
@@ -63,17 +90,54 @@
 
 private: // Internal methods
     void DoServiceL( const RMessage2& aMessage );
+    void DoAsyncServiceL( const RMessage2& aMessage );
+    void DoUiServiceL( const RMessage2& aMessage );
+    void DoCmdServiceL( const RMessage2& aMessage );
     static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName );
     void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId );
     void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName );
     void HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage );
+    void StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage);
+    
+    inline CMemSpyEngineServer& Server() const { return *static_cast<CMemSpyEngineServer*>(const_cast<CServer2*>(CSession2::Server())); }
 
 private:
     CMemSpyEngine& iEngine;
     HBufC* iClientThreadName;
     TUint32 iClientThreadId;
+    TBool iIsCliRequest;
     };
 
+/**
+ * CMemSpyDwOperationTracker
+ * Tracks device wide operation progress and calls iOperationMessage.Complete upon completion. 
+ */
+NONSHARABLE_CLASS( CMemSpyDwOperationTracker ) : public MMemSpyDeviceWideOperationsObserver
+	{
+public:
+	static CMemSpyDwOperationTracker* NewL(CMemSpyDeviceWideOperations::TOperation aOperation, 
+			const RMessage2& aOperationMessage,
+			CMemSpyEngineServer& aServer);
+	~CMemSpyDwOperationTracker();
+	
+	void AddNotificationL(const RMessage2& aMessage);
+	
+	void Cancel();
+
+public: // From MMemSpyDeviceWideOperationsObserver
+	void HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2);
+	
+private:
+	CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer);
+	void ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation);
+	
+private:
+	RMessage2 iOperationMessage;
+	CMemSpyEngineServer& iServer;
+	CArrayFixFlat<RMessage2>* iPendingNotifications;
+	CMemSpyDeviceWideOperations* iOperation;
+	TInt iProgress;
+	};
 
 
 #endif
--- a/memspy/Engine/Include/Sink/MemSpyEngineOutputSinkFile.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Include/Sink/MemSpyEngineOutputSinkFile.h	Thu Jul 22 16:50:07 2010 +0100
@@ -32,12 +32,12 @@
 NONSHARABLE_CLASS( CMemSpyEngineOutputSinkFile ) : public CMemSpyEngineOutputSink
     {
 public:
-    static CMemSpyEngineOutputSinkFile* NewL( CMemSpyEngine& aEngine );
+    static CMemSpyEngineOutputSinkFile* NewL( CMemSpyEngine& aEngine, const TDesC& aRootFolder );
     ~CMemSpyEngineOutputSinkFile();
 
 public:
     CMemSpyEngineOutputSinkFile( CMemSpyEngine& aEngine );
-    void ConstructL();
+    void ConstructL( const TDesC& aRootFolder );
     
 private: // From CMemSpyEngineOutputSink
     void ProcessSuspendedL( TProcessId aId );
@@ -64,6 +64,8 @@
 
     TUint iFileServerProcessId;
     TBool iFileServerSuspended;
+    
+    HBufC* iRoot;
 
 private:
     friend class CMemSpyEngineFileHolder;
@@ -117,4 +119,4 @@
 
 
 
-#endif
\ No newline at end of file
+#endif
--- a/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -19,6 +19,9 @@
 
 // System includes
 #include <e32svr.h>
+#include <w32std.h>
+#include <APGTASK.H>
+#include <APGWGNAM.H>  
 
 // User includes
 #include <memspy/engine/memspyengine.h>
@@ -38,7 +41,40 @@
 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
+#include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
+#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
+#include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
 
+#include <memspy/engine/memspyprocessdata.h>
+#include <memspy/engine/memspythreaddata.h>
+#include <memspy/engine/memspykernelobjectdata.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
+#include <memspy/engine/memspymemorytrackingcycledata.h>
+#include <memspy/engine/memspyengineoutputsink.h>
+#include <memspy/engine/memspyenginehelperactiveobject.h>
+
+inline CShutdown::CShutdown() :CTimer(-1)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+inline void CShutdown::ConstructL()
+    {
+    CTimer::ConstructL();
+    }
+
+inline void CShutdown::Start()
+    {
+    After(KMyShutdownDelay);
+    }
+
+void CShutdown::RunL()
+    //
+    // Initiate server exit when the timer expires
+    //
+    {
+    CActiveScheduler::Stop();
+    }
 
 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
 :   CServer2( EPriorityNormal ), iEngine( aEngine )
@@ -54,6 +90,10 @@
 void CMemSpyEngineServer::ConstructL()
     {
     StartL( KMemSpyServerName );
+    
+    iShutdown.ConstructL();
+    // ensure that the server still exits even if the 1st client fails to connect
+    iShutdown.Start();
     }
 
 
@@ -79,6 +119,34 @@
 	return session;
     }
 
+void CMemSpyEngineServer::AddSession(TBool aCliRequest)
+    {
+    if (aCliRequest)
+        {
+        iCliConnected = ETrue;
+        }
+    else
+        {
+        ++iSessionCount;
+        }
+    iShutdown.Cancel();
+    }
+
+void CMemSpyEngineServer::DropSession(TBool aCliRequest)
+    {
+    if (!aCliRequest)
+        {
+        --iSessionCount;
+        }
+    
+    if (iSessionCount == 0 && !iCliConnected)
+        {
+        iShutdown.Start();
+        }
+    }
+
+
+
 
 
 
@@ -120,6 +188,8 @@
 #endif
 
     delete iClientThreadName;
+    
+    Server().DropSession(iIsCliRequest);
     }
 
 
@@ -138,10 +208,17 @@
     iClientThreadId = thread.Id();
 
     CleanupStack::PopAndDestroy( &thread );
-
+    
+    const TUid KCliUid3 = { 0x2002129D };
+    iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3);
+    
     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
     }
 
+void CMemSpyEngineSession::CreateL()
+    {   
+    Server().AddSession(iIsCliRequest);
+    }
 
 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
     {
@@ -162,13 +239,669 @@
         {
         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
         }
-    aMessage.Complete( error );
+    
+    if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone)
+    	{
+		aMessage.Complete( error );
+    	}
 
     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
 	}
 
+// ---------------------------------------------------------
+// DoServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+	{
+	TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
+	if (function >= EMemSpyClientServerOpMarkerUiFirst && 
+		function < EMemSpyClientServerOpMarkerUiLast)
+		
+		DoUiServiceL(aMessage);
+	else
+		DoCmdServiceL(aMessage);
+	}
+// ---------------------------------------------------------
+// DoUiServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
+    {
+	switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
+		{
+		case EMemSpyClientServerOpGetProcessCount:
+			{
+			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
+			break;
+			}
+		case EMemSpyClientServerOpGetProcesses:
+			{
+			CMemSpyEngineObjectContainer& list = iEngine.Container();
+			
+			TPckgBuf<TInt> a0;
+			aMessage.ReadL(0, a0);
+			TInt realCount = Min(a0(), list.Count());
+			
+			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
+				{
+				CMemSpyProcess& process = iEngine.Container().At(i);
+				TMemSpyProcessData data;
+				data.iIsDead = process.IsDead();
+				data.iId = process.Id();
+				data.iName.Copy(process.Name().Left(KMaxFullName));
+				data.iThreadCount = process.Count();
+				data.iPriority = process.Priority();
+				data.iExitType = process.ExitType();
+				data.iExitReason = process.ExitReason();
+				data.iExitCategory = process.ExitCategory();
+				data.iSID = process.SID();
+				
+				TPckgBuf<TMemSpyProcessData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}
+			
+			a0 = list.Count();
+			aMessage.WriteL(0, a0);
 
-void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+			break;
+			}
+		case EMemSpyClienServerOpGetProcessIdByName:
+			{
+			TFullName processName;
+			aMessage.ReadL(0, processName);
+			
+			TBool found(EFalse);
+			
+			for (TInt i=0; i<iEngine.Container().Count(); i++)
+				{
+				CMemSpyProcess& process = iEngine.Container().At(i);
+				if (process.Name().FindF(processName) >= 0)
+					{
+					found = ETrue;
+					TPckgBuf<TProcessId> procId(process.Id());
+					aMessage.WriteL(1, procId);
+					}
+				}
+			
+			if (!found)
+				{
+				User::Leave(KErrNotFound);
+				}
+			
+			break;
+			}
+		case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
+			{
+			TBool ret = EFalse;
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+			
+			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
+				{
+				ret = ETrue;
+				}
+			TPckgBuf<TBool> retBuf( ret );
+			aMessage.WriteL( 1, retBuf );
+			
+			break;
+			}
+		case EMemSpyClientServerOpEndProcess:
+			{
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyEndType> type;
+			aMessage.ReadL( 1, type );
+					
+			CMemSpyEngineObjectContainer& container = iEngine.Container();			
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+									
+			switch ( type() )
+				{
+				case ETerminate:
+					{
+					process.TerminateL();
+					break;
+					}
+				case EPanic:
+					{
+					process.PanicL();
+					break;
+					}
+				case EKill:
+					{
+					process.KillL();
+					break;
+					}
+				}																
+			break;
+			}
+		case EMemSpyClientServerOpSwitchToProcess:
+			{/*
+			TInt wgCount;
+			RWsSession wsSession;
+			User::LeaveIfError( wsSession.Connect() );
+			CleanupClosePushL( wsSession );
+			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+			CleanupClosePushL( wgArray );
+			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+			TApaTask task( wsSession );
+			TBool brought( EFalse );
+			TInt wgId( KErrNotFound );
+			TThreadId threadId;
+			
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+			
+			// loop trough threads in a process
+			for ( TInt i = 0; i < process.MdcaCount(); i++ )
+				{
+				TInt wgCountLocal = wgCount;
+							
+				// loop trough all window groups and see if a thread id matches
+				while( !brought && wgCountLocal-- )
+					{
+					wgId = wgArray[wgCountLocal].iId;
+					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+					if ( threadId == process.At( i ).Id() )
+						{
+						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+						task.SetWgId( wgId );
+						if ( !wgName->Hidden() && task.Exists() )
+							{
+							task.BringToForeground();
+							brought = ETrue;                        
+							}
+						CleanupStack::PopAndDestroy( wgName );
+						}
+					}
+				}
+			
+			TPckgBuf<TBool> ret( brought );
+			aMessage.WriteL( 1, ret );
+			
+			break;*/
+			}
+		case EMemSpyClientServerOpGetThreadCount:
+			{
+			TPckgBuf<TProcessId> pid;
+			aMessage.ReadL(1, pid);
+			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
+			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
+			break;
+			}
+		case EMemSpyClientServerOpGetThreads:
+			{
+			TPckgBuf<TProcessId> pid;
+			aMessage.ReadL(2, pid);
+			
+			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
+			
+			TPckgBuf<TInt> a0;
+			aMessage.ReadL(0, a0);
+			TInt realCount = Min(a0(), list.Count());
+						
+			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
+				{
+				CMemSpyThread& thread = list.At(i);
+				
+				TMemSpyThreadData data;
+				data.iId = thread.Id();
+				data.iName.Copy(thread.Name().Left(KMaxFullName));
+				data.iThreadPriority = thread.Priority();
+				
+				TPckgBuf<TMemSpyThreadData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}
+			
+			a0 = list.Count();
+			aMessage.WriteL(0, a0);
+
+			break;
+			}
+		case EMemSpyClientServerOpSetThreadPriority:
+			{
+			TPckgBuf<TThreadId> tid;
+			TPckgBuf<TInt> priority;
+			aMessage.ReadL(0, tid);
+			aMessage.ReadL(1, priority);
+			
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
+			
+			if (thread)
+				{				
+				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
+				}					
+			break;
+			}
+		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
+			{
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+			
+			TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() );
+			
+			TPckgBuf<TBool> retBuf( ret );
+			aMessage.WriteL( 1, retBuf );
+							
+			break;
+			}
+		case EMemSpyClientServerOpEndThread:
+			{
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyEndType> type;
+			aMessage.ReadL( 1, type );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+			
+			if( thread )
+				{
+				switch ( type() )
+					{
+					case ETerminate:
+						{
+						thread->TerminateL();
+						break;
+						}
+					case EPanic:
+						{
+						thread->PanicL();
+						break;
+						}
+					case EKill:
+						{
+						thread->KillL();
+						break;
+						}
+					}				
+				}			
+			break;
+			}
+		case EMemSpyClientServerOpSwitchToThread:
+			{
+			TInt wgCount;
+			RWsSession wsSession;
+			User::LeaveIfError( wsSession.Connect() );
+			CleanupClosePushL( wsSession );
+			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+			CleanupClosePushL( wgArray );
+			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+			TApaTask task( wsSession );
+			TBool brought( EFalse );
+			TInt wgId( KErrNotFound );
+			TThreadId threadId;
+					
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+					
+			// loop trough all window groups and see if a thread id matches
+			while( !brought && wgCount-- )
+				{
+				wgId = wgArray[wgCount].iId;
+				User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+				if ( threadId == id() )
+					{
+					CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+					task.SetWgId( wgId );
+					if ( !wgName->Hidden() && task.Exists() )
+						{
+						task.BringToForeground();
+						brought = ETrue;                        
+						}
+					CleanupStack::PopAndDestroy( wgName );
+					}
+				}			
+			TPckgBuf<TBool> ret( brought );
+			aMessage.WriteL( 1, ret );															
+					
+			break;
+			}		
+		case EMemSpyClientServerOpGetInfoItemType:
+			{
+			
+			TPckgBuf<TInt> index;
+			aMessage.ReadL( 0, index );			
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 1, id);
+								
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL; //not needed
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+		            
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
+			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
+			
+			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
+			aMessage.WriteL( 2, ret );			
+			
+			break;
+			}
+		case EMemSpyClientServerOpGetThreadInfoItemsCount:
+			{
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyThreadInfoItemType> type;
+			aMessage.ReadL( 1, type );					 
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			
+			container.ProcessAndThreadByThreadId( id(), process, thread );
+			
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
+								
+			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
+				    
+			TInt count = threadInfoItemBase.MdcaCount();		    
+			TPckgBuf<TInt> tempret( count );
+			aMessage.WriteL( 2, tempret );
+		
+			break;
+			}		
+		case EMemSpyClientServerOpGetThreadInfoItems:
+			{
+			TPckgBuf<TInt> count;
+			aMessage.ReadL( 0, count );						
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 1, id );
+			TPckgBuf<TMemSpyThreadInfoItemType> type;
+			aMessage.ReadL( 2, type );			
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
+							  
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
+
+			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
+			
+			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
+								
+			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
+				{
+				TMemSpyThreadInfoItemData data;
+				
+				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
+				TInt tabPos = caption.Locate('\t');
+				if (tabPos != KErrNotFound)
+					caption.Set(caption.Left(tabPos));
+				
+				TPtrC value(threadInfoItemBase.MdcaPoint(i));
+				tabPos = value.LocateReverse('\t');
+				if (tabPos != KErrNotFound)
+					value.Set(value.Mid(tabPos + 1));
+												
+				data.iCaption.Copy( caption.Left(64) );
+				data.iValue.Copy( value.Left(32) );
+							
+				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
+				aMessage.WriteL(3, buffer, offset);				
+				}			
+			aMessage.WriteL(0, count);
+					
+			break;
+			}
+		// --- KernelObjects related functions ---
+		case EMemSpyClientServerOpGetKernelObjectCount:
+			{
+			TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
+			TPckgBuf<TInt> ret( iCount );
+			aMessage.WriteL(0, ret);			
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjects:
+			{
+			TPckgBuf<TInt> count;
+			aMessage.ReadL(0, count);
+			
+			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
+			CleanupStack::PushL( model );
+			
+			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
+				{
+				TMemSpyKernelObjectData data;
+				
+				TPtrC name(model->At(i).Name().Mid(1));
+				TInt tabPos = name.Locate('\t');
+				if (tabPos != KErrNotFound)
+					name.Set(name.Left(tabPos));
+												
+				data.iName.Copy(name);
+				data.iType = model->At(i).Type();
+				data.iCount = model->At(i).Count();											
+				data.iSize = model->At(i).Count() * model->At(i).Count();
+
+				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}			
+			aMessage.WriteL(0, count);
+			CleanupStack::PopAndDestroy( model );
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjectItemCount:
+			{
+			TPckgBuf<TMemSpyDriverContainerType> tempType;
+			aMessage.ReadL(1, tempType); //get type of kernel object
+			TMemSpyDriverContainerType type = tempType();
+			
+			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
+			CleanupStack::PushL( iObjectList );
+			
+			TInt count = iObjectList->Count();
+			TPckgBuf<TInt> ret( count );
+			aMessage.WriteL( 0, ret );
+			
+			CleanupStack::PopAndDestroy( iObjectList );
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjectItems:
+			{
+			TPckgBuf<TInt> count;
+			TPckgBuf<TMemSpyDriverContainerType> tempType;
+			aMessage.ReadL( 0, count ); //get count of items
+			aMessage.ReadL(1, tempType); //get type of kernel object
+			TInt c = count();
+						
+			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
+			CleanupStack::PushL( iObjectList );
+			
+			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
+				{
+				TMemSpyDriverHandleInfoGeneric data;								
+															
+				data = iObjectList->At( i );
+				
+				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
+				aMessage.WriteL(2, buffer, offset);
+				}			
+			
+			CleanupStack::PopAndDestroy( iObjectList );			
+			break;
+			}
+			
+		case EMemSpyClientServerOpOutputAllContainerContents:
+			{
+			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+			CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
+			
+			model->OutputL( iEngine.Sink() );
+
+			break;
+			}
+			
+		case EMemSpyClientServerOpDumpKernelHeap:
+			{
+		    iEngine.HelperHeap().OutputHeapDataKernelL();
+			
+			break;
+			}
+			
+		case EMemSpyClientServerOpOutputInfoHandles:
+			{
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL(0, id);
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
+										  
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
+			
+			threadInfoContainer.PrintL();
+			
+			break;
+			}
+			
+		case EMemSpyClientServerOpOutputAOList:
+			{
+			TPckgBuf<TThreadId> id;
+			TPckgBuf<TMemSpyThreadInfoItemType> type;
+			aMessage.ReadL(0, id);
+			aMessage.ReadL(1, type);
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
+										  
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
+
+			CMemSpyThreadInfoItemBase* threadInfoItem = &threadInfoContainer.Item( type() );
+						
+			CMemSpyThreadInfoActiveObjects* activeObjectArray = static_cast< CMemSpyThreadInfoActiveObjects* >( threadInfoItem );			
+						
+		    // Begin a new data stream
+		    _LIT( KMemSpyContext, "Active Object List - " );
+		    _LIT( KMemSpyFolder, "Active Objects" );
+		    iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder );
+		    		    
+		    // Set prefix for overall listing
+		    iEngine.Sink().OutputPrefixSetLC( KMemSpyContext );
+
+		    // Create header
+		    CMemSpyEngineActiveObjectArray::OutputDataColumnsL( iEngine );
+		    
+		    // List items
+		    const TInt count = activeObjectArray->Array().Count();
+		    for(TInt i=0; i<count; i++)
+		        {
+		        const CMemSpyEngineActiveObject& object = activeObjectArray->Array().At( i );
+		        //
+		        object.OutputDataL( iEngine );
+		        }
+
+		    // Tidy up
+		    CleanupStack::PopAndDestroy(); // prefix
+
+		    // End data stream		    		    
+		    iEngine.Sink().DataStreamEndL();		    
+			
+			break;
+			}
+			
+		// --- Kernel Heap related functions ---
+		case EMemSpyClientServerOpGetHeap:
+			{
+			TMemSpyHeapInfo heapInfo;			
+			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
+			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
+			
+			TPckgBuf<TMemSpyHeapData> buffer(data);
+			aMessage.WriteL(0, buffer);
+			
+			break;
+			}
+		
+		case EMemSpyClientServerOpGetMemoryTrackingCycleCount:
+			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.HelperSysMemTracker().CompletedCycles().Count()));
+			break;
+			
+		case EMemSpyClientServerOpGetMemoryTrackingCycles:
+			{
+			const RPointerArray<CMemSpyEngineHelperSysMemTrackerCycle>& list = iEngine.HelperSysMemTracker().CompletedCycles();
+
+			TPckgBuf<TInt> a0;
+			aMessage.ReadL(0, a0);
+			TInt realCount = Min(a0(), list.Count());
+			
+			for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyMemoryTrackingCycleData))
+				{
+				CMemSpyProcess& process = iEngine.Container().At(i);
+				TMemSpyMemoryTrackingCycleData data;
+				data.iCycleNumber = list[i]->CycleNumber();
+				data.iCaption.Copy(list[i]->Caption().Left(KMaxFullName));
+				data.iTime = list[i]->Time();
+				data.iFreeMemory = list[i]->MemoryFree();
+				data.iMemoryDelta = list[i]->MemoryDelta();
+				data.iPreviousCycleDiff = list[i]->MemoryFreePreviousCycle();
+				
+				TPckgBuf<TMemSpyMemoryTrackingCycleData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}
+			
+			a0 = list.Count();
+			aMessage.WriteL(0, a0);
+
+		break;
+		}
+	case EMemSpyClientServerOpIsSwmtRunning:
+		{
+		TPckgBuf<TBool> running(iEngine.HelperSysMemTracker().IsActive());
+		aMessage.WriteL(0, running);
+		break;
+		}
+			
+		
+	case EMemSpyClientServerOpNotifyDeviceWideOperationProgress:
+		{
+		if (!Server().CurrentOperationTracker())
+			{
+			User::Leave(KErrNotReady);
+			}
+		
+		Server().CurrentOperationTracker()->AddNotificationL(aMessage);
+		break;
+		}
+		
+	case EMemSpyClientServerOpCancelDeviceWideOperation:
+		if (!Server().CurrentOperationTracker())
+			{
+			User::Leave(KErrNotReady);
+			}
+		
+		Server().CurrentOperationTracker()->Cancel();
+		break;
+		}
+    }
+
+// ---------------------------------------------------------
+// DoCmdServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
     {
     TInt error = KErrNone;
 
@@ -382,16 +1115,31 @@
 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
     {
     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
+    
     //
     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
         {
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
-        iEngine.HelperHeap().OutputHeapInfoForDeviceL();
+        if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
+        	{
+			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage);
+        	}
+        else
+        	{
+			iEngine.HelperHeap().OutputHeapInfoForDeviceL();
+        	}
         }
     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
         {
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
-        iEngine.HelperStack().OutputStackInfoForDeviceL();
+        if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
+			{
+			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage);
+			}
+		else
+			{
+			iEngine.HelperStack().OutputStackInfoForDeviceL();
+			}
         }
     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
         {
@@ -481,12 +1229,31 @@
     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
         {
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
-        iEngine.InstallSinkL( ESinkTypeDebug );
+        iEngine.InstallDebugSinkL();
         }
     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
         {
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
-        iEngine.InstallSinkL( ESinkTypeFile );
+        // Read file name from message.
+        TFileName fileName;
+        RBuf buf;
+		buf.CleanupClosePushL();
+		
+		TInt len = aMessage.GetDesLength( 0 );
+		if ( len > 0 )
+			{
+			buf.CreateL( len );
+			aMessage.ReadL( 0, buf, 0 );
+			
+			iEngine.InstallFileSinkL( buf );           
+			}
+		else
+			{
+			iEngine.InstallFileSinkL( KNullDesC );
+			}
+		
+		CleanupStack::PopAndDestroy( &buf );
+        
         }
     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
         {
@@ -517,6 +1284,46 @@
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
         }
+    else if ( aFunction == EMemSpyClientServerOpSummaryInfo )
+    	{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfo") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralSummary, aMessage);
+    	}
+    else if ( aFunction == EMemSpyClientServerOpSummaryInfoDetailed )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfoDetailed") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpHeapInfo )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfo") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapInfo, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpHeapCellListing )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapCellListing") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapCellListing, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpHeapData )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapData") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapData, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpStackInfo )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfo") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackInfo, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpStackDataUser )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataUser") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataUser, aMessage);
+		}
+    else if ( aFunction == EMemSpyClientServerOpStackDataKernel )
+		{
+		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataKernel") );
+		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataKernel, aMessage);
+		}
     else
         {
         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
@@ -526,7 +1333,108 @@
     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
     }
 
+void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage)
+	{
+	if (Server().CurrentOperationTracker())
+		{
+		User::Leave(KErrInUse);
+		}
+	
+	Server().SetCurrentOperationTracker(CMemSpyDwOperationTracker::NewL(aOperation, aMessage, Server()));
+	}
+
+
+
+
+
 
 
 
 
+CMemSpyDwOperationTracker* CMemSpyDwOperationTracker::NewL(CMemSpyDeviceWideOperations::TOperation aOperation, 
+		const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer)
+	{
+	CMemSpyDwOperationTracker* self = new (ELeave) CMemSpyDwOperationTracker(aOperationMessage, aServer);
+	CleanupStack::PushL( self );
+	self->ConstructL(aOperation);
+	CleanupStack::Pop( self );
+	return self;
+	}
+	
+CMemSpyDwOperationTracker::~CMemSpyDwOperationTracker()
+	{
+	delete iOperation;
+	delete iPendingNotifications;
+	}
+
+CMemSpyDwOperationTracker::CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) : 
+		iOperationMessage(aOperationMessage),
+		iServer(aServer),
+		iPendingNotifications(0),
+		iOperation(0),
+		iProgress(0)
+	{
+	}
+
+
+void CMemSpyDwOperationTracker::ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation)
+	{
+	iPendingNotifications = new (ELeave) CArrayFixFlat<RMessage2>(3);
+	iOperation = CMemSpyDeviceWideOperations::NewL(iServer.Engine(), *this, aOperation);
+	}
+
+void CMemSpyDwOperationTracker::AddNotificationL(const RMessage2& aMessage)
+	{
+	iPendingNotifications->AppendL(aMessage);
+	}
+
+void CMemSpyDwOperationTracker::Cancel()
+	{
+	iOperation->Cancel();
+	}
+
+void CMemSpyDwOperationTracker::HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2)
+	{
+	switch( aEvent )
+		{
+	case MMemSpyDeviceWideOperationsObserver::EOperationCompleted:
+	case MMemSpyDeviceWideOperationsObserver::EOperationCancelled:
+		iServer.SetCurrentOperationTracker(0);
+		
+		for (TInt i=0; i<iPendingNotifications->Count(); i++)
+			{
+			iPendingNotifications->At(i).Complete(KErrCancel);
+			}
+		
+		if (iOperationMessage.Function() & KMemSpyOpFlagsAsyncOperation)
+			{
+			iOperationMessage.Complete(
+				aEvent == MMemSpyDeviceWideOperationsObserver::EOperationCompleted ? KErrNone : KErrCancel);
+			}
+		
+		iPendingNotifications->Reset();
+		
+		delete this;
+		break;
+		
+	case MMemSpyDeviceWideOperationsObserver::EOperationProgressEnd:
+		{
+		iProgress += aParam1;
+		for (TInt i=0; i<iPendingNotifications->Count(); i++)
+			{
+			TInt err;
+			TRAP(err, iPendingNotifications->At(i).WriteL(0, TPckgBuf<TInt>( iProgress * 100 / iOperation->TotalOperationSize() )));
+			TRAP(err, iPendingNotifications->At(i).WriteL(1, aParam2));
+			if (err != KErrNone)
+				{
+				// TODO: iPendingProgressNotifications->At(i).Panic()
+				}
+			iPendingNotifications->At(i).Complete(KErrNone);
+			}
+		iPendingNotifications->Reset();
+		break;
+		}
+		
+		}
+	
+	}
--- a/memspy/Engine/Source/DeviceWideOps/MemSpyDeviceWideOperations.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/DeviceWideOps/MemSpyDeviceWideOperations.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -286,9 +286,10 @@
         break;
     case EPerEntityHeapData:
         // Complete op by outputting kernel heap data
-        pType.Set( KMemSpyUiThreadNameKernel );
-        iObserver.HandleDeviceWideOperationEvent( MMemSpyDeviceWideOperationsObserver::EOperationProgressStart, 0, pType );
-        iEngine.HelperHeap().OutputHeapDataKernelL();
+        // TODO: Uncomment after kernel heap dump is fixed
+//        pType.Set( KMemSpyUiThreadNameKernel );
+//        iObserver.HandleDeviceWideOperationEvent( MMemSpyDeviceWideOperationsObserver::EOperationProgressStart, 0, pType );
+//        iEngine.HelperHeap().OutputHeapDataKernelL();
         break;
     default:
         break;
--- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperActiveObject.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperActiveObject.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -101,7 +101,7 @@
     //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - allocated cell header length is: %d", iHeapInfo.iHeapCellHeaderLengthAllocated);
 
     // Do we have a ROM-based scheduler pointer?
-    if  ( scheduler != NULL && iHeapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
+    if  ( scheduler != NULL && iHeapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown )
         {
         //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - scheduler: 0x%08x", scheduler);
 
@@ -149,9 +149,9 @@
     //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType);
     User::LeaveIfError( err );
     
-    if  ( cellType == EMemSpyDriverGoodAllocatedCell )
+	if (cellType & EMemSpyDriverAllocatedCellMask)
         {
-        const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated();
+        const TInt payloadLength = cellLength;
         HBufC8* data = HBufC8::NewLC( payloadLength );
         TPtr8 pData( data->Des() );
         //
@@ -281,9 +281,9 @@
     //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType);
     User::LeaveIfError( err );
     
-    if  ( cellType == EMemSpyDriverGoodAllocatedCell )
+    if (cellType & EMemSpyDriverAllocatedCellMask)
         {
-        const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated();
+        const TInt payloadLength = cellLength;
         //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - payloadLength: %d", payloadLength);
 
         // const TInt payloadLength = Max( 512, cellLength - iHeapInfo.iHeapCellHeaderLengthAllocated ); // Prevent negative payload lengths?
--- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -300,12 +300,11 @@
     // Get the heap info - we need this for verification purposes
     TMemSpyHeapInfo info;
     TInt err = iEngine.Driver().GetHeapInfoUser( info, aFbServThread.Id() );
-    if ( err == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeRHeap )
+    if ( err == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeUnknown )
         {
         err = KErrNotSupported;
         }
     User::LeaveIfError( err );
-    TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - allocated cell header length is: %d", info.AsRHeap().MetaData().HeaderSizeAllocated() ));
 
     // Now walk the heap!
     err = iEngine.Driver().WalkHeapInit( aFbServThread.Id() );
@@ -324,13 +323,12 @@
             err = iEngine.Driver().WalkHeapNextCell( aFbServThread.Id(), cellType, cellAddress, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
             TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - cellIndex[%d] err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", cellIndex, err, cellLength, cellAllocationNumber, cellType));
 
-            if  ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell )
+            if  ( err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask))
                 {
                 // We know we are looking for a relatively large *allocated* cell.
-                if  ( cellLength >= KFbServExpectedMinimumCellSize && cellLength <= KFbServExpectedMaximumCellSize && cellType == EMemSpyDriverGoodAllocatedCell )
+                if  ( cellLength >= KFbServExpectedMinimumCellSize && cellLength <= KFbServExpectedMaximumCellSize )
                     {
-                    const TInt payloadLength = cellLength - info.AsRHeap().MetaData().HeaderSizeAllocated();
-                    TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - cell was long enough. Full cell len: %d, header: %d, therefore dataLen: %d", cellLength, info.AsRHeap().MetaData().HeaderSizeAllocated(), payloadLength));
+                    const TInt payloadLength = cellLength;
 
                     // This is *probably* the right cell. Let's get the data and check.
                     HBufC8* data = HBufC8::NewLC( payloadLength );
@@ -345,9 +343,9 @@
                         //iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) cellAddress, pData.Length() );
                     
                         // Check the data
-                        const TUint heapSize = info.AsRHeap().ObjectData().Size();
-                        const TUint heapBaseAddress = (TUint) info.AsRHeap().ObjectData().Base();
-                        const TBool correctHeapCellLocated = VerifyCorrectHeapCellL( *data, cellAddress, cellPayloadAddress, heapBaseAddress, heapSize );
+                        const TUint heapMaxSize = info.AsRHeap().MetaData().iMaxHeapSize;
+                        const TUint heapBaseAddress = (TUint) info.AsRHeap().MetaData().ChunkBaseAddress();
+                        const TBool correctHeapCellLocated = VerifyCorrectHeapCellL( *data, cellAddress, cellPayloadAddress, heapBaseAddress, heapMaxSize );
                         TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - verified: %d", correctHeapCellLocated));
 
                         if  ( correctHeapCellLocated )
@@ -404,7 +402,7 @@
     TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
     TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType));
 
-    if  ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell )
+	if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask))
         {
         // Check that the cell size meets our expectations - it should be a CObjectCon cell.
         const TInt expectedCellSize = sizeof(CObjectCon*) + cellHeaderSize;
@@ -520,7 +518,7 @@
     TInt err = iEngine.Driver().WalkHeapGetCellInfo( aArrayCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
     TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aArrayCellAddress, cellLength, cellAllocationNumber, cellType));
 
-    if  ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell )
+    if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask))
         {
         // Check that the cell size meets our expectations. 
         // The cell should be a very specific length
@@ -577,13 +575,13 @@
     }
 
 
-TBool CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapSize )
+TBool CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapMaxSize )
     {
     (void) aPayloadAddress;
     (void) aCellAddress;
-    TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - START - aDataLen: %d, aCellAddress: 0x%08x, aPayloadAddress: 0x%08x, aHeapStartingAddress: 0x%08x, aHeapSize: %d", aData.Length(), aCellAddress, aPayloadAddress, aHeapStartingAddress, aHeapSize ));
+    TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - START - aDataLen: %d, aCellAddress: 0x%08x, aPayloadAddress: 0x%08x, aHeapStartingAddress: 0x%08x, aHeapSize: %d", aData.Length(), aCellAddress, aPayloadAddress, aHeapStartingAddress, aHeapMaxSize ));
 
-    const TUint KFbServHeapCeilingAddress = aHeapStartingAddress + aHeapSize;
+    const TUint KFbServHeapCeilingAddress = aHeapStartingAddress + aHeapMaxSize;
 
     // Whether we can use this cell's data...
     TBool correctCell = EFalse;
@@ -746,7 +744,7 @@
     TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
     TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType));
 
-    if  ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell )
+    if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask))
         {
         // Check that the cell size meets our expectations - it should be a CBitmapObject, but without the additional "this" pointer
         // which we have tacked onto the object.
--- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -45,6 +45,7 @@
 _LIT( KCellTypeBadAllocatedCellAddress,  "[Bad Allocated Cell Address]");
 _LIT( KCellTypeBadFreeCellAddress,       "[Bad Free Cell Address]     ");
 _LIT( KCellTypeBadFreeCellSize,          "[Bad Free Cell Size]        ");
+_LIT( KCellTypeBad,                      "[Bad Cell]                  ");
 _LIT( KCellTypeUnknown,                  "[Unknown!]                  ");
 _LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d");
 _LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" );
@@ -104,7 +105,7 @@
         {
         UpdateSharedHeapInfoL( aThread.Process().Id(), aThread.Id(), heapInfo );
         }
-    if  ( error == KErrNone && heapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
+    if  ( error == KErrNone && heapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown )
         {
         // Get thread name for context
         const TFullName pName( aThread.FullName() );
@@ -159,36 +160,43 @@
                 TUint fourByteCellData = 0;
                 TPtrC pType(KNullDesC);
                 //
-                switch(cellType)
-                    {
-                case EMemSpyDriverGoodAllocatedCell:
-                    {
+				if (cellType & EMemSpyDriverAllocatedCellMask)
+					{
                     r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 );
                     if  ( r == KErrNone )
                         {
                         fourByteCellData = DescriptorAsDWORD( cellData );
                         }
                     pType.Set(KCellTypeGoodAllocatedCell);
-                    break;
                     }
-                case EMemSpyDriverGoodFreeCell:
+				else if (cellType & EMemSpyDriverFreeCellMask)
+					{
                     pType.Set(KCellTypeGoodFreeCell);
-                    break;
-                case EMemSpyDriverBadAllocatedCellSize:
-                    pType.Set(KCellTypeBadAllocatedCellSize);
-                    break;
-                case EMemSpyDriverBadAllocatedCellAddress:
-                    pType.Set(KCellTypeBadAllocatedCellAddress);
-                    break;
-                case EMemSpyDriverBadFreeCellAddress:
-                    pType.Set(KCellTypeBadFreeCellAddress);
-                    break;
-                case EMemSpyDriverBadFreeCellSize:
-                    pType.Set(KCellTypeBadFreeCellSize);
-                    break;
-                default:
+					}
+				else if (cellType & EMemSpyDriverBadCellMask)
+					{
+					switch (cellType)
+						{
+					case EMemSpyDriverHeapBadAllocatedCellSize:
+						pType.Set(KCellTypeBadAllocatedCellSize);
+						break;
+					case EMemSpyDriverHeapBadAllocatedCellAddress:
+						pType.Set(KCellTypeBadAllocatedCellAddress);
+						break;
+					case EMemSpyDriverHeapBadFreeCellAddress:
+						pType.Set(KCellTypeBadFreeCellAddress);
+						break;
+					case EMemSpyDriverHeapBadFreeCellSize:
+						pType.Set(KCellTypeBadFreeCellSize);
+						break;
+					default:
+						pType.Set(KCellTypeBad);
+						break;
+						}
+					}
+				else
+					{
                     pType.Set(KCellTypeUnknown);
-                    break;
                     }
 
                 if  ( r == KErrNone )
@@ -241,31 +249,30 @@
     // Make sure the process is suspended for the entire time we are manipulating it's heap
     iEngine.ProcessSuspendLC( aThread.Process().Id() );
 
-    // Get the heap info, including free cell information
-    RArray<TMemSpyDriverFreeCell> freeCells;
-    CleanupClosePushL( freeCells );
+    // Get the heap info, including cell information
+    RArray<TMemSpyDriverCell> cells;
+    CleanupClosePushL( cells );
     TMemSpyHeapInfo heapInfo;
     TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
-    GetHeapInfoUserL( aThread.Process().Id(), aThread.Id(), heapInfo, &freeCells );
+    GetHeapInfoUserL(aThread.Process().Id(), aThread.Id(), heapInfo, &cells, ETrue);
     TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
 
     // Get the heap data
     const TFullName pName( aThread.FullName() );
-    OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &freeCells );
-    CleanupStack::PopAndDestroy( &freeCells );
+    OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &cells );
+    CleanupStack::PopAndDestroy( &cells );
 
     // Resume process
     CleanupStack::PopAndDestroy();
     }
 
 
-EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverFreeCell>* aFreeCells )
+EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells)
     {
-    OutputHeapDataUserL( aPid, aTid, aThreadName, aInfo, ETrue, aFreeCells );
+    OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells);
     }
 
-
-void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverFreeCell>* aFreeCells )
+void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverCell>* aCells )
     {
     TBuf<KMaxFullName + 100> printFormat;
 
@@ -291,7 +298,7 @@
     iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &aThreadName );
 
     // Info section
-    OutputHeapInfoL( aInfo, aThreadName, aFreeCells );
+    OutputHeapInfoL( aInfo, aThreadName, aCells );
 
     // Code segments (needed for map file reading...)
     _LIT(KCellListCodeSegInfoFormat, "CodeSegs - ");
@@ -315,14 +322,25 @@
     TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) );
 
     TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining );
-    if  ( r == KErrNone )
+	TUint prevEndAddress = readAddress + pData.Length();
+    if (r == KErrNone)
         {
-        while ( r == KErrNone )
+        while (r == KErrNone)
             {
+			if (readAddress > prevEndAddress)
+				{
+				// We've hit a discontinuity, ie one or more unmapped pages
+				_LIT(KBreak, "........");
+				iEngine.Sink().OutputLineL(KBreak);
+				}
             _LIT(KHeapDumpDataFormat, "%S");
-            iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length() );
-            if  ( remaining > 0 )
-                r = iEngine.Driver().GetHeapDataNext( aTid, pData, readAddress, remaining );
+            iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length());
+			readAddress += pData.Length();
+            if (remaining > 0)
+				{
+				prevEndAddress = readAddress;
+                r = iEngine.Driver().GetHeapDataNext(aTid, pData, readAddress, remaining);
+				}
             else
                 break;
             }
@@ -365,11 +383,9 @@
 
 
 
-
-
-EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray<TMemSpyDriverFreeCell>* aFreeCells )
-    {
-    CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC( aInfo, aFreeCells );
+EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray<TMemSpyDriverCell>* aCells )
+	{
+    CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC(aInfo, aCells);
 
     // Format the thread name according to upper/lower case request parameters
     _LIT( KOverallCaption1, "HEAP INFO FOR THREAD '%S'");
@@ -416,7 +432,6 @@
     {
     const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
     const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
-    const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData();
     const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
 
     // Example:
@@ -456,20 +471,20 @@
                                          aIndex,
                                          aInfo.Tid(),
                                          rHeapMetaData.ChunkHandle(),
-                                         rHeapObjectData.Base(),
-                                         rHeapObjectData.Size(),
-                                         rHeapObjectData.iMinLength,
-                                         rHeapObjectData.iMaxLength,
-                                         rHeapObjectData.iFree.next,
-                                         rHeapObjectData.iFree.len,
+                                         /*rHeapObjectData.Base(),*/ rHeapMetaData.iAllocatorAddress,
+                                         /*rHeapObjectData.Size(),*/ rHeapMetaData.iHeapSize,
+                                         /*rHeapObjectData.iMinLength,*/ rHeapMetaData.iMinHeapSize,
+                                         /*rHeapObjectData.iMaxLength,*/ rHeapMetaData.iMaxHeapSize,
+                                         /*rHeapObjectData.iFree.next,*/ NULL,
+                                         /*rHeapObjectData.iFree.len,*/ 0,
                                          rHeapStats.StatsFree().TypeCount(),
                                          rHeapStats.StatsFree().TypeSize(),
                                          rHeapStats.StatsFree().SlackSpaceCellSize(),
                                          rHeapStats.StatsFree().LargestCellSize(),
                                          rHeapStats.StatsAllocated().LargestCellSize(),
-                                         rHeapObjectData.iCellCount,
-                                         rHeapObjectData.iMinCell,
-                                         rHeapObjectData.iTotalAllocSize,
+                                         /*rHeapObjectData.iCellCount,*/ rHeapStats.StatsAllocated().TypeCount(),
+                                         /*rHeapObjectData.iMinCell,*/ 0,
+                                         /*rHeapObjectData.iTotalAllocSize,*/ rHeapStats.StatsAllocated().TypeSize(),
                                          rHeapMetaData.IsSharedHeap(),
                                          &KFmtFields,
                                          aIndex
@@ -519,7 +534,7 @@
         // Get kernel heap info
         GetHeapInfoKernelL( info );
 
-        if ( info.Type() == TMemSpyHeapInfo::ETypeRHeap )
+        if ( info.Type() != TMemSpyHeapInfo::ETypeUnknown )
             {
             TName threadName;
             MemSpyEngineUtils::GetKernelHeapThreadAndProcessNames( threadName, processName );
@@ -546,7 +561,7 @@
                     {
                     UpdateSharedHeapInfoL( process.Id(), thread.Id(), info );
                     }
-                if  ( error == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeRHeap )
+                if  ( error == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeUnknown )
                     {
                     OutputCSVEntryL( index++, info, threadName, processName );
                     }
@@ -577,16 +592,21 @@
 
 
 
-EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells )
+EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells)
+    {
+	GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse);
+	}
+
+EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverCell>* aCells, TBool aCollectAllocatedCellsAsWellAsFree)
     {
     iEngine.ProcessSuspendLC( aProcess );
     TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
     
     TInt r = KErrNone;
     //
-    if  ( aFreeCells )
+    if  (aCells)
         {
-        r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aFreeCells );
+        r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aCells, aCollectAllocatedCellsAsWellAsFree);
         }
     else
         {
@@ -736,9 +756,11 @@
     _LIT(KHeaderDump, "Heap Data");
     iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' );
 
-    _LIT(KHeapDumpDataFormat, "%S");
+    /*TOMSCI TODO this stuff needs fixing
+	_LIT(KHeapDumpDataFormat, "%S");
     const TUint8* heapBaseAddress = info.AsRHeap().ObjectData().Base();
     iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, data->Ptr(), heapBaseAddress, data->Length() );
+	*/
 
     CleanupStack::PopAndDestroy(); // clear prefix
     CleanupStack::PopAndDestroy( data );
@@ -795,22 +817,29 @@
         _LIT( KItem0_Type_Unknown, "Unknown" );
         list->AddItemL( KItem0, KItem0_Type_Unknown );
         }
-    else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
+    else
         {
         const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
         const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData();
-        const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData();
         const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics();
 
         _LIT( KItem0_Type_RHeap, "RHeap" );
-        list->AddItemL( KItem0, KItem0_Type_RHeap );
+        _LIT( KItem0_Type_RHybridHeap, "RHybridHeap" );
+		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
+			{
+	        list->AddItemL( KItem0, KItem0_Type_RHeap );
+			}
+		else
+			{
+	        list->AddItemL( KItem0, KItem0_Type_RHybridHeap );
+			}
 
         // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. 
         _LIT( KItem1, "Heap size" );
-        list->AddItemL( KItem1, objectData.Size() );
+        list->AddItemL(KItem1, metaData.iHeapSize);
 
-        _LIT( KItem8b, "Heap base address" );
-        list->AddItemHexL( KItem8b, (TUint) objectData.Base() );
+        _LIT( KItem8b, "Allocator address" );
+        list->AddItemHexL( KItem8b, (TUint)metaData.iAllocatorAddress );
         
         _LIT( KItem1b, "Shared" );
         list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() );
@@ -845,34 +874,21 @@
         // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring
         // any slack space at the end (which can often be recovered, to the granularity of one page of ram)
         _LIT( KItem8a, "Fragmentation" );
-        list->AddItemPercentageL( KItem8a, objectData.Size(), ( statistics.StatsFree().TypeSize()  - statistics.StatsFree().SlackSpaceCellSize() ) );
-
-        _LIT( KItem13, "Header size (A)" );
-        list->AddItemL( KItem13, metaData.HeaderSizeAllocated() );
-
-        _LIT( KItem14, "Header size (F)" );
-        list->AddItemL( KItem14, metaData.HeaderSizeFree() );
+        list->AddItemPercentageL( KItem8a, metaData.iHeapSize, ( statistics.StatsFree().TypeSize()  - statistics.StatsFree().SlackSpaceCellSize() ) );
 
-        _LIT( KItem9a, "Overhead (alloc)" );
-        const TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount();
-        list->AddItemL( KItem9a, allocOverhead );
-
-        _LIT( KItem9b, "Overhead (free)" );
-        const TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount();
-        list->AddItemL( KItem9b, freeOverhead );
 
         _LIT( KItem9c, "Overhead (total)" );
-        const TInt totalOverhead = freeOverhead + allocOverhead;
+		const TInt totalOverhead = metaData.iHeapSize - statistics.StatsAllocated().TypeSize();
         list->AddItemL( KItem9c, totalOverhead );
 
         _LIT( KItem9d, "Overhead" );
-        list->AddItemPercentageL( KItem9d, objectData.Size(), totalOverhead  );
+        list->AddItemPercentageL( KItem9d, metaData.iHeapSize, totalOverhead  );
 
         _LIT( KItem10, "Min. length" );
-        list->AddItemL( KItem10, objectData.iMinLength );
+        list->AddItemL( KItem10, metaData.iMinHeapSize );
 
         _LIT( KItem11, "Max. length" );
-        list->AddItemL( KItem11, objectData.iMaxLength );
+        list->AddItemL( KItem11, metaData.iMaxHeapSize );
 
         _LIT( KItem12, "Debug Allocator Library" );
         list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() );
@@ -882,17 +898,16 @@
     }
 
 
-EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverFreeCell>* aFreeCells )
-    {
+EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells )
+	{
     CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() );
     //
     AppendMetaDataL( aInfo, *list );
-    AppendObjectDataL( aInfo, *list );
     AppendStatisticsL( aInfo, *list );
     //
-    if  ( aFreeCells )
+    if  ( aCells )
         {
-        AppendFreeCellsL( *aFreeCells, *list );
+        AppendCellsL( *aCells, *list );
         }
     //
     return list;
@@ -902,27 +917,34 @@
 //cigasto: not formatted - raw heap info 
 EXPORT_C TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo( const TMemSpyHeapInfo& aInfo )
 	{
+	_LIT(KUnknown, "Unknown");
 	TMemSpyHeapData list;
+	list.iType.Copy(KUnknown);
 
 	// Heap type	
-	if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
-		{
-		_LIT( KItem0_Type_Unknown, "Unknown" );
-		list.iType.Append( KItem0_Type_Unknown );
-		}
-	else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
+	if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown)
 		{
 		const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
 		const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData();
-		const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData();
 		const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics();
 
-		_LIT( KItem0_Type_RHeap, "RHeap" );
-		list.iType.Append( KItem0_Type_RHeap );
+		_LIT(KRHeap, "RHeap");
+		_LIT(KRHybridHeap, "RHybridHeap");
+		switch (aInfo.Type())
+			{
+			case TMemSpyHeapInfo::ETypeRHeap:
+				list.iType.Copy(KRHeap);
+				break;
+			case TMemSpyHeapInfo::ETypeRHybridHeap:
+				list.iType.Copy(KRHybridHeap);
+				break;
+			default:
+				break;
+			}
 
-	    // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. 	    
-	    list.iSize = objectData.Size();
-	    list.iBaseAddress = (TUint) objectData.Base();	        
+	    // Heap size is the total amount of memory committed to the heap, which includes the size of the embedded (in-place) RHeap/RHybridHeap.
+	    list.iSize = metaData.iHeapSize;
+	    list.iBaseAddress = (TUint)metaData.iAllocatorAddress; // TODO we can't do the base address any more, allocator address is the closest thing
 	    list.iShared = metaData.IsSharedHeap();
 	    list.iChunkSize = metaData.ChunkSize();
 	    list.iAllocationsCount = statistics.StatsAllocated().TypeCount();
@@ -933,16 +955,16 @@
 	    list.iTotalFree =  statistics.StatsFree().TypeSize();
 	    list.iSlackFreeSpace = statistics.StatsFree().SlackSpaceCellSize();
 	    list.iFragmentation = statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize(); //to calculate percentage value use iSize as 100% value
-	    list.iHeaderSizeA = metaData.HeaderSizeAllocated();
-	    list.iHeaderSizeF = metaData.HeaderSizeFree();
-	    TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount();
+	    list.iHeaderSizeA = 0; //metaData.HeaderSizeAllocated();
+	    list.iHeaderSizeF = 0; //metaData.HeaderSizeFree();
+	    TInt allocOverhead = rHeap.Overhead(); //metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount();
 	    list.iAllocationOverhead = allocOverhead;
-	    TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount();
-	    list.iFreeOverhead = freeOverhead;
-	    list.iTotalOverhead = freeOverhead + allocOverhead;
-	    list.iOverhead = freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value    
-	    list.iMinLength = objectData.iMinLength;
-	    list.iMaxLength = objectData.iMaxLength;
+	    //TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount();
+	    list.iFreeOverhead = 0; // TODO there is no way of calculating this
+	    list.iTotalOverhead = allocOverhead; // freeOverhead + allocOverhead
+	    list.iOverhead = allocOverhead; //freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value    
+	    list.iMinLength = metaData.iMinHeapSize;
+	    list.iMaxLength = metaData.iMaxHeapSize;
 	    list.iDebugAllocatorLibrary = metaData.IsDebugAllocator();
 		}
 
@@ -1001,7 +1023,7 @@
 
     // Type
     _LIT( KMetaData_Type,  "Type:" );
-    if ( aInfo.Type() != TMemSpyHeapInfo::ETypeRHeap )
+    if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
         {
         _LIT( KMetaData_Type_Unknown,  "Unknown" );
         aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown );
@@ -1012,15 +1034,23 @@
     
         // Type
         _LIT( KMetaData_Type_RHeap,  "Symbian OS RHeap" );
-        aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap );
+        _LIT( KMetaData_Type_RHybridHeap,  "Symbian OS RHybridHeap" );
+		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
+			{
+	        aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap );
+			}
+		else
+			{
+			aList.AddItemL( KMetaData_Type, KMetaData_Type_RHybridHeap );
+			}
 
         // VTable
-        _LIT( KMetaData_VTable,  "VTable:" );
-        aList.AddItemHexL( KMetaData_VTable, metaData.VTable() );
+        //_LIT( KMetaData_VTable,  "VTable:" );
+        //aList.AddItemHexL( KMetaData_VTable, metaData.VTable() );
 
         // Object size
-        _LIT( KMetaData_ObjectSize,  "Object Size:" );
-        aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() );
+        //_LIT( KMetaData_ObjectSize,  "Object Size:" );
+        //aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() );
 
         // Chunk name
         _LIT( KMetaData_ChunkName,  "Chunk Name:" );
@@ -1039,14 +1069,6 @@
         _LIT( KMetaData_DebugAllocator,  "Debug Allocator:" );
         aList.AddItemYesNoL( KMetaData_DebugAllocator, metaData.IsDebugAllocator() );
 
-        // Cell header overhead (free cells)
-        _LIT( KMetaData_CellHeaderOverheadFree,  "Overhead (Free):" );
-        aList.AddItemL( KMetaData_CellHeaderOverheadFree, metaData.HeaderSizeFree() );
-
-        // Cell header overhead (allocated cells)
-        _LIT( KMetaData_CellHeaderOverheadAlloc,  "Overhead (Alloc):" );
-        aList.AddItemL( KMetaData_CellHeaderOverheadAlloc, metaData.HeaderSizeAllocated() );
-
         // Shared Heap
         _LIT( KMetaData_Shared,  "Shared:" );
         aList.AddItemYesNoL( KMetaData_Shared, metaData.IsSharedHeap() );
@@ -1058,90 +1080,9 @@
     aList.AddBlankItemL( 1 );
     }
 
-
-void CMemSpyEngineHelperHeap::AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList )
-    {
-    if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
-        {
-        const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
-        const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData();
-
-        // Make caption
-        _LIT( KOverallCaption1, "RAllocator" );
-        aList.AddItemL( KOverallCaption1 );
-        aList.AddUnderlineForPreviousItemL( '=', 0 );
-
-        // RAllocator
-        _LIT( KObjectData_RAllocator_iAccessCount,  "RAllocator::iAccessCount" );
-        aList.AddItemL( KObjectData_RAllocator_iAccessCount, objectData.iAccessCount );
-        _LIT( KObjectData_RAllocator_iHandleCount,  "RAllocator::iHandleCount" );
-        aList.AddItemL( KObjectData_RAllocator_iHandleCount, objectData.iHandleCount );
-        _LIT( KObjectData_RAllocator_iHandles,  "RAllocator::iHandles" );
-        aList.AddItemL( KObjectData_RAllocator_iHandles, objectData.iHandles );
-        _LIT( KObjectData_RAllocator_iFlags,  "RAllocator::iFlags" );
-        aList.AddItemHexL( KObjectData_RAllocator_iFlags, objectData.iFlags );
-        _LIT( KObjectData_RAllocator_iCellCount,  "RAllocator::iCellCount" );
-        aList.AddItemL( KObjectData_RAllocator_iCellCount, objectData.iCellCount );
-        _LIT( KObjectData_RAllocator_iTotalAllocSize,  "RAllocator::iTotalAllocSize" );
-        aList.AddItemL( KObjectData_RAllocator_iTotalAllocSize, objectData.iTotalAllocSize );
-
-        aList.AddBlankItemL( 1 );
-
-        // Make caption
-        _LIT( KOverallCaption2, "RHeap" );
-        aList.AddItemL( KOverallCaption2 );
-        aList.AddUnderlineForPreviousItemL( '=', 0 );
-
-        // RHeap
-        _LIT( KObjectData_RHeap_iMinLength,  "RHeap::iMinLength" );
-        aList.AddItemL( KObjectData_RHeap_iMinLength, objectData.iMinLength );
-        _LIT( KObjectData_RHeap_iMaxLength,  "RHeap::iMaxLength" );
-        aList.AddItemL( KObjectData_RHeap_iMaxLength, objectData.iMaxLength );
-        _LIT( KObjectData_RHeap_iOffset,  "RHeap::iOffset" );
-        aList.AddItemL( KObjectData_RHeap_iOffset, objectData.iOffset );
-        _LIT( KObjectData_RHeap_iGrowBy,  "RHeap::iGrowBy" );
-        aList.AddItemL( KObjectData_RHeap_iGrowBy, objectData.iGrowBy );
-        _LIT( KObjectData_RHeap_iChunkHandle,  "RHeap::iChunkHandle" );
-        aList.AddItemHexL( KObjectData_RHeap_iChunkHandle, objectData.iChunkHandle );
-        _LIT( KObjectData_RHeap_iBase,  "RHeap::iBase" );
-        aList.AddItemL( KObjectData_RHeap_iBase, objectData.iBase );
-        _LIT( KObjectData_RHeap_iTop,  "RHeap::iTop" );
-        aList.AddItemL( KObjectData_RHeap_iTop, objectData.iTop );
-        _LIT( KObjectData_RHeap_iAlign,  "RHeap::iAlign" );
-        aList.AddItemL( KObjectData_RHeap_iAlign, objectData.iAlign );
-        _LIT( KObjectData_RHeap_iMinCell,  "RHeap::iMinCell" );
-        aList.AddItemL( KObjectData_RHeap_iMinCell, objectData.iMinCell );
-        _LIT( KObjectData_RHeap_iPageSize,  "RHeap::iPageSize" );
-        aList.AddItemL( KObjectData_RHeap_iPageSize, objectData.iPageSize );
-        _LIT( KObjectData_RHeap_iFree_next,  "RHeap::iFree.next" );
-        aList.AddItemL( KObjectData_RHeap_iFree_next, objectData.iFree.next );
-        _LIT( KObjectData_RHeap_iFree_len,  "RHeap::iFree.len" );
-        aList.AddItemL( KObjectData_RHeap_iFree_len, objectData.iFree.len );
-        _LIT( KObjectData_RHeap_iNestingLevel,  "RHeap::iNestingLevel" );
-        aList.AddItemL( KObjectData_RHeap_iNestingLevel, objectData.iNestingLevel );
-        _LIT( KObjectData_RHeap_iAllocCount,  "RHeap::iAllocCount" );
-        aList.AddItemL( KObjectData_RHeap_iAllocCount, objectData.iAllocCount );
-        _LIT( KObjectData_RHeap_iFailType,  "RHeap::iFailType" );
-        aList.AddItemL( KObjectData_RHeap_iFailType, (TInt) objectData.iFailType );
-        _LIT( KObjectData_RHeap_iFailRate,  "RHeap::iFailRate" );
-        aList.AddItemL( KObjectData_RHeap_iFailRate, objectData.iFailRate );
-        _LIT( KObjectData_RHeap_iFailed,  "RHeap::iFailed" );
-        aList.AddItemTrueFalseL( KObjectData_RHeap_iFailed, objectData.iFailed );
-        _LIT( KObjectData_RHeap_iFailAllocCount,  "RHeap::iFailAllocCount" );
-        aList.AddItemL( KObjectData_RHeap_iFailAllocCount, objectData.iFailAllocCount );
-        _LIT( KObjectData_RHeap_iRand,  "RHeap::iRand" );
-        aList.AddItemL( KObjectData_RHeap_iRand, objectData.iRand );
-        _LIT( KObjectData_RHeap_iTestData,  "RHeap::iTestData" );
-        aList.AddItemL( KObjectData_RHeap_iTestData, objectData.iTestData );
-
-        aList.AddBlankItemL( 1 );
-        }
-    }
-
-
 void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList )
     {
-    if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap )
+    if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown)
         {
         const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
         const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics();
@@ -1161,10 +1102,13 @@
         aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() );
         aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() );
         aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() );
-        _LIT( KStatsData_Free_SlackCellAddress,  "Slack:" );
-        aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() );
-        _LIT( KStatsData_Free_SlackCellSize,  "Slack size:" );
-        aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() );
+		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
+			{
+			_LIT( KStatsData_Free_SlackCellAddress,  "Slack:" );
+			aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() );
+			_LIT( KStatsData_Free_SlackCellSize,  "Slack size:" );
+			aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() );
+			}
         _LIT( KStatsData_Free_Checksum,  "Checksum:" );
         aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() );
 
@@ -1181,44 +1125,61 @@
         aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() );
 
         aList.AddBlankItemL( 1 );
-
-        // Common
-        _LIT( KOverallCaption3, "Common Statistics" );
-        aList.AddItemL( KOverallCaption3 );
-        aList.AddUnderlineForPreviousItemL( '=', 0 );
-
-        _LIT( KStatsData_Common_TotalCellCount,  "Total cell count:" );
-        aList.AddItemL( KStatsData_Common_TotalCellCount, rHeapStats.StatsCommon().TotalCellCount() );
-
-        _LIT( KStatsData_Common_TotalSize,  "Total cell size:" );
-        aList.AddItemL( KStatsData_Common_TotalSize, rHeapStats.StatsAllocated().TypeSize() + rHeapStats.StatsFree().TypeSize() );
-
-        aList.AddBlankItemL( 1 );
-        }
+         }
     }
 
 
-void CMemSpyEngineHelperHeap::AppendFreeCellsL( const RArray<TMemSpyDriverFreeCell>& aFreeCells, CMemSpyEngineOutputList& aList )
+void CMemSpyEngineHelperHeap::AppendCellsL(const RArray<TMemSpyDriverCell>& aCells, CMemSpyEngineOutputList& aList)
     {
-    // Free space
+    // For reasons that may or may not turn out to be sensible, we separate free and allocated cells in the output data
+
     _LIT( KOverallCaption1, "Free Cell List" );
     aList.AddItemL( KOverallCaption1 );
     aList.AddUnderlineForPreviousItemL( '=', 0 );
 
     TBuf<128> caption;
     _LIT( KCaptionFormat, "FC %04d" );
-    _LIT( KValueFormat, "0x%08x %8d %1d" );
+    _LIT( KValueFormat, "0x%08x %8d %d" );
 
-    const TInt count = aFreeCells.Count();
+	TBool foundAllocatedCells = EFalse;
+    const TInt count = aCells.Count();
     for( TInt i=0; i<count; i++ )
         {
-        const TMemSpyDriverFreeCell& cell = aFreeCells[ i ];
-        caption.Format( KCaptionFormat, i + 1 );
-        aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType );
+        const TMemSpyDriverCell& cell = aCells[ i ];
+		if (cell.iType & EMemSpyDriverAllocatedCellMask)
+			{
+			foundAllocatedCells = ETrue;
+			}
+		else if (cell.iType & EMemSpyDriverFreeCellMask)
+			{
+	        caption.Format( KCaptionFormat, i + 1 );
+		    aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType );
+			}
         }
+
+	if (foundAllocatedCells)
+		{
+        aList.AddBlankItemL( 1 );
+		_LIT( KOverallCaption1, "Allocated Cell List" );
+		aList.AddItemL( KOverallCaption1 );
+		aList.AddUnderlineForPreviousItemL( '=', 0 );
+
+		TBuf<128> caption;
+		_LIT( KCaptionFormat, "AC %04d" );
+		_LIT( KValueFormat, "0x%08x %8d %d" );
+
+		for (TInt i = 0; i < count; i++)
+			{
+			const TMemSpyDriverCell& cell = aCells[ i ];
+			if (cell.iType & EMemSpyDriverAllocatedCellMask)
+				{
+				caption.Format( KCaptionFormat, i + 1 );
+				aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType );
+				}
+			}
+		}
     }
 
-
 void CMemSpyEngineHelperHeap::UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo )
     {
     RArray<TThreadId> threads;
--- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperKernelContainers.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperKernelContainers.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -76,7 +76,7 @@
     {
     CMemSpyEngineGenericKernelObjectContainer* container = CMemSpyEngineGenericKernelObjectContainer::NewLC();
     //
-    for( TInt i=EMemSpyDriverContainerTypeFirst; i<=EMemSpyDriverContainerTypeChunk; i++ ) //EMemSpyDriverContainerTypeLast
+    for( TInt i=EMemSpyDriverContainerTypeFirst; i<=EMemSpyDriverContainerTypeLast; i++ )
         {
         const TMemSpyDriverContainerType type = static_cast< TMemSpyDriverContainerType >( i );
         //
--- a/memspy/Engine/Source/MemSpyEngine.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/MemSpyEngine.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -67,6 +67,10 @@
     return self;
     }
 
+EXPORT_C CMemSpyEngine* CMemSpyEngine::NewL( RFs& aFsSession, TBool aStartServer )
+    {
+    return NewL(aFsSession);
+    }
 
 EXPORT_C RFs& CMemSpyEngine::FsSession()
     {
@@ -118,9 +122,18 @@
 
 EXPORT_C void CMemSpyEngine::InstallSinkL( TMemSpySinkType aType )
     {
-    iImp->InstallSinkL( aType );
+    iImp->InstallSinkL( aType, KNullDesC );
     }
 
+EXPORT_C void CMemSpyEngine::InstallDebugSinkL()
+    {
+    iImp->InstallSinkL( ESinkTypeDebug, KNullDesC );
+    }
+
+EXPORT_C void CMemSpyEngine::InstallFileSinkL( const TDesC& aRootFolder )
+    {
+    iImp->InstallSinkL( ESinkTypeFile, aRootFolder );
+    }
 
 EXPORT_C void CMemSpyEngine::ListOpenFilesL()
     {
--- a/memspy/Engine/Source/MemSpyEngineImp.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/MemSpyEngineImp.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -52,6 +52,11 @@
 #include <memspy/engine/memspyenginehelperwindowserver.h>
 #include <memspy/engine/memspyenginehelpercondvar.h>
 
+#ifdef _DEBUG
+#define LOG(args...) RDebug::Printf(args)
+#else
+#define LOG(args...)
+#endif
 
 CMemSpyEngineImp::CMemSpyEngineImp( RFs& aFsSession, CMemSpyEngine& aEngine )
 :   iFsSession( aFsSession ), iEngine( aEngine )
@@ -61,20 +66,16 @@
 
 CMemSpyEngineImp::~CMemSpyEngineImp()
     {
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - START" );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - START" );
 
     if  ( iMidwife )
         {
         iMidwife->RemoveObserver( *this );
         }
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting helpers..." );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting helpers..." );
     delete iHelperSysMemTracker;
-    //delete iServer;
+    delete iServer;
     delete iHelperKernelContainers;
     delete iHelperFbServ;
     delete iHelperHeap;
@@ -94,52 +95,37 @@
     
     iHelperWindowServerLoader.Close();
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting utilities..." );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting utilities..." );
     delete iChunkWatcher;
     delete iUndertaker;
     delete iMidwife;
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying containers..." );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying containers..." );
     iContainers.ResetAndDestroy();
     iContainers.Close();
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying driver..." );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying driver..." );
     if  ( iMemSpyDriver )
         {
         iMemSpyDriver->Close();
         delete iMemSpyDriver;
         }
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying sink..." );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying sink..." );
     delete iSink;
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - END" );
-#endif
+    LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - END" );
     }
 
 
 void CMemSpyEngineImp::ConstructL()
     {
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructL() - START" );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructL() - START" );
     //
     iFsSession.SetSessionPath( _L("\\") );
     
-    // Starting the server before the driver connection is made
-    // ensures that only one instance of MemSpy can run (either the S60
-    // UI or the console UI ).
-    // DONE: MK: Removing server from engine. iServer = CMemSpyEngineServer::NewL( iEngine );
-    //
+    iServer = CMemSpyEngineServer::NewL( iEngine );
+    
     iMemSpyDriver = new(ELeave) RMemSpyDriverClient();
     const TInt error = Driver().Open();
     User::LeaveIfError( error );
@@ -163,96 +149,60 @@
     iHelperSysMemTracker = CMemSpyEngineHelperSysMemTracker::NewL( iEngine );
     iMidwife->AddObserverL( *this );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructL() - END" );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructL() - END" );
     }
 
 
 void CMemSpyEngineImp::ConstructHelpersL()
     {
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - START" );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - START" );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Heap..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Heap..." );
     iHelperHeap = CMemSpyEngineHelperHeap::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Stack..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Stack..." );
     iHelperStack = CMemSpyEngineHelperStack::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Code Segments..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Code Segments..." );
     iHelperCodeSegment = CMemSpyEngineHelperCodeSegment::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Chunk..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Chunk..." );
     iHelperChunk = CMemSpyEngineHelperChunk::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Thread..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Thread..." );
     iHelperThread = CMemSpyEngineHelperThread::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Process..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Process..." );
     iHelperProcess = CMemSpyEngineHelperProcess::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Server..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Server..." );
     iHelperServer = CMemSpyEngineHelperServer::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - AO..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - AO..." );
     iHelperActiveObject = CMemSpyEngineHelperActiveObject::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - Kernel Containers..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - Kernel Containers..." );
     iHelperKernelContainers = CMemSpyEngineHelperKernelContainers::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - File System..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - File System..." );
     iHelperFileSystem = CMemSpyEngineHelperFileSystem::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - ECOM..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - ECOM..." );
     iHelperECom = CMemSpyEngineHelperECom::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - FBSERV..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - FBSERV..." );
     iHelperFbServ = CMemSpyEngineHelperFbServ::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - ROM..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - ROM..." );
     iHelperROM = CMemSpyEngineHelperROM::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - RAM..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - RAM..." );
     iHelperRAM = CMemSpyEngineHelperRAM::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer..." );
     
     TInt err = iHelperWindowServerLoader.Load( _L("memspywindowserverhelper.dll") );
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer load err: %d", err );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer load err: %d", err );
     if ( !err )
         {
 #ifdef __WINS__ // ordinal is different 
@@ -262,18 +212,19 @@
 #endif
         if ( entry != NULL )
             {
-            iHelperWindowServer = (MMemSpyEngineHelperWindowServer*) entry();
+			typedef MMemSpyEngineHelperWindowServer* (*TEntryFn)(void);
+			TRAP(err, iHelperWindowServer = ((TEntryFn)entry)());
+			if (err)
+				{
+				LOG("err from memspywindowserverhelper.dll - %d", err);
+				}
             }
         }
     
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - CondVar..." );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - CondVar..." );
     iHelperCondVar = CMemSpyEngineHelperCondVar::NewL( iEngine );
 
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::ConstructHelpersL() - END" );
-#endif
+    LOG( "CMemSpyEngineImp::ConstructHelpersL() - END" );
     }
 
 
@@ -334,12 +285,14 @@
     return iSink->Type();
     }
 
+void CMemSpyEngineImp::InstallSinkL( TMemSpySinkType aType )
+	{
+	InstallSinkL( aType, KNullDesC );
+	}
 
-void CMemSpyEngineImp::InstallSinkL( TMemSpySinkType aType )
+void CMemSpyEngineImp::InstallSinkL( TMemSpySinkType aType, const TDesC& aRootFolder )
     {
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::InstallSinkL() - START - switching sink from %d to %d...", (iSink != NULL ? iSink->Type() : -1), aType );
-#endif
+    LOG( "CMemSpyEngineImp::InstallSinkL() - START - switching sink from %d to %d...", (iSink != NULL ? iSink->Type() : -1), aType );
     //
     CMemSpyEngineOutputSink* sink = NULL;
     //
@@ -349,16 +302,14 @@
         sink = CMemSpyEngineOutputSinkDebug::NewL( iEngine );
         break;
     case ESinkTypeFile:
-        sink = CMemSpyEngineOutputSinkFile::NewL( iEngine );
+        sink = CMemSpyEngineOutputSinkFile::NewL( iEngine, aRootFolder );
         break;
         }
     //
     delete iSink;
     iSink = sink;
     //
-#ifdef _DEBUG
-    RDebug::Printf( "CMemSpyEngineImp::InstallSinkL() - END - sink type: %d", iSink->Type() );
-#endif
+    LOG( "CMemSpyEngineImp::InstallSinkL() - END - sink type: %d", iSink->Type() );
     }
 
 
--- a/memspy/Engine/Source/MemSpyEngineUtils.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/MemSpyEngineUtils.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -274,7 +274,7 @@
 
 EXPORT_C TMemSpyPercentText MemSpyEngineUtils::FormatPercentage( TReal aOneHundredPercentValue, TReal aValue )
     {
-    const TReal value = (TInt) (( aValue / aOneHundredPercentValue) * 100.0);
+    const TReal value = (( aValue / aOneHundredPercentValue) * 100.0);
     
     _LIT(KPercentFormat, "%3.2f %%");
 
@@ -365,6 +365,7 @@
 EXPORT_C void MemSpyEngineUtils::GetFolderL( RFs& aFsSession, TDes& aFolder, const CMemSpyEngineSinkMetaData& aMetaData, const TDriveNumber* aForceDrive )
     {
     const TChar KMemSpyDirectorySeparator = '\\';
+    const TChar KMemSpyDriveSeparator = ':';
 
     TDriveList drives;
     User::LeaveIfError( aFsSession.DriveList( drives ) );
@@ -379,7 +380,26 @@
         }
     else
         {
-        logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession );
+		// check if drive is specified in root path
+		if ( aMetaData.Root().Length() > 2 && aMetaData.Root()[1] == KMemSpyDriveSeparator )
+			{
+			TChar drive = aMetaData.Root()[0];
+			
+			// check if drive is valid
+			if (drives.Locate(drive) != KErrNone)
+				{
+				TDriveUnit driveUnit( aMetaData.Root().Left(1) );
+				logDrive = static_cast<TDriveNumber>(static_cast<TInt>(driveUnit));
+				}
+			else
+				{
+				logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession );
+				}
+			}
+		else
+			{
+			logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession );
+			}
         }
 
     // Prepare the drive buffer
@@ -389,7 +409,35 @@
     // Prepare the drive name
     TDriveUnit driveUnit( logDrive );
     pFileName.Append( driveUnit.Name() );
-    pFileName.Append( KMemSpyLogRootPath );
+    
+    if ( aMetaData.Root().Length() == 0 )
+    	{
+		pFileName.Append( KMemSpyLogRootPath );
+    	}
+    else
+    	{
+		TPtrC root( aMetaData.Root() );
+		// check if root path contains drive (e.g. c:) and remove it
+		if ( root.Length() > 2 && root[1] == KMemSpyDriveSeparator )
+			{
+			root.Set( root.Mid( 2 ) );
+			}
+		// check if root starts with \ and remove it
+		if ( root.Length() > 1 && root[0] == KMemSpyDirectorySeparator )
+			{
+			root.Set( root.Mid( 1 ) );
+			}
+		
+		// append root path
+		pFileName.Append( KMemSpyDirectorySeparator );
+		pFileName.Append( root );
+		
+		// add trailing slash if necessary
+		if ( root[root.Length() - 1] != KMemSpyDirectorySeparator )
+			{
+			pFileName.Append( KMemSpyDirectorySeparator );
+			}
+    	}
 
     // Add any custom folder information
     if  ( aMetaData.Folder().Length() > 0 )
--- a/memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -102,8 +102,18 @@
         for( TInt j=0; j<count; j++ )
             {
             const CMemSpyEngineOutputListItem* item = iItems[ j ];
-            maxLengthCaption = Max( maxLengthCaption, item->Caption().Length() );
-            maxLengthValue = Max( maxLengthValue, item->Value().Length() );
+			if (item->Value().Length())
+				{
+	            maxLengthCaption = Max( maxLengthCaption, item->Caption().Length() );
+	            maxLengthValue = Max( maxLengthValue, item->Value().Length() );
+				}
+			else
+				{
+				// If something doesn't have a value (ie it's a section header, represented as just a caption) then the caption
+				// shouldn't be factored into the maxcaptionlength. But consider it in maxlengthValue to make sure we actually
+				// make the overall buffers big enough
+				maxLengthValue = Max( maxLengthValue, item->Caption().Length() );
+				}
             }
 
         // Second pass - real this time - to print the values
@@ -121,7 +131,15 @@
             HBufC* value = MemSpyEngineUtils::CleanupTextLC( item->Value() );
 
             // Now format the final line, with padding.
-            pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') );
+			if (value->Length()) 
+				{
+	            pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') );
+				}
+			else
+				{
+				// items without value (ie just captions, ie section headers) aren't constrained by the maxLengthCaption restriction
+				pLine.Copy(*caption);
+				}
             pLine.Append( *value );
             CleanupStack::PopAndDestroy( 2, caption );
 
--- a/memspy/Engine/Source/Sink/MemSpyEngineOutputSink.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputSink.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -380,6 +380,7 @@
 
 EXPORT_C CMemSpyEngineSinkMetaData::~CMemSpyEngineSinkMetaData()
     {
+	delete iRoot;
     delete iContext;
     delete iFolder;
     delete iExtension;
@@ -387,8 +388,9 @@
     }
 
 
-void CMemSpyEngineSinkMetaData::ConstructL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime )
+void CMemSpyEngineSinkMetaData::ConstructL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime )
     {
+	iRoot = aRoot.AllocL();
     iContext = aContext.AllocL();
     iFolder = aFolder.AllocL();
     iExtension = aExtension.AllocL();
@@ -407,15 +409,24 @@
     return CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue );
     }
 
+EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL(  const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp )
+	{
+	return NewL( KNullDesC, aContext, aFolder, aExtension, aOverwrite, aUseFileTimeStamp );
+	}
 
-EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp )
+EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp )
+    {
+    return NewL( KNullDesC, aContext, aFolder, aExtension, aOverwrite, aUseFileTimeStamp, aFolderTimeStamp );
+    }
+
+EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp )
     {
     // Create a dummy time, we'll clear it after ConstructL() returns...
     TTime now; now.HomeTime();
 
     CMemSpyEngineSinkMetaData* self = new(ELeave) CMemSpyEngineSinkMetaData( aOverwrite, aUseFileTimeStamp );
     CleanupStack::PushL( self );
-    self->ConstructL( aContext, aFolder, aExtension, now );
+    self->ConstructL( aRoot, aContext, aFolder, aExtension, now );
     CleanupStack::Pop( self );
 
     // Clear folder time stamp
@@ -423,14 +434,11 @@
     return self;
     }
 
-
-EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp )
+EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp )
     {
     CMemSpyEngineSinkMetaData* self = new(ELeave) CMemSpyEngineSinkMetaData( aOverwrite, aUseFileTimeStamp );
     CleanupStack::PushL( self );
-    self->ConstructL( aContext, aFolder, aExtension, aFolderTimeStamp );
+    self->ConstructL( aRoot, aContext, aFolder, aExtension, aFolderTimeStamp );
     CleanupStack::Pop( self );
     return self;
     }
-
-
--- a/memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -41,6 +41,8 @@
 CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile()
     {
     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - START" ) );
+    
+    delete iRoot;
 
     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - destroying normal logs..." ) );
     iLogs.ResetAndDestroy();
@@ -56,9 +58,11 @@
     }
 
 
-void CMemSpyEngineOutputSinkFile::ConstructL()
+void CMemSpyEngineOutputSinkFile::ConstructL( const TDesC& aRootFolder )
     {
     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - START" ) );
+    
+    iRoot = aRootFolder.AllocL();
 
     BaseConstructL();
 
@@ -78,11 +82,11 @@
     }
 
 
-CMemSpyEngineOutputSinkFile* CMemSpyEngineOutputSinkFile::NewL( CMemSpyEngine& aEngine )
+CMemSpyEngineOutputSinkFile* CMemSpyEngineOutputSinkFile::NewL( CMemSpyEngine& aEngine, const TDesC& aRootFolder )
     {
     CMemSpyEngineOutputSinkFile* self = new(ELeave) CMemSpyEngineOutputSinkFile( aEngine );
     CleanupStack::PushL( self );
-    self->ConstructL();
+    self->ConstructL( aRootFolder );
     CleanupStack::Pop( self );
     return self;
     }
@@ -154,7 +158,7 @@
 
 void CMemSpyEngineOutputSinkFile::DataStreamBeginL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseTimeStamp )
     {
-    CMemSpyEngineSinkMetaData* meta = CMemSpyEngineSinkMetaData::NewL( aContext, aFolder, aExtension, aOverwrite, aUseTimeStamp );
+    CMemSpyEngineSinkMetaData* meta = CMemSpyEngineSinkMetaData::NewL( iRoot->Des(), aContext, aFolder, aExtension, aOverwrite, aUseTimeStamp );
     CleanupStack::PushL( meta );
 
     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamBeginL() - START - log count: %d, iFileServerSuspended: %d", iLogs.Count(), iFileServerSuspended ) );
@@ -409,7 +413,7 @@
 
     // Make emtpy meta data
     ASSERT( !iMetaData );
-    iMetaData = CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue );
+    iMetaData = CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue );
 
     // Prepare common details
     CommonConstructL();
--- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTracker.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTracker.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -129,7 +129,7 @@
     }
 
 
-void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL()
+EXPORT_C void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL()
     {
     iImp->CheckForChangesNowL();
     }
--- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -216,15 +216,8 @@
 
 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveFreeCellsChanged() const
     {
-    TBool changed = 
-        ( iCurrent.AsRHeap().ObjectData().iFree.next != iLast.AsRHeap().ObjectData().iFree.next ) ||
-        ( iCurrent.AsRHeap().ObjectData().iFree.len != iLast.AsRHeap().ObjectData().iFree.len );
-    //
-    if ( !changed )
-        {
-        changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() );
-        changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() != iLast.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() );
-        }
+    TBool changed = ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() ) ||
+		( iCurrent.AsRHeap().Statistics().StatsFree().TypeSize() != iLast.AsRHeap().Statistics().StatsFree().TypeSize() );
     //
     return changed;
     }
@@ -296,7 +289,7 @@
 
 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputHeaderL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
     {
-    _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Base Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs");
+    _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Heap Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs");
     aSink.OutputLineL( KHeaderHeap );
     }
 
@@ -315,7 +308,6 @@
     TPtr pBuf(buf->Des());
 
     const TMemSpyHeapMetaDataRHeap& metaData = iCurrent.AsRHeap().MetaData();
-    const TMemSpyHeapObjectDataRHeap& objectData = iCurrent.AsRHeap().ObjectData();
     const TMemSpyHeapStatisticsRHeap& stats = iCurrent.AsRHeap().Statistics();
 
     // Strip any process & thread
@@ -326,12 +318,12 @@
                  iThreadName, 
                  &pChunkName,
                  metaData.ChunkHandle(),
-                 objectData.Base(),
+                 /*objectData.Base(),*/ metaData.iAllocatorAddress,
                  metaData.ChunkSize(),
-                 objectData.iMinLength,
-                 objectData.iMaxLength,
-                 objectData.iFree.next,
-                 objectData.iFree.len,
+                 /*objectData.iMinLength,*/ metaData.iMinHeapSize,
+                 /*objectData.iMaxLength,*/ metaData.iMaxHeapSize,
+                 /*objectData.iFree.next,*/ NULL, //TODO
+                 /*objectData.iFree.len,*/ 0,
                  stats.StatsAllocated().TypeCount(),
                  stats.StatsAllocated().TypeSize(),
                  stats.StatsFree().TypeCount(),
@@ -371,18 +363,22 @@
         {
         // Starts a data Stream
         aCycle.DataStreamBeginL( aSink, *iThreadName );
+        
+        TInt err = KErrNone;
 
         if  ( IsKernel() )
             {
-            engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream );
+            TRAP(err, engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream ));
             }
         else if ( thread )
             {
-            engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream ); 
+            TRAP(err, engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream )); 
             }
 
         // End the stream (commit the file)
         aCycle.DataStreamEndL( aSink );
+        
+        User::LeaveIfError(err);
         }
     }
 
--- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -443,12 +443,13 @@
     }
 #endif
 
-    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles )
-        {
-        RDebug::Print( KMemSpyKeepaliveMessage );
-        // Bitmap
-        CreateSeedItemsBitmapL( *chunks );        
-        }
+// TODO: Uncomment when  bitmap handels are fixed
+//    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles )
+//        {
+//        RDebug::Print( KMemSpyKeepaliveMessage );
+//        // Bitmap
+//        CreateSeedItemsBitmapL( *chunks );        
+//        }
 
 #ifdef SYSMEMTRACKERLOGGING
     {
@@ -479,12 +480,13 @@
     }
 #endif
 
-    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap )
-        {
-        RDebug::Print( KMemSpyKeepaliveMessage );
-        // Look for kernel heaps
-        CreateSeedItemsHeapKernelL( *chunks );
-        }
+//  TODO: Uncomment after fix
+//    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap )
+//        {
+//        RDebug::Print( KMemSpyKeepaliveMessage );
+//        // Look for kernel heaps
+//        CreateSeedItemsHeapKernelL( *chunks );
+//        }
 
 #ifdef SYSMEMTRACKERLOGGING
     {
@@ -551,12 +553,13 @@
     }
 #endif
 
-    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks )
-        {
-        RDebug::Print( KMemSpyKeepaliveMessage );
-        // Stacks ($DAT)
-        CreateSeedItemsStacksL( *chunks );        
-        }
+//    TODO: Uncomment after fix
+//    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks )
+//        {
+//        RDebug::Print( KMemSpyKeepaliveMessage );
+//        // Stacks ($DAT)
+//        CreateSeedItemsStacksL( *chunks );        
+//        }
 
 #ifdef SYSMEMTRACKERLOGGING
      {
@@ -569,12 +572,13 @@
     }
 #endif
 
-    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData )
-        {
-        RDebug::Print( KMemSpyKeepaliveMessage );
-        // Global data (DLL$DATA)
-        CreateSeedItemsGlobalDataL( *chunks );        
-        }
+//  TODO: Uncomment after fix
+//    if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData )
+//        {
+//        RDebug::Print( KMemSpyKeepaliveMessage );
+//        // Global data (DLL$DATA)
+//        CreateSeedItemsGlobalDataL( *chunks );        
+//        }
 
  #ifdef SYSMEMTRACKERLOGGING
     {
--- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectContainer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectContainer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -773,9 +773,9 @@
         for( TInt i=0; i<leftCount; i++ )
             {
             const TMemSpyHeapInfo& info = leftInfos[ i ];
-            if ( info.Type() == TMemSpyHeapInfo::ETypeRHeap )
+            if ( info.Type() != TMemSpyHeapInfo::ETypeUnknown )
                 {
-                leftSize += (TInt) info.AsRHeap().ObjectData().Size();
+                leftSize += (TInt) info.AsRHeap().MetaData().iHeapSize;
                 }
             }
         CleanupStack::PopAndDestroy( &leftInfos );
@@ -789,9 +789,9 @@
         for( TInt i=0; i<rightCount; i++ )
             {
             const TMemSpyHeapInfo& info = rightInfos[ i ];
-            if ( info.Type() == TMemSpyHeapInfo::ETypeRHeap )
+            if ( info.Type() == TMemSpyHeapInfo::ETypeUnknown )
                 {
-                rightSize += (TInt) info.AsRHeap().ObjectData().Size();
+                rightSize += (TInt) info.AsRHeap().MetaData().iHeapSize;
                 }
             }
         CleanupStack::PopAndDestroy( &rightInfos );
--- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectProcess.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectProcess.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -515,6 +515,25 @@
     return iInfo->VID();
     }
 
+EXPORT_C TProcessPriority CMemSpyProcess::Priority() const
+	{
+	return iPriority;
+	}
+
+EXPORT_C TExitCategoryName CMemSpyProcess::ExitCategory() const
+	{
+	return iExitCategory;
+	}
+
+EXPORT_C TInt CMemSpyProcess::ExitReason() const
+	{
+	return iExitReason;
+	}
+
+EXPORT_C TExitType CMemSpyProcess::ExitType() const
+	{
+	return iExitType;
+	}
 
 EXPORT_C TUidType CMemSpyProcess::UIDs() const
     {
--- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -123,6 +123,17 @@
     return TPtrC( item->Combined() );
     }
 
+EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Caption(TInt aIndex ) const
+	{
+	CItem* item = iItems[ aIndex ];
+	return TPtrC( item->Caption() );
+	}
+
+EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Value(TInt aIndex ) const
+	{
+	CItem* item = iItems[ aIndex ];
+	return TPtrC( item->Value() );
+	}
 
 EXPORT_C CMemSpyEngine& CMemSpyThreadInfoItemBase::Engine() const
     {
--- a/memspy/Engine/eabi/MemSpyEngineu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/eabi/MemSpyEngineu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -540,4 +540,17 @@
 	_ZNK36CMemSpyEngineGenericKernelObjectList10ItemsCountEv @ 539 NONAME
 	_ZNK36CMemSpyEngineGenericKernelObjectList4SizeEv @ 540 NONAME
 	_ZNK13CMemSpyThread8PriorityEv @ 541 NONAME
+	_ZN13CMemSpyEngine4NewLER3RFsi @ 542 NONAME
+	_ZNK14CMemSpyProcess10ExitReasonEv @ 543 NONAME
+	_ZNK14CMemSpyProcess12ExitCategoryEv @ 544 NONAME
+	_ZNK14CMemSpyProcess8ExitTypeEv @ 545 NONAME
+	_ZNK14CMemSpyProcess8PriorityEv @ 546 NONAME
+	_ZNK25CMemSpyThreadInfoItemBase5ValueEi @ 547 NONAME
+	_ZNK25CMemSpyThreadInfoItemBase7CaptionEi @ 548 NONAME
+	_ZN13CMemSpyEngine16InstallFileSinkLERK7TDesC16 @ 549 NONAME
+	_ZN13CMemSpyEngine17InstallDebugSinkLEv @ 550 NONAME
+	_ZN25CMemSpyEngineSinkMetaData4NewLERK7TDesC16S2_S2_S2_ii @ 551 NONAME
+	_ZN25CMemSpyEngineSinkMetaData4NewLERK7TDesC16S2_S2_S2_iiRK5TTime @ 552 NONAME
+	_ZN32CMemSpyEngineHelperSysMemTracker19CheckForChangesNowLEv @ 553 NONAME
+	_ZN23CMemSpyEngineHelperHeap16GetHeapInfoUserLERK10TProcessIdRK9TThreadIdR15TMemSpyHeapInfoP6RArrayI21TMemSpyDriverFreeCellEi @ 554 NONAME
 
--- a/memspy/Engine/group/MemSpyEngine.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/Engine/group/MemSpyEngine.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -113,15 +113,18 @@
 
 OS_LAYER_SYSTEMINCLUDE
 
+APP_LAYER_SYSTEMINCLUDE
+
 LIBRARY			euser.lib 
 LIBRARY			MemSpyDriverClient.lib hal.lib estor.lib
 LIBRARY			efsrv.lib bafl.lib fbscli.lib
 LIBRARY			ecom.lib xmlframework.lib charconv.lib
-
+LIBRARY			apgrfx.lib
+LIBRARY	 		ws32.lib
 
 
 #include "MemSpyEngine.config"
 
+//EXPORTUNFROZEN
 
 
-
--- a/memspy/MemSpyClient/bwins/MemSpyClientu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/bwins/MemSpyClientu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -1,114 +1,184 @@
 EXPORTS
 	?CpuUse@CMemSpyApiThread@@QBEHXZ @ 1 NONAME ; int CMemSpyApiThread::CpuUse(void) const
 	?Name@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 2 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::Name(void) const
-	?AccessCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 3 NONAME ; int CMemSpyApiKernelObjectItem::AccessCount(void) const
-	?TotalOverhead@CMemSpyApiHeap@@QAEHXZ @ 4 NONAME ; int CMemSpyApiHeap::TotalOverhead(void)
-	?UniqueID@CMemSpyApiKernelObjectItem@@QBEHXZ @ 5 NONAME ; int CMemSpyApiKernelObjectItem::UniqueID(void) const
-	?SessionType@CMemSpyApiKernelObjectItem@@QBE?AW4TIpcSessionType@@XZ @ 6 NONAME ; enum TIpcSessionType CMemSpyApiKernelObjectItem::SessionType(void) const
-	?VID@CMemSpyApiThread@@QBEHXZ @ 7 NONAME ; int CMemSpyApiThread::VID(void) const
-	?MaxLength@CMemSpyApiHeap@@QAEHXZ @ 8 NONAME ; int CMemSpyApiHeap::MaxLength(void)
-	?ProcessNumberUsing@CMemSpyApiThread@@QBEHXZ @ 9 NONAME ; int CMemSpyApiThread::ProcessNumberUsing(void) const
-	?AddressOfKernelOwner@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 10 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfKernelOwner(void)
-	?FreeCount@CMemSpyApiHeap@@QAEHXZ @ 11 NONAME ; int CMemSpyApiHeap::FreeCount(void)
-	?ExitType@CMemSpyApiProcess@@QBE?AW4TExitType@@XZ @ 12 NONAME ; enum TExitType CMemSpyApiProcess::ExitType(void) const
-	?TotalFree@CMemSpyApiHeap@@QAEHXZ @ 13 NONAME ; int CMemSpyApiHeap::TotalFree(void)
-	?SwitchToThread@RMemSpySession@@QAEHVTThreadId@@H@Z @ 14 NONAME ; int RMemSpySession::SwitchToThread(class TThreadId, int)
-	?FreeOverhead@CMemSpyApiHeap@@QAEHXZ @ 15 NONAME ; int CMemSpyApiHeap::FreeOverhead(void)
-	?SlackFreeSpace@CMemSpyApiHeap@@QAEHXZ @ 16 NONAME ; int CMemSpyApiHeap::SlackFreeSpace(void)
-	?Priority@CMemSpyApiKernelObjectItem@@QBEHXZ @ 17 NONAME ; int CMemSpyApiKernelObjectItem::Priority(void) const
-	?EndThread@RMemSpySession@@QAEHVTThreadId@@W4TEndType@@@Z @ 18 NONAME ; int RMemSpySession::EndThread(class TThreadId, enum TEndType)
-	?ThreadCount@CMemSpyApiProcess@@QBEHXZ @ 19 NONAME ; int CMemSpyApiProcess::ThreadCount(void) const
-	?RequestCount@CMemSpyApiThread@@QBEHXZ @ 20 NONAME ; int CMemSpyApiThread::RequestCount(void) const
-	??1CMemSpyApiProcess@@QAE@XZ @ 21 NONAME ; CMemSpyApiProcess::~CMemSpyApiProcess(void)
-	?SetThreadPriorityL@RMemSpySession@@QAEXVTThreadId@@H@Z @ 22 NONAME ; void RMemSpySession::SetThreadPriorityL(class TThreadId, int)
-	?MinLength@CMemSpyApiHeap@@QAEHXZ @ 23 NONAME ; int CMemSpyApiHeap::MinLength(void)
-	?Restrictions@CMemSpyApiKernelObjectItem@@QBEIXZ @ 24 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Restrictions(void) const
-	?Id@CMemSpyApiKernelObjectItem@@QBEHXZ @ 25 NONAME ; int CMemSpyApiKernelObjectItem::Id(void) const
-	?Count@CMemSpyApiKernelObjectItem@@QBEHXZ @ 26 NONAME ; int CMemSpyApiKernelObjectItem::Count(void) const
-	?ExitCategory@CMemSpyApiProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 27 NONAME ; class TBuf<16> CMemSpyApiProcess::ExitCategory(void) const
-	?ControllingOwner@CMemSpyApiKernelObjectItem@@QBEIXZ @ 28 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ControllingOwner(void) const
-	?Count@CMemSpyApiKernelObject@@QBEHXZ @ 29 NONAME ; int CMemSpyApiKernelObject::Count(void) const
-	?StartPos@CMemSpyApiKernelObjectItem@@QBEHXZ @ 30 NONAME ; int CMemSpyApiKernelObjectItem::StartPos(void) const
-	?TimerState@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerState@@XZ @ 31 NONAME ; enum TMemSpyDriverTimerState CMemSpyApiKernelObjectItem::TimerState(void) const
-	?ExitType@CMemSpyApiThread@@QBE?AW4TExitType@@XZ @ 32 NONAME ; enum TExitType CMemSpyApiThread::ExitType(void) const
-	?BaseAddress@CMemSpyApiHeap@@QAEHXZ @ 33 NONAME ; int CMemSpyApiHeap::BaseAddress(void)
-	?Version@CMemSpyApiKernelObjectItem@@QBE?AVTVersion@@XZ @ 34 NONAME ; class TVersion CMemSpyApiKernelObjectItem::Version(void) const
-	?SwitchToProcess@RMemSpySession@@QAEHVTProcessId@@H@Z @ 35 NONAME ; int RMemSpySession::SwitchToProcess(class TProcessId, int)
-	?MaxSize@CMemSpyApiKernelObjectItem@@QBEHXZ @ 36 NONAME ; int CMemSpyApiKernelObjectItem::MaxSize(void) const
-	?Type@CMemSpyApiHeap@@QAEAAVTDesC16@@XZ @ 37 NONAME ; class TDesC16 & CMemSpyApiHeap::Type(void)
-	?AddressOfOwningProcess@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 38 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningProcess(void)
-	?Id@CMemSpyApiProcess@@QBE?AVTProcessId@@XZ @ 39 NONAME ; class TProcessId CMemSpyApiProcess::Id(void) const
-	??1CMemSpyApiKernelObjectItem@@QAE@XZ @ 40 NONAME ; CMemSpyApiKernelObjectItem::~CMemSpyApiKernelObjectItem(void)
-	?BiggestAllocation@CMemSpyApiHeap@@QAEHXZ @ 41 NONAME ; int CMemSpyApiHeap::BiggestAllocation(void)
-	?ExitReason@CMemSpyApiProcess@@QBEHXZ @ 42 NONAME ; int CMemSpyApiProcess::ExitReason(void) const
-	?MsgCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 43 NONAME ; int CMemSpyApiKernelObjectItem::MsgCount(void) const
-	?AllocationsCount@CMemSpyApiHeap@@QAEHXZ @ 44 NONAME ; int CMemSpyApiHeap::AllocationsCount(void)
-	?AllocationOverhead@CMemSpyApiHeap@@QAEHXZ @ 45 NONAME ; int CMemSpyApiHeap::AllocationOverhead(void)
-	?NameOfOwner@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 46 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameOfOwner(void) const
-	?WaitCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 47 NONAME ; int CMemSpyApiKernelObjectItem::WaitCount(void) const
-	?ThreadSystemPermanentOrCritical@RMemSpySession@@QAEHVTThreadId@@H@Z @ 48 NONAME ; int RMemSpySession::ThreadSystemPermanentOrCritical(class TThreadId, int)
-	?Protection@CMemSpyApiKernelObjectItem@@QBEIXZ @ 49 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Protection(void) const
-	?Attributes@CMemSpyApiThread@@QBEHXZ @ 50 NONAME ; int CMemSpyApiThread::Attributes(void) const
-	?BiggestFree@CMemSpyApiHeap@@QAEHXZ @ 51 NONAME ; int CMemSpyApiHeap::BiggestFree(void)
-	?Bottom@CMemSpyApiKernelObjectItem@@QBEHXZ @ 52 NONAME ; int CMemSpyApiKernelObjectItem::Bottom(void) const
-	?Size@CMemSpyApiKernelObject@@QBE_JXZ @ 53 NONAME ; long long CMemSpyApiKernelObject::Size(void) const
-	?ThreadHandles@CMemSpyApiThread@@QBEHXZ @ 54 NONAME ; int CMemSpyApiThread::ThreadHandles(void) const
-	?SvrSessionType@CMemSpyApiKernelObjectItem@@QBEEXZ @ 55 NONAME ; unsigned char CMemSpyApiKernelObjectItem::SvrSessionType(void) const
-	?TotalAllocations@CMemSpyApiHeap@@QAEHXZ @ 56 NONAME ; int CMemSpyApiHeap::TotalAllocations(void)
-	?Name@CMemSpyApiProcess@@QBEABVTDesC16@@XZ @ 57 NONAME ; class TDesC16 const & CMemSpyApiProcess::Name(void) const
-	?ChunkType@CMemSpyApiKernelObjectItem@@QBEIXZ @ 58 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ChunkType(void) const
-	?GetKernelObjects@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 59 NONAME ; int RMemSpySession::GetKernelObjects(class RArray<class CMemSpyApiKernelObject *> &)
-	?HeaderSizeF@CMemSpyApiHeap@@QAEHXZ @ 60 NONAME ; int CMemSpyApiHeap::HeaderSizeF(void)
-	?Id@CMemSpyApiThread@@QBE?AVTThreadId@@XZ @ 61 NONAME ; class TThreadId CMemSpyApiThread::Id(void) const
-	?MsgLimit@CMemSpyApiKernelObjectItem@@QBEHXZ @ 62 NONAME ; int CMemSpyApiKernelObjectItem::MsgLimit(void) const
-	?AddressOfDataBssStackChunk@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 63 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfDataBssStackChunk(void)
-	?MapAttr@CMemSpyApiKernelObjectItem@@QBEIXZ @ 64 NONAME ; unsigned int CMemSpyApiKernelObjectItem::MapAttr(void) const
-	?Top@CMemSpyApiKernelObjectItem@@QBEHXZ @ 65 NONAME ; int CMemSpyApiKernelObjectItem::Top(void) const
-	?Resetting@CMemSpyApiKernelObjectItem@@QBEEXZ @ 66 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Resetting(void) const
-	?HeaderSizeA@CMemSpyApiHeap@@QAEHXZ @ 67 NONAME ; int CMemSpyApiHeap::HeaderSizeA(void)
-	?EndProcess@RMemSpySession@@QAEHVTProcessId@@W4TEndType@@@Z @ 68 NONAME ; int RMemSpySession::EndProcess(class TProcessId, enum TEndType)
-	?AddressOfCodeSeg@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 69 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfCodeSeg(void)
-	?TotalAccessCount@CMemSpyApiKernelObjectItem@@QBEGXZ @ 70 NONAME ; unsigned short CMemSpyApiKernelObjectItem::TotalAccessCount(void) const
-	?GetThreadsL@RMemSpySession@@QAEXVTProcessId@@AAV?$RArray@PAVCMemSpyApiThread@@@@W4TSortType@@@Z @ 71 NONAME ; void RMemSpySession::GetThreadsL(class TProcessId, class RArray<class CMemSpyApiThread *> &, enum TSortType)
-	?Changes@CMemSpyApiKernelObjectItem@@QBEIXZ @ 72 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Changes(void) const
-	?ProcessId@CMemSpyApiThread@@QBE?AVTProcessId@@XZ @ 73 NONAME ; class TProcessId CMemSpyApiThread::ProcessId(void) const
-	??0RMemSpySession@@QAE@XZ @ 74 NONAME ; RMemSpySession::RMemSpySession(void)
-	?Type@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 75 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObjectItem::Type(void) const
-	?AddressOfServer@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 76 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfServer(void)
-	?Size@CMemSpyApiHeap@@QAEHXZ @ 77 NONAME ; int CMemSpyApiHeap::Size(void)
-	??1CMemSpyApiKernelObject@@QAE@XZ @ 78 NONAME ; CMemSpyApiKernelObject::~CMemSpyApiKernelObject(void)
-	??1CMemSpyApiHeap@@QAE@XZ @ 79 NONAME ; CMemSpyApiHeap::~CMemSpyApiHeap(void)
-	?ChunkSize@CMemSpyApiHeap@@QAEHXZ @ 80 NONAME ; int CMemSpyApiHeap::ChunkSize(void)
-	?UnitsMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 81 NONAME ; unsigned int CMemSpyApiKernelObjectItem::UnitsMask(void) const
-	?Size@CMemSpyApiKernelObjectItem@@QBEKXZ @ 82 NONAME ; unsigned long CMemSpyApiKernelObjectItem::Size(void) const
-	?State@CMemSpyApiKernelObjectItem@@QBEEXZ @ 83 NONAME ; unsigned char CMemSpyApiKernelObjectItem::State(void) const
-	?Shared@CMemSpyApiHeap@@QAEHXZ @ 84 NONAME ; int CMemSpyApiHeap::Shared(void)
-	?Type@CMemSpyApiKernelObject@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 85 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObject::Type(void) const
-	?Fragmentation@CMemSpyApiHeap@@QAEHXZ @ 86 NONAME ; int CMemSpyApiHeap::Fragmentation(void)
-	?Name@CMemSpyApiKernelObject@@QBEABVTDesC16@@XZ @ 87 NONAME ; class TDesC16 const & CMemSpyApiKernelObject::Name(void) const
-	?TimerType@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerType@@XZ @ 88 NONAME ; enum TMemSpyDriverTimerType CMemSpyApiKernelObjectItem::TimerType(void) const
-	?ProcessSystemPermanentOrCritical@RMemSpySession@@QAEHVTProcessId@@H@Z @ 89 NONAME ; int RMemSpySession::ProcessSystemPermanentOrCritical(class TProcessId, int)
-	?SecurityZone@CMemSpyApiKernelObjectItem@@QBEIXZ @ 90 NONAME ; unsigned int CMemSpyApiKernelObjectItem::SecurityZone(void) const
-	?CreatorId@CMemSpyApiKernelObjectItem@@QBEIXZ @ 91 NONAME ; unsigned int CMemSpyApiKernelObjectItem::CreatorId(void) const
-	?MapCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 92 NONAME ; int CMemSpyApiKernelObjectItem::MapCount(void) const
-	?NameDetail@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 93 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameDetail(void) const
-	?OpenChannels@CMemSpyApiKernelObjectItem@@QAEHXZ @ 94 NONAME ; int CMemSpyApiKernelObjectItem::OpenChannels(void)
-	?Order@CMemSpyApiKernelObjectItem@@QBEEXZ @ 95 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Order(void) const
-	?ProcessPriority@CMemSpyApiThread@@QBE?AW4TProcessPriority@@XZ @ 96 NONAME ; enum TProcessPriority CMemSpyApiThread::ProcessPriority(void) const
-	?GetProcessesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiProcess@@@@W4TSortType@@@Z @ 97 NONAME ; void RMemSpySession::GetProcessesL(class RArray<class CMemSpyApiProcess *> &, enum TSortType)
-	?Handle@CMemSpyApiKernelObjectItem@@QBEPAXXZ @ 98 NONAME ; void * CMemSpyApiKernelObjectItem::Handle(void) const
-	?ParseMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 99 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ParseMask(void) const
-	?Attributes@CMemSpyApiKernelObjectItem@@QBEHXZ @ 100 NONAME ; int CMemSpyApiKernelObjectItem::Attributes(void) const
-	?DebugAllocatorLibrary@CMemSpyApiHeap@@QAEHXZ @ 101 NONAME ; int CMemSpyApiHeap::DebugAllocatorLibrary(void)
-	?ThreadNumberUsing@CMemSpyApiThread@@QBEHXZ @ 102 NONAME ; int CMemSpyApiThread::ThreadNumberUsing(void) const
-	?Overhead@CMemSpyApiHeap@@QAEHXZ @ 103 NONAME ; int CMemSpyApiHeap::Overhead(void)
-	?Connect@RMemSpySession@@QAEHXZ @ 104 NONAME ; int RMemSpySession::Connect(void)
-	??1CMemSpyApiThread@@QAE@XZ @ 105 NONAME ; CMemSpyApiThread::~CMemSpyApiThread(void)
-	?SID@CMemSpyApiThread@@QBEHXZ @ 106 NONAME ; int CMemSpyApiThread::SID(void) const
-	?AddressOfOwningThread@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 107 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningThread(void)
-	?GetKernelObjectItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 108 NONAME ; int RMemSpySession::GetKernelObjectItems(class RArray<class CMemSpyApiKernelObjectItem *> &, enum TMemSpyDriverContainerType)
-	?ProcessHandles@CMemSpyApiThread@@QBEHXZ @ 109 NONAME ; int CMemSpyApiThread::ProcessHandles(void) const
-	?ThreadPriority@CMemSpyApiThread@@QBE?AW4TThreadPriority@@XZ @ 110 NONAME ; enum TThreadPriority CMemSpyApiThread::ThreadPriority(void) const
-	?GetHeap@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 111 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeap(void)
-	?Name@CMemSpyApiThread@@QBEABVTDesC16@@XZ @ 112 NONAME ; class TDesC16 const & CMemSpyApiThread::Name(void) const
+	?GetThreadInfoItemsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiThreadInfoItem@@@@VTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 3 NONAME ; void RMemSpySession::GetThreadInfoItemsL(class RArray<class CMemSpyApiThreadInfoItem *> &, class TThreadId, enum TMemSpyThreadInfoItemType)
+	?Description@TMemSpyDeviceWideOperationProgress@@QBEABVTDesC16@@XZ @ 4 NONAME ; class TDesC16 const & TMemSpyDeviceWideOperationProgress::Description(void) const
+	?TotalOverhead@CMemSpyApiHeap@@QAEHXZ @ 5 NONAME ; int CMemSpyApiHeap::TotalOverhead(void)
+	?OutputDetailedPhoneInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 6 NONAME ; void RMemSpySession::OutputDetailedPhoneInfo(class TRequestStatus &)
+	?UniqueID@CMemSpyApiKernelObjectItem@@QBEHXZ @ 7 NONAME ; int CMemSpyApiKernelObjectItem::UniqueID(void) const
+	?OutputHeapData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 8 NONAME ; void RMemSpySession::OutputHeapData(class TRequestStatus &)
+	?SessionType@CMemSpyApiKernelObjectItem@@QBE?AW4TIpcSessionType@@XZ @ 9 NONAME ; enum TIpcSessionType CMemSpyApiKernelObjectItem::SessionType(void) const
+	?VID@CMemSpyApiThread@@QBEHXZ @ 10 NONAME ; int CMemSpyApiThread::VID(void) const
+	?OutputStackInfoL@RMemSpySession@@QAEXVTThreadId@@@Z @ 11 NONAME ; void RMemSpySession::OutputStackInfoL(class TThreadId)
+	?GetOutputSink@RMemSpySession@@QAEXW4TMemSpySinkType@@@Z @ 12 NONAME ; void RMemSpySession::GetOutputSink(enum TMemSpySinkType)
+	?FreeMemory@CMemSpyApiMemoryTrackingCycle@@QBEAB_JXZ @ 13 NONAME ; long long const & CMemSpyApiMemoryTrackingCycle::FreeMemory(void) const
+	?ProcessNumberUsing@CMemSpyApiThread@@QBEHXZ @ 14 NONAME ; int CMemSpyApiThread::ProcessNumberUsing(void) const
+	?PreviousCycleDiff@CMemSpyApiMemoryTrackingCycle@@QBE_JXZ @ 15 NONAME ; long long CMemSpyApiMemoryTrackingCycle::PreviousCycleDiff(void) const
+	?OutputStackDataL@RMemSpySession@@QAEXVTThreadId@@W4TMemSpyDriverDomainType@@@Z @ 16 NONAME ; void RMemSpySession::OutputStackDataL(class TThreadId, enum TMemSpyDriverDomainType)
+	?OutputThreadHeapDataL@RMemSpySession@@QAEXVTThreadId@@@Z @ 17 NONAME ; void RMemSpySession::OutputThreadHeapDataL(class TThreadId)
+	?ExitType@CMemSpyApiProcess@@QBE?AW4TExitType@@XZ @ 18 NONAME ; enum TExitType CMemSpyApiProcess::ExitType(void) const
+	?SwitchOutputToFileL@RMemSpySession@@QAEXABVTDesC16@@@Z @ 19 NONAME ; void RMemSpySession::SwitchOutputToFileL(class TDesC16 const &)
+	?OutputHeapCellListing@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 20 NONAME ; void RMemSpySession::OutputHeapCellListing(class TRequestStatus &)
+	?SetThreadPriorityL@RMemSpySession@@QAEXVTThreadId@@H@Z @ 21 NONAME ; void RMemSpySession::SetThreadPriorityL(class TThreadId, int)
+	?Restrictions@CMemSpyApiKernelObjectItem@@QBEIXZ @ 22 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Restrictions(void) const
+	?Id@CMemSpyApiKernelObjectItem@@QBEHXZ @ 23 NONAME ; int CMemSpyApiKernelObjectItem::Id(void) const
+	?Count@CMemSpyApiKernelObjectItem@@QBEHXZ @ 24 NONAME ; int CMemSpyApiKernelObjectItem::Count(void) const
+	?ControllingOwner@CMemSpyApiKernelObjectItem@@QBEIXZ @ 25 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ControllingOwner(void) const
+	?SwmtResetTracking@RMemSpySession@@QAEXXZ @ 26 NONAME ; void RMemSpySession::SwmtResetTracking(void)
+	?Version@CMemSpyApiKernelObjectItem@@QBE?AVTVersion@@XZ @ 27 NONAME ; class TVersion CMemSpyApiKernelObjectItem::Version(void) const
+	?SwitchToProcess@RMemSpySession@@QAEHVTProcessId@@H@Z @ 28 NONAME ; int RMemSpySession::SwitchToProcess(class TProcessId, int)
+	?MaxSize@CMemSpyApiKernelObjectItem@@QBEHXZ @ 29 NONAME ; int CMemSpyApiKernelObjectItem::MaxSize(void) const
+	?IsSwmtRunningL@RMemSpySession@@QAEHXZ @ 30 NONAME ; int RMemSpySession::IsSwmtRunningL(void)
+	?EndThread@RMemSpySession@@QAEHVTThreadId@@W4TMemSpyEndType@@@Z @ 31 NONAME ; int RMemSpySession::EndThread(class TThreadId, enum TMemSpyEndType)
+	?AddressOfOwningProcess@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 32 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningProcess(void)
+	?ExitReason@CMemSpyApiProcess@@QBEHXZ @ 33 NONAME ; int CMemSpyApiProcess::ExitReason(void) const
+	?MsgCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 34 NONAME ; int CMemSpyApiKernelObjectItem::MsgCount(void) const
+	?AllocationsCount@CMemSpyApiHeap@@QAEHXZ @ 35 NONAME ; int CMemSpyApiHeap::AllocationsCount(void)
+	?WaitCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 36 NONAME ; int CMemSpyApiKernelObjectItem::WaitCount(void) const
+	?SID@CMemSpyApiProcess@@QBEKXZ @ 37 NONAME ; unsigned long CMemSpyApiProcess::SID(void) const
+	?GetKernelObjectsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 38 NONAME ; void RMemSpySession::GetKernelObjectsL(class RArray<class CMemSpyApiKernelObject *> &)
+	?CycleNumber@CMemSpyApiMemoryTrackingCycle@@QBEHXZ @ 39 NONAME ; int CMemSpyApiMemoryTrackingCycle::CycleNumber(void) const
+	?Size@CMemSpyApiKernelObject@@QBE_JXZ @ 40 NONAME ; long long CMemSpyApiKernelObject::Size(void) const
+	?SetSwmtCategoriesL@RMemSpySession@@QAEXH@Z @ 41 NONAME ; void RMemSpySession::SetSwmtCategoriesL(int)
+	?CancelDeviceWideOperationL@RMemSpySession@@QAEXXZ @ 42 NONAME ; void RMemSpySession::CancelDeviceWideOperationL(void)
+	?TotalAllocations@CMemSpyApiHeap@@QAEHXZ @ 43 NONAME ; int CMemSpyApiHeap::TotalAllocations(void)
+	?Name@CMemSpyApiProcess@@QBEABVTDesC16@@XZ @ 44 NONAME ; class TDesC16 const & CMemSpyApiProcess::Name(void) const
+	?DumpKernelHeap@RMemSpySession@@QAEXXZ @ 45 NONAME ; void RMemSpySession::DumpKernelHeap(void)
+	?GetKernelObjects@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 46 NONAME ; int RMemSpySession::GetKernelObjects(class RArray<class CMemSpyApiKernelObject *> &)
+	?Priority@CMemSpyApiProcess@@QBE?AW4TProcessPriority@@XZ @ 47 NONAME ; enum TProcessPriority CMemSpyApiProcess::Priority(void) const
+	?HeaderSizeF@CMemSpyApiHeap@@QAEHXZ @ 48 NONAME ; int CMemSpyApiHeap::HeaderSizeF(void)
+	?OutputCompactStackInfoL@RMemSpySession@@QAEXXZ @ 49 NONAME ; void RMemSpySession::OutputCompactStackInfoL(void)
+	?MsgLimit@CMemSpyApiKernelObjectItem@@QBEHXZ @ 50 NONAME ; int CMemSpyApiKernelObjectItem::MsgLimit(void) const
+	?AddressOfDataBssStackChunk@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 51 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfDataBssStackChunk(void)
+	?Top@CMemSpyApiKernelObjectItem@@QBEHXZ @ 52 NONAME ; int CMemSpyApiKernelObjectItem::Top(void) const
+	?Resetting@CMemSpyApiKernelObjectItem@@QBEEXZ @ 53 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Resetting(void) const
+	?HeaderSizeA@CMemSpyApiHeap@@QAEHXZ @ 54 NONAME ; int CMemSpyApiHeap::HeaderSizeA(void)
+	?OutputHeapData@RMemSpySession@@QAEXXZ @ 55 NONAME ; void RMemSpySession::OutputHeapData(void)
+	?TotalAccessCount@CMemSpyApiKernelObjectItem@@QBEGXZ @ 56 NONAME ; unsigned short CMemSpyApiKernelObjectItem::TotalAccessCount(void) const
+	?Changes@CMemSpyApiKernelObjectItem@@QBEIXZ @ 57 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Changes(void) const
+	??0RMemSpySession@@QAE@XZ @ 58 NONAME ; RMemSpySession::RMemSpySession(void)
+	?OutputUserStackData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 59 NONAME ; void RMemSpySession::OutputUserStackData(class TRequestStatus &)
+	?AddressOfServer@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 60 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfServer(void)
+	?SetSwmtConfig@RMemSpySession@@QAEXVTMemSpyEngineHelperSysMemTrackerConfig@@@Z @ 61 NONAME ; void RMemSpySession::SetSwmtConfig(class TMemSpyEngineHelperSysMemTrackerConfig)
+	?Size@CMemSpyApiHeap@@QAEHXZ @ 62 NONAME ; int CMemSpyApiHeap::Size(void)
+	??1CMemSpyApiKernelObject@@QAE@XZ @ 63 NONAME ; CMemSpyApiKernelObject::~CMemSpyApiKernelObject(void)
+	?GetInfoItemType@RMemSpySession@@QAEHHVTThreadId@@AAW4TMemSpyThreadInfoItemType@@@Z @ 64 NONAME ; int RMemSpySession::GetInfoItemType(int, class TThreadId, enum TMemSpyThreadInfoItemType &)
+	??1CMemSpyApiHeap@@QAE@XZ @ 65 NONAME ; CMemSpyApiHeap::~CMemSpyApiHeap(void)
+	?SetSwmtHeapDumpsEnabledL@RMemSpySession@@QAEXH@Z @ 66 NONAME ; void RMemSpySession::SetSwmtHeapDumpsEnabledL(int)
+	?SetSwmtFilter@RMemSpySession@@QAEXABVTDesC16@@@Z @ 67 NONAME ; void RMemSpySession::SetSwmtFilter(class TDesC16 const &)
+	?Size@CMemSpyApiKernelObjectItem@@QBEKXZ @ 68 NONAME ; unsigned long CMemSpyApiKernelObjectItem::Size(void) const
+	?OutputThreadInfoHandlesL@RMemSpySession@@QAEXVTThreadId@@@Z @ 69 NONAME ; void RMemSpySession::OutputThreadInfoHandlesL(class TThreadId)
+	?OutputThreadHeapDataL@RMemSpySession@@QAEXABVTDesC16@@@Z @ 70 NONAME ; void RMemSpySession::OutputThreadHeapDataL(class TDesC16 const &)
+	?Type@CMemSpyApiKernelObject@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 71 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObject::Type(void) const
+	?Name@CMemSpyApiKernelObject@@QBEABVTDesC16@@XZ @ 72 NONAME ; class TDesC16 const & CMemSpyApiKernelObject::Name(void) const
+	?Fragmentation@CMemSpyApiHeap@@QAEHXZ @ 73 NONAME ; int CMemSpyApiHeap::Fragmentation(void)
+	?TimerType@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerType@@XZ @ 74 NONAME ; enum TMemSpyDriverTimerType CMemSpyApiKernelObjectItem::TimerType(void) const
+	?Value@CMemSpyApiThreadInfoItem@@QBEABVTDesC16@@XZ @ 75 NONAME ; class TDesC16 const & CMemSpyApiThreadInfoItem::Value(void) const
+	?SecurityZone@CMemSpyApiKernelObjectItem@@QBEIXZ @ 76 NONAME ; unsigned int CMemSpyApiKernelObjectItem::SecurityZone(void) const
+	?CreatorId@CMemSpyApiKernelObjectItem@@QBEIXZ @ 77 NONAME ; unsigned int CMemSpyApiKernelObjectItem::CreatorId(void) const
+	?Order@CMemSpyApiKernelObjectItem@@QBEEXZ @ 78 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Order(void) const
+	?NameDetail@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 79 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameDetail(void) const
+	?OutputStackInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 80 NONAME ; void RMemSpySession::OutputStackInfo(class TRequestStatus &)
+	?Handle@CMemSpyApiKernelObjectItem@@QBEPAXXZ @ 81 NONAME ; void * CMemSpyApiKernelObjectItem::Handle(void) const
+	?GetProcessesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiProcess@@@@W4TSortType@@@Z @ 82 NONAME ; void RMemSpySession::GetProcessesL(class RArray<class CMemSpyApiProcess *> &, enum TSortType)
+	?ParseMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 83 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ParseMask(void) const
+	?Attributes@CMemSpyApiKernelObjectItem@@QBEHXZ @ 84 NONAME ; int CMemSpyApiKernelObjectItem::Attributes(void) const
+	?MemoryDelta@CMemSpyApiMemoryTrackingCycle@@QBE_JXZ @ 85 NONAME ; long long CMemSpyApiMemoryTrackingCycle::MemoryDelta(void) const
+	?Caption@CMemSpyApiThreadInfoItem@@QBEABVTDesC16@@XZ @ 86 NONAME ; class TDesC16 const & CMemSpyApiThreadInfoItem::Caption(void) const
+	?DebugAllocatorLibrary@CMemSpyApiHeap@@QAEHXZ @ 87 NONAME ; int CMemSpyApiHeap::DebugAllocatorLibrary(void)
+	?Overhead@CMemSpyApiHeap@@QAEHXZ @ 88 NONAME ; int CMemSpyApiHeap::Overhead(void)
+	?ForceSwmtUpdate@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 89 NONAME ; void RMemSpySession::ForceSwmtUpdate(class TRequestStatus &)
+	?GetHeapL@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 90 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeapL(void)
+	?OutputKernelStackData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 91 NONAME ; void RMemSpySession::OutputKernelStackData(class TRequestStatus &)
+	?AddressOfOwningThread@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 92 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningThread(void)
+	?ThreadPriority@CMemSpyApiThread@@QBE?AW4TThreadPriority@@XZ @ 93 NONAME ; enum TThreadPriority CMemSpyApiThread::ThreadPriority(void) const
+	?GetHeap@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 94 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeap(void)
+	??1CMemSpyApiMemoryTrackingCycle@@QAE@XZ @ 95 NONAME ; CMemSpyApiMemoryTrackingCycle::~CMemSpyApiMemoryTrackingCycle(void)
+	?AccessCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 96 NONAME ; int CMemSpyApiKernelObjectItem::AccessCount(void) const
+	?OutputHeapInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 97 NONAME ; void RMemSpySession::OutputHeapInfo(class TRequestStatus &)
+	?Time@CMemSpyApiMemoryTrackingCycle@@QBEABVTTime@@XZ @ 98 NONAME ; class TTime const & CMemSpyApiMemoryTrackingCycle::Time(void) const
+	?SetSwmtTimerIntervalL@RMemSpySession@@QAEXH@Z @ 99 NONAME ; void RMemSpySession::SetSwmtTimerIntervalL(int)
+	?MaxLength@CMemSpyApiHeap@@QAEHXZ @ 100 NONAME ; int CMemSpyApiHeap::MaxLength(void)
+	?OutputKernelHeapData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 101 NONAME ; void RMemSpySession::OutputKernelHeapData(class TRequestStatus &)
+	?AddressOfKernelOwner@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 102 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfKernelOwner(void)
+	??1CMemSpyApiThreadInfoItem@@QAE@XZ @ 103 NONAME ; CMemSpyApiThreadInfoItem::~CMemSpyApiThreadInfoItem(void)
+	?FreeCount@CMemSpyApiHeap@@QAEHXZ @ 104 NONAME ; int CMemSpyApiHeap::FreeCount(void)
+	?TotalFree@CMemSpyApiHeap@@QAEHXZ @ 105 NONAME ; int CMemSpyApiHeap::TotalFree(void)
+	?SwitchToThread@RMemSpySession@@QAEHVTThreadId@@H@Z @ 106 NONAME ; int RMemSpySession::SwitchToThread(class TThreadId, int)
+	?FreeOverhead@CMemSpyApiHeap@@QAEHXZ @ 107 NONAME ; int CMemSpyApiHeap::FreeOverhead(void)
+	?SwitchOutputToTraceL@RMemSpySession@@QAEXXZ @ 108 NONAME ; void RMemSpySession::SwitchOutputToTraceL(void)
+	?SlackFreeSpace@CMemSpyApiHeap@@QAEHXZ @ 109 NONAME ; int CMemSpyApiHeap::SlackFreeSpace(void)
+	?ForceSwmtUpdateL@RMemSpySession@@QAEXXZ @ 110 NONAME ; void RMemSpySession::ForceSwmtUpdateL(void)
+	?Priority@CMemSpyApiKernelObjectItem@@QBEHXZ @ 111 NONAME ; int CMemSpyApiKernelObjectItem::Priority(void) const
+	?ThreadCount@CMemSpyApiProcess@@QBEHXZ @ 112 NONAME ; int CMemSpyApiProcess::ThreadCount(void) const
+	?Caption@CMemSpyApiMemoryTrackingCycle@@QBEABVTDesC16@@XZ @ 113 NONAME ; class TDesC16 const & CMemSpyApiMemoryTrackingCycle::Caption(void) const
+	?RequestCount@CMemSpyApiThread@@QBEHXZ @ 114 NONAME ; int CMemSpyApiThread::RequestCount(void) const
+	?StopSwmtTimerL@RMemSpySession@@QAEXXZ @ 115 NONAME ; void RMemSpySession::StopSwmtTimerL(void)
+	??1CMemSpyApiProcess@@QAE@XZ @ 116 NONAME ; CMemSpyApiProcess::~CMemSpyApiProcess(void)
+	?MinLength@CMemSpyApiHeap@@QAEHXZ @ 117 NONAME ; int CMemSpyApiHeap::MinLength(void)
+	?ExitCategory@CMemSpyApiProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 118 NONAME ; class TBuf<16> CMemSpyApiProcess::ExitCategory(void) const
+	?Progress@TMemSpyDeviceWideOperationProgress@@QBEHXZ @ 119 NONAME ; int TMemSpyDeviceWideOperationProgress::Progress(void) const
+	?Count@CMemSpyApiKernelObject@@QBEHXZ @ 120 NONAME ; int CMemSpyApiKernelObject::Count(void) const
+	?StartPos@CMemSpyApiKernelObjectItem@@QBEHXZ @ 121 NONAME ; int CMemSpyApiKernelObjectItem::StartPos(void) const
+	?TimerState@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerState@@XZ @ 122 NONAME ; enum TMemSpyDriverTimerState CMemSpyApiKernelObjectItem::TimerState(void) const
+	?BaseAddress@CMemSpyApiHeap@@QAEHXZ @ 123 NONAME ; int CMemSpyApiHeap::BaseAddress(void)
+	?ExitType@CMemSpyApiThread@@QBE?AW4TExitType@@XZ @ 124 NONAME ; enum TExitType CMemSpyApiThread::ExitType(void) const
+	?StartSwmtTimerL@RMemSpySession@@QAEXH@Z @ 125 NONAME ; void RMemSpySession::StartSwmtTimerL(int)
+	?Type@CMemSpyApiHeap@@QAEAAVTDesC16@@XZ @ 126 NONAME ; class TDesC16 & CMemSpyApiHeap::Type(void)
+	?Id@CMemSpyApiProcess@@QBE?AVTProcessId@@XZ @ 127 NONAME ; class TProcessId CMemSpyApiProcess::Id(void) const
+	?BiggestAllocation@CMemSpyApiHeap@@QAEHXZ @ 128 NONAME ; int CMemSpyApiHeap::BiggestAllocation(void)
+	??1CMemSpyApiKernelObjectItem@@QAE@XZ @ 129 NONAME ; CMemSpyApiKernelObjectItem::~CMemSpyApiKernelObjectItem(void)
+	?AllocationOverhead@CMemSpyApiHeap@@QAEHXZ @ 130 NONAME ; int CMemSpyApiHeap::AllocationOverhead(void)
+	?NameOfOwner@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 131 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameOfOwner(void) const
+	?OutputAllContainerContents@RMemSpySession@@QAEXXZ @ 132 NONAME ; void RMemSpySession::OutputAllContainerContents(void)
+	?OutputKernelObjectsL@RMemSpySession@@QAEXXZ @ 133 NONAME ; void RMemSpySession::OutputKernelObjectsL(void)
+	?ThreadSystemPermanentOrCritical@RMemSpySession@@QAEHVTThreadId@@H@Z @ 134 NONAME ; int RMemSpySession::ThreadSystemPermanentOrCritical(class TThreadId, int)
+	?Protection@CMemSpyApiKernelObjectItem@@QBEIXZ @ 135 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Protection(void) const
+	?BiggestFree@CMemSpyApiHeap@@QAEHXZ @ 136 NONAME ; int CMemSpyApiHeap::BiggestFree(void)
+	?Attributes@CMemSpyApiThread@@QBEHXZ @ 137 NONAME ; int CMemSpyApiThread::Attributes(void) const
+	?Bottom@CMemSpyApiKernelObjectItem@@QBEHXZ @ 138 NONAME ; int CMemSpyApiKernelObjectItem::Bottom(void) const
+	?StartSwmtTimerL@RMemSpySession@@QAEXXZ @ 139 NONAME ; void RMemSpySession::StartSwmtTimerL(void)
+	?GetKernelObjectItemsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 140 NONAME ; void RMemSpySession::GetKernelObjectItemsL(class RArray<class CMemSpyApiKernelObjectItem *> &, enum TMemSpyDriverContainerType)
+	?NotifyDeviceWideOperationProgress@RMemSpySession@@QAEXAAVTMemSpyDeviceWideOperationProgress@@AAVTRequestStatus@@@Z @ 141 NONAME ; void RMemSpySession::NotifyDeviceWideOperationProgress(class TMemSpyDeviceWideOperationProgress &, class TRequestStatus &)
+	?OutputCompactHeapInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 142 NONAME ; void RMemSpySession::OutputCompactHeapInfo(class TRequestStatus &)
+	?OutputPhoneInfo@RMemSpySession@@QAEXXZ @ 143 NONAME ; void RMemSpySession::OutputPhoneInfo(void)
+	?ThreadHandles@CMemSpyApiThread@@QBEHXZ @ 144 NONAME ; int CMemSpyApiThread::ThreadHandles(void) const
+	?SvrSessionType@CMemSpyApiKernelObjectItem@@QBEEXZ @ 145 NONAME ; unsigned char CMemSpyApiKernelObjectItem::SvrSessionType(void) const
+	?SwitchOutputSinkL@RMemSpySession@@QAEXW4TMemSpySinkType@@@Z @ 146 NONAME ; void RMemSpySession::SwitchOutputSinkL(enum TMemSpySinkType)
+	?ChunkType@CMemSpyApiKernelObjectItem@@QBEIXZ @ 147 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ChunkType(void) const
+	?Id@CMemSpyApiThread@@QBE?AVTThreadId@@XZ @ 148 NONAME ; class TThreadId CMemSpyApiThread::Id(void) const
+	?OutputPhoneInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 149 NONAME ; void RMemSpySession::OutputPhoneInfo(class TRequestStatus &)
+	?GetProcessIdByNameL@RMemSpySession@@QAE?AVTProcessId@@ABVTDesC16@@@Z @ 150 NONAME ; class TProcessId RMemSpySession::GetProcessIdByNameL(class TDesC16 const &)
+	?GetMemoryTrackingCyclesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiMemoryTrackingCycle@@@@@Z @ 151 NONAME ; void RMemSpySession::GetMemoryTrackingCyclesL(class RArray<class CMemSpyApiMemoryTrackingCycle *> &)
+	?MapAttr@CMemSpyApiKernelObjectItem@@QBEIXZ @ 152 NONAME ; unsigned int CMemSpyApiKernelObjectItem::MapAttr(void) const
+	?OutputCompactStackInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 153 NONAME ; void RMemSpySession::OutputCompactStackInfo(class TRequestStatus &)
+	?VID@CMemSpyApiProcess@@QBEKXZ @ 154 NONAME ; unsigned long CMemSpyApiProcess::VID(void) const
+	?AddressOfCodeSeg@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 155 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfCodeSeg(void)
+	?GetThreadsL@RMemSpySession@@QAEXVTProcessId@@AAV?$RArray@PAVCMemSpyApiThread@@@@W4TSortType@@@Z @ 156 NONAME ; void RMemSpySession::GetThreadsL(class TProcessId, class RArray<class CMemSpyApiThread *> &, enum TSortType)
+	?ProcessId@CMemSpyApiThread@@QBE?AVTProcessId@@XZ @ 157 NONAME ; class TProcessId CMemSpyApiThread::ProcessId(void) const
+	?Type@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 158 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObjectItem::Type(void) const
+	?ChunkSize@CMemSpyApiHeap@@QAEHXZ @ 159 NONAME ; int CMemSpyApiHeap::ChunkSize(void)
+	?UnitsMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 160 NONAME ; unsigned int CMemSpyApiKernelObjectItem::UnitsMask(void) const
+	?State@CMemSpyApiKernelObjectItem@@QBEEXZ @ 161 NONAME ; unsigned char CMemSpyApiKernelObjectItem::State(void) const
+	?Shared@CMemSpyApiHeap@@QAEHXZ @ 162 NONAME ; int CMemSpyApiHeap::Shared(void)
+	?SetSwmtAutoStartProcessList@RMemSpySession@@QAEXPAV?$CArrayFixFlat@VTUid@@@@@Z @ 163 NONAME ; void RMemSpySession::SetSwmtAutoStartProcessList(class CArrayFixFlat<class TUid> *)
+	?OutputCompactHeapInfoL@RMemSpySession@@QAEXXZ @ 164 NONAME ; void RMemSpySession::OutputCompactHeapInfoL(void)
+	?ProcessSystemPermanentOrCritical@RMemSpySession@@QAEHVTProcessId@@H@Z @ 165 NONAME ; int RMemSpySession::ProcessSystemPermanentOrCritical(class TProcessId, int)
+	?OutputKernelHeapDataL@RMemSpySession@@QAEXXZ @ 166 NONAME ; void RMemSpySession::OutputKernelHeapDataL(void)
+	?MapCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 167 NONAME ; int CMemSpyApiKernelObjectItem::MapCount(void) const
+	?OpenChannels@CMemSpyApiKernelObjectItem@@QAEHXZ @ 168 NONAME ; int CMemSpyApiKernelObjectItem::OpenChannels(void)
+	?EndProcess@RMemSpySession@@QAEHVTProcessId@@W4TMemSpyEndType@@@Z @ 169 NONAME ; int RMemSpySession::EndProcess(class TProcessId, enum TMemSpyEndType)
+	?ProcessPriority@CMemSpyApiThread@@QBE?AW4TProcessPriority@@XZ @ 170 NONAME ; enum TProcessPriority CMemSpyApiThread::ProcessPriority(void) const
+	?OutputAOListL@RMemSpySession@@QAEXVTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 171 NONAME ; void RMemSpySession::OutputAOListL(class TThreadId, enum TMemSpyThreadInfoItemType)
+	?ThreadNumberUsing@CMemSpyApiThread@@QBEHXZ @ 172 NONAME ; int CMemSpyApiThread::ThreadNumberUsing(void) const
+	?OutputHeapInfoUserL@RMemSpySession@@QAEXVTThreadId@@@Z @ 173 NONAME ; void RMemSpySession::OutputHeapInfoUserL(class TThreadId)
+	?OutputThreadCellListL@RMemSpySession@@QAEXVTThreadId@@@Z @ 174 NONAME ; void RMemSpySession::OutputThreadCellListL(class TThreadId)
+	?GetThreadInfoItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiThreadInfoItem@@@@VTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 175 NONAME ; int RMemSpySession::GetThreadInfoItems(class RArray<class CMemSpyApiThreadInfoItem *> &, class TThreadId, enum TMemSpyThreadInfoItemType)
+	??1CMemSpyApiThread@@QAE@XZ @ 176 NONAME ; CMemSpyApiThread::~CMemSpyApiThread(void)
+	?Connect@RMemSpySession@@QAEHXZ @ 177 NONAME ; int RMemSpySession::Connect(void)
+	?SID@CMemSpyApiThread@@QBEHXZ @ 178 NONAME ; int CMemSpyApiThread::SID(void) const
+	?GetKernelObjectItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 179 NONAME ; int RMemSpySession::GetKernelObjectItems(class RArray<class CMemSpyApiKernelObjectItem *> &, enum TMemSpyDriverContainerType)
+	?ProcessHandles@CMemSpyApiThread@@QBEHXZ @ 180 NONAME ; int CMemSpyApiThread::ProcessHandles(void) const
+	?Name@CMemSpyApiThread@@QBEABVTDesC16@@XZ @ 181 NONAME ; class TDesC16 const & CMemSpyApiThread::Name(void) const
+	?IsDead@CMemSpyApiProcess@@QBEHXZ @ 182 NONAME ; int CMemSpyApiProcess::IsDead(void) const
 
--- a/memspy/MemSpyClient/eabi/MemSpyClientu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/eabi/MemSpyClientu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -23,98 +23,170 @@
 	_ZN14CMemSpyApiHeap9TotalFreeEv @ 22 NONAME
 	_ZN14CMemSpyApiHeapD1Ev @ 23 NONAME
 	_ZN14CMemSpyApiHeapD2Ev @ 24 NONAME
-	_ZN14RMemSpySession10EndProcessE10TProcessId8TEndType @ 25 NONAME
+	_ZN14RMemSpySession10EndProcessE10TProcessId14TMemSpyEndType @ 25 NONAME
 	_ZN14RMemSpySession11GetThreadsLE10TProcessIdR6RArrayIP16CMemSpyApiThreadE9TSortType @ 26 NONAME
-	_ZN14RMemSpySession13GetProcessesLER6RArrayIP17CMemSpyApiProcessE9TSortType @ 27 NONAME
-	_ZN14RMemSpySession14SwitchToThreadE9TThreadIdi @ 28 NONAME
-	_ZN14RMemSpySession15SwitchToProcessE10TProcessIdi @ 29 NONAME
-	_ZN14RMemSpySession16GetKernelObjectsER6RArrayIP22CMemSpyApiKernelObjectE @ 30 NONAME
-	_ZN14RMemSpySession20GetKernelObjectItemsER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 31 NONAME
-	_ZN14RMemSpySession31ThreadSystemPermanentOrCriticalE9TThreadIdi @ 32 NONAME
-	_ZN14RMemSpySession32ProcessSystemPermanentOrCriticalE10TProcessIdi @ 33 NONAME
-	_ZN14RMemSpySession7ConnectEv @ 34 NONAME
-	_ZN14RMemSpySession7GetHeapEv @ 35 NONAME
-	_ZN14RMemSpySession9EndThreadE9TThreadId8TEndType @ 36 NONAME
-	_ZN14RMemSpySessionC1Ev @ 37 NONAME
-	_ZN14RMemSpySessionC2Ev @ 38 NONAME
-	_ZN16CMemSpyApiThreadD1Ev @ 39 NONAME
-	_ZN16CMemSpyApiThreadD2Ev @ 40 NONAME
-	_ZN17CMemSpyApiProcessD1Ev @ 41 NONAME
-	_ZN17CMemSpyApiProcessD2Ev @ 42 NONAME
-	_ZN22CMemSpyApiKernelObjectD1Ev @ 43 NONAME
-	_ZN22CMemSpyApiKernelObjectD2Ev @ 44 NONAME
-	_ZN26CMemSpyApiKernelObjectItem12OpenChannelsEv @ 45 NONAME
-	_ZN26CMemSpyApiKernelObjectItem15AddressOfServerEv @ 46 NONAME
-	_ZN26CMemSpyApiKernelObjectItem16AddressOfCodeSegEv @ 47 NONAME
-	_ZN26CMemSpyApiKernelObjectItem20AddressOfKernelOwnerEv @ 48 NONAME
-	_ZN26CMemSpyApiKernelObjectItem21AddressOfOwningThreadEv @ 49 NONAME
-	_ZN26CMemSpyApiKernelObjectItem22AddressOfOwningProcessEv @ 50 NONAME
-	_ZN26CMemSpyApiKernelObjectItem26AddressOfDataBssStackChunkEv @ 51 NONAME
-	_ZN26CMemSpyApiKernelObjectItemD1Ev @ 52 NONAME
-	_ZN26CMemSpyApiKernelObjectItemD2Ev @ 53 NONAME
-	_ZNK16CMemSpyApiThread10AttributesEv @ 54 NONAME
-	_ZNK16CMemSpyApiThread12RequestCountEv @ 55 NONAME
-	_ZNK16CMemSpyApiThread13ThreadHandlesEv @ 56 NONAME
-	_ZNK16CMemSpyApiThread14ProcessHandlesEv @ 57 NONAME
-	_ZNK16CMemSpyApiThread14ThreadPriorityEv @ 58 NONAME
-	_ZNK16CMemSpyApiThread15ProcessPriorityEv @ 59 NONAME
-	_ZNK16CMemSpyApiThread17ThreadNumberUsingEv @ 60 NONAME
-	_ZNK16CMemSpyApiThread18ProcessNumberUsingEv @ 61 NONAME
-	_ZNK16CMemSpyApiThread2IdEv @ 62 NONAME
-	_ZNK16CMemSpyApiThread3SIDEv @ 63 NONAME
-	_ZNK16CMemSpyApiThread3VIDEv @ 64 NONAME
-	_ZNK16CMemSpyApiThread4NameEv @ 65 NONAME
-	_ZNK16CMemSpyApiThread6CpuUseEv @ 66 NONAME
-	_ZNK16CMemSpyApiThread8ExitTypeEv @ 67 NONAME
-	_ZNK16CMemSpyApiThread9ProcessIdEv @ 68 NONAME
-	_ZNK17CMemSpyApiProcess10ExitReasonEv @ 69 NONAME
-	_ZNK17CMemSpyApiProcess11ThreadCountEv @ 70 NONAME
-	_ZNK17CMemSpyApiProcess12ExitCategoryEv @ 71 NONAME
-	_ZNK17CMemSpyApiProcess2IdEv @ 72 NONAME
-	_ZNK17CMemSpyApiProcess4NameEv @ 73 NONAME
-	_ZNK17CMemSpyApiProcess8ExitTypeEv @ 74 NONAME
-	_ZNK22CMemSpyApiKernelObject4NameEv @ 75 NONAME
-	_ZNK22CMemSpyApiKernelObject4SizeEv @ 76 NONAME
-	_ZNK22CMemSpyApiKernelObject4TypeEv @ 77 NONAME
-	_ZNK22CMemSpyApiKernelObject5CountEv @ 78 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem10AttributesEv @ 79 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem10NameDetailEv @ 80 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem10ProtectionEv @ 81 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem10TimerStateEv @ 82 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem11AccessCountEv @ 83 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem11NameOfOwnerEv @ 84 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem11SessionTypeEv @ 85 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem12RestrictionsEv @ 86 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem12SecurityZoneEv @ 87 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem14SvrSessionTypeEv @ 88 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem16ControllingOwnerEv @ 89 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem16TotalAccessCountEv @ 90 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem2IdEv @ 91 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem3TopEv @ 92 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem4NameEv @ 93 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem4SizeEv @ 94 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem4TypeEv @ 95 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem5CountEv @ 96 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem5OrderEv @ 97 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem5StateEv @ 98 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem6BottomEv @ 99 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem6HandleEv @ 100 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem7ChangesEv @ 101 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem7MapAttrEv @ 102 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem7MaxSizeEv @ 103 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem7VersionEv @ 104 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8MapCountEv @ 105 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8MsgCountEv @ 106 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8MsgLimitEv @ 107 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8PriorityEv @ 108 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8StartPosEv @ 109 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem8UniqueIDEv @ 110 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9ChunkTypeEv @ 111 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9CreatorIdEv @ 112 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9ParseMaskEv @ 113 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9ResettingEv @ 114 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9TimerTypeEv @ 115 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9UnitsMaskEv @ 116 NONAME
-	_ZNK26CMemSpyApiKernelObjectItem9WaitCountEv @ 117 NONAME
-	_ZN14RMemSpySession18SetThreadPriorityLE9TThreadIdi @ 118 NONAME
+	_ZN14RMemSpySession13GetOutputSinkE15TMemSpySinkType @ 27 NONAME
+	_ZN14RMemSpySession13GetProcessesLER6RArrayIP17CMemSpyApiProcessE9TSortType @ 28 NONAME
+	_ZN14RMemSpySession13OutputAOListLE9TThreadId25TMemSpyThreadInfoItemType @ 29 NONAME
+	_ZN14RMemSpySession13SetSwmtConfigE38TMemSpyEngineHelperSysMemTrackerConfig @ 30 NONAME
+	_ZN14RMemSpySession13SetSwmtFilterERK7TDesC16 @ 31 NONAME
+	_ZN14RMemSpySession14DumpKernelHeapEv @ 32 NONAME
+	_ZN14RMemSpySession14IsSwmtRunningLEv @ 33 NONAME
+	_ZN14RMemSpySession14OutputHeapDataER14TRequestStatus @ 34 NONAME
+	_ZN14RMemSpySession14OutputHeapDataEv @ 35 NONAME
+	_ZN14RMemSpySession14OutputHeapInfoER14TRequestStatus @ 36 NONAME
+	_ZN14RMemSpySession14StopSwmtTimerLEv @ 37 NONAME
+	_ZN14RMemSpySession14SwitchToThreadE9TThreadIdi @ 38 NONAME
+	_ZN14RMemSpySession15ForceSwmtUpdateER14TRequestStatus @ 39 NONAME
+	_ZN14RMemSpySession15GetInfoItemTypeEi9TThreadIdR25TMemSpyThreadInfoItemType @ 40 NONAME
+	_ZN14RMemSpySession15OutputPhoneInfoER14TRequestStatus @ 41 NONAME
+	_ZN14RMemSpySession15OutputPhoneInfoEv @ 42 NONAME
+	_ZN14RMemSpySession15OutputStackInfoER14TRequestStatus @ 43 NONAME
+	_ZN14RMemSpySession15StartSwmtTimerLEi @ 44 NONAME
+	_ZN14RMemSpySession15StartSwmtTimerLEv @ 45 NONAME
+	_ZN14RMemSpySession15SwitchToProcessE10TProcessIdi @ 46 NONAME
+	_ZN14RMemSpySession16ForceSwmtUpdateLEv @ 47 NONAME
+	_ZN14RMemSpySession16GetKernelObjectsER6RArrayIP22CMemSpyApiKernelObjectE @ 48 NONAME
+	_ZN14RMemSpySession16OutputStackDataLE9TThreadId23TMemSpyDriverDomainType @ 49 NONAME
+	_ZN14RMemSpySession16OutputStackInfoLE9TThreadId @ 50 NONAME
+	_ZN14RMemSpySession17GetKernelObjectsLER6RArrayIP22CMemSpyApiKernelObjectE @ 51 NONAME
+	_ZN14RMemSpySession17SwitchOutputSinkLE15TMemSpySinkType @ 52 NONAME
+	_ZN14RMemSpySession17SwmtResetTrackingEv @ 53 NONAME
+	_ZN14RMemSpySession18GetThreadInfoItemsER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 54 NONAME
+	_ZN14RMemSpySession18SetSwmtCategoriesLEi @ 55 NONAME
+	_ZN14RMemSpySession18SetThreadPriorityLE9TThreadIdi @ 56 NONAME
+	_ZN14RMemSpySession19GetProcessIdByNameLERK7TDesC16 @ 57 NONAME
+	_ZN14RMemSpySession19GetThreadInfoItemsLER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 58 NONAME
+	_ZN14RMemSpySession19OutputHeapInfoUserLE9TThreadId @ 59 NONAME
+	_ZN14RMemSpySession19OutputUserStackDataER14TRequestStatus @ 60 NONAME
+	_ZN14RMemSpySession19SwitchOutputToFileLERK7TDesC16 @ 61 NONAME
+	_ZN14RMemSpySession20GetKernelObjectItemsER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 62 NONAME
+	_ZN14RMemSpySession20OutputKernelHeapDataER14TRequestStatus @ 63 NONAME
+	_ZN14RMemSpySession20OutputKernelObjectsLEv @ 64 NONAME
+	_ZN14RMemSpySession20SwitchOutputToTraceLEv @ 65 NONAME
+	_ZN14RMemSpySession21GetKernelObjectItemsLER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 66 NONAME
+	_ZN14RMemSpySession21OutputCompactHeapInfoER14TRequestStatus @ 67 NONAME
+	_ZN14RMemSpySession21OutputHeapCellListingER14TRequestStatus @ 68 NONAME
+	_ZN14RMemSpySession21OutputKernelHeapDataLEv @ 69 NONAME
+	_ZN14RMemSpySession21OutputKernelStackDataER14TRequestStatus @ 70 NONAME
+	_ZN14RMemSpySession21OutputThreadCellListLE9TThreadId @ 71 NONAME
+	_ZN14RMemSpySession21OutputThreadHeapDataLE9TThreadId @ 72 NONAME
+	_ZN14RMemSpySession21OutputThreadHeapDataLERK7TDesC16 @ 73 NONAME
+	_ZN14RMemSpySession21SetSwmtTimerIntervalLEi @ 74 NONAME
+	_ZN14RMemSpySession22OutputCompactHeapInfoLEv @ 75 NONAME
+	_ZN14RMemSpySession22OutputCompactStackInfoER14TRequestStatus @ 76 NONAME
+	_ZN14RMemSpySession23OutputCompactStackInfoLEv @ 77 NONAME
+	_ZN14RMemSpySession23OutputDetailedPhoneInfoER14TRequestStatus @ 78 NONAME
+	_ZN14RMemSpySession24GetMemoryTrackingCyclesLER6RArrayIP29CMemSpyApiMemoryTrackingCycleE @ 79 NONAME
+	_ZN14RMemSpySession24OutputThreadInfoHandlesLE9TThreadId @ 80 NONAME
+	_ZN14RMemSpySession24SetSwmtHeapDumpsEnabledLEi @ 81 NONAME
+	_ZN14RMemSpySession26CancelDeviceWideOperationLEv @ 82 NONAME
+	_ZN14RMemSpySession26OutputAllContainerContentsEv @ 83 NONAME
+	_ZN14RMemSpySession27SetSwmtAutoStartProcessListEP13CArrayFixFlatI4TUidE @ 84 NONAME
+	_ZN14RMemSpySession31ThreadSystemPermanentOrCriticalE9TThreadIdi @ 85 NONAME
+	_ZN14RMemSpySession32ProcessSystemPermanentOrCriticalE10TProcessIdi @ 86 NONAME
+	_ZN14RMemSpySession33NotifyDeviceWideOperationProgressER34TMemSpyDeviceWideOperationProgressR14TRequestStatus @ 87 NONAME
+	_ZN14RMemSpySession7ConnectEv @ 88 NONAME
+	_ZN14RMemSpySession7GetHeapEv @ 89 NONAME
+	_ZN14RMemSpySession8GetHeapLEv @ 90 NONAME
+	_ZN14RMemSpySession9EndThreadE9TThreadId14TMemSpyEndType @ 91 NONAME
+	_ZN14RMemSpySessionC1Ev @ 92 NONAME
+	_ZN14RMemSpySessionC2Ev @ 93 NONAME
+	_ZN16CMemSpyApiThreadD1Ev @ 94 NONAME
+	_ZN16CMemSpyApiThreadD2Ev @ 95 NONAME
+	_ZN17CMemSpyApiProcessD1Ev @ 96 NONAME
+	_ZN17CMemSpyApiProcessD2Ev @ 97 NONAME
+	_ZN22CMemSpyApiKernelObjectD1Ev @ 98 NONAME
+	_ZN22CMemSpyApiKernelObjectD2Ev @ 99 NONAME
+	_ZN24CMemSpyApiThreadInfoItemD1Ev @ 100 NONAME
+	_ZN24CMemSpyApiThreadInfoItemD2Ev @ 101 NONAME
+	_ZN26CMemSpyApiKernelObjectItem12OpenChannelsEv @ 102 NONAME
+	_ZN26CMemSpyApiKernelObjectItem15AddressOfServerEv @ 103 NONAME
+	_ZN26CMemSpyApiKernelObjectItem16AddressOfCodeSegEv @ 104 NONAME
+	_ZN26CMemSpyApiKernelObjectItem20AddressOfKernelOwnerEv @ 105 NONAME
+	_ZN26CMemSpyApiKernelObjectItem21AddressOfOwningThreadEv @ 106 NONAME
+	_ZN26CMemSpyApiKernelObjectItem22AddressOfOwningProcessEv @ 107 NONAME
+	_ZN26CMemSpyApiKernelObjectItem26AddressOfDataBssStackChunkEv @ 108 NONAME
+	_ZN26CMemSpyApiKernelObjectItemD1Ev @ 109 NONAME
+	_ZN26CMemSpyApiKernelObjectItemD2Ev @ 110 NONAME
+	_ZN29CMemSpyApiMemoryTrackingCycleD1Ev @ 111 NONAME
+	_ZN29CMemSpyApiMemoryTrackingCycleD2Ev @ 112 NONAME
+	_ZNK16CMemSpyApiThread10AttributesEv @ 113 NONAME
+	_ZNK16CMemSpyApiThread12RequestCountEv @ 114 NONAME
+	_ZNK16CMemSpyApiThread13ThreadHandlesEv @ 115 NONAME
+	_ZNK16CMemSpyApiThread14ProcessHandlesEv @ 116 NONAME
+	_ZNK16CMemSpyApiThread14ThreadPriorityEv @ 117 NONAME
+	_ZNK16CMemSpyApiThread15ProcessPriorityEv @ 118 NONAME
+	_ZNK16CMemSpyApiThread17ThreadNumberUsingEv @ 119 NONAME
+	_ZNK16CMemSpyApiThread18ProcessNumberUsingEv @ 120 NONAME
+	_ZNK16CMemSpyApiThread2IdEv @ 121 NONAME
+	_ZNK16CMemSpyApiThread3SIDEv @ 122 NONAME
+	_ZNK16CMemSpyApiThread3VIDEv @ 123 NONAME
+	_ZNK16CMemSpyApiThread4NameEv @ 124 NONAME
+	_ZNK16CMemSpyApiThread6CpuUseEv @ 125 NONAME
+	_ZNK16CMemSpyApiThread8ExitTypeEv @ 126 NONAME
+	_ZNK16CMemSpyApiThread9ProcessIdEv @ 127 NONAME
+	_ZNK17CMemSpyApiProcess10ExitReasonEv @ 128 NONAME
+	_ZNK17CMemSpyApiProcess11ThreadCountEv @ 129 NONAME
+	_ZNK17CMemSpyApiProcess12ExitCategoryEv @ 130 NONAME
+	_ZNK17CMemSpyApiProcess2IdEv @ 131 NONAME
+	_ZNK17CMemSpyApiProcess3SIDEv @ 132 NONAME
+	_ZNK17CMemSpyApiProcess3VIDEv @ 133 NONAME
+	_ZNK17CMemSpyApiProcess4NameEv @ 134 NONAME
+	_ZNK17CMemSpyApiProcess8ExitTypeEv @ 135 NONAME
+	_ZNK17CMemSpyApiProcess8PriorityEv @ 136 NONAME
+	_ZNK22CMemSpyApiKernelObject4NameEv @ 137 NONAME
+	_ZNK22CMemSpyApiKernelObject4SizeEv @ 138 NONAME
+	_ZNK22CMemSpyApiKernelObject4TypeEv @ 139 NONAME
+	_ZNK22CMemSpyApiKernelObject5CountEv @ 140 NONAME
+	_ZNK24CMemSpyApiThreadInfoItem5ValueEv @ 141 NONAME
+	_ZNK24CMemSpyApiThreadInfoItem7CaptionEv @ 142 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem10AttributesEv @ 143 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem10NameDetailEv @ 144 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem10ProtectionEv @ 145 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem10TimerStateEv @ 146 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem11AccessCountEv @ 147 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem11NameOfOwnerEv @ 148 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem11SessionTypeEv @ 149 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem12RestrictionsEv @ 150 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem12SecurityZoneEv @ 151 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem14SvrSessionTypeEv @ 152 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem16ControllingOwnerEv @ 153 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem16TotalAccessCountEv @ 154 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem2IdEv @ 155 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem3TopEv @ 156 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem4NameEv @ 157 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem4SizeEv @ 158 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem4TypeEv @ 159 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem5CountEv @ 160 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem5OrderEv @ 161 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem5StateEv @ 162 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem6BottomEv @ 163 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem6HandleEv @ 164 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem7ChangesEv @ 165 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem7MapAttrEv @ 166 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem7MaxSizeEv @ 167 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem7VersionEv @ 168 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8MapCountEv @ 169 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8MsgCountEv @ 170 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8MsgLimitEv @ 171 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8PriorityEv @ 172 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8StartPosEv @ 173 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem8UniqueIDEv @ 174 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9ChunkTypeEv @ 175 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9CreatorIdEv @ 176 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9ParseMaskEv @ 177 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9ResettingEv @ 178 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9TimerTypeEv @ 179 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9UnitsMaskEv @ 180 NONAME
+	_ZNK26CMemSpyApiKernelObjectItem9WaitCountEv @ 181 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle10FreeMemoryEv @ 182 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle11CycleNumberEv @ 183 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle11MemoryDeltaEv @ 184 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle17PreviousCycleDiffEv @ 185 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle4TimeEv @ 186 NONAME
+	_ZNK29CMemSpyApiMemoryTrackingCycle7CaptionEv @ 187 NONAME
+	_ZNK34TMemSpyDeviceWideOperationProgress11DescriptionEv @ 188 NONAME
+	_ZNK34TMemSpyDeviceWideOperationProgress8ProgressEv @ 189 NONAME
+	_ZNK17CMemSpyApiProcess6IsDeadEv @ 190 NONAME
 
--- a/memspy/MemSpyClient/group/MemSpyClient.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/group/MemSpyClient.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -24,14 +24,17 @@
 VENDORID	VID_DEFAULT
 SMPSAFE
 
-CAPABILITY PowerMgmt SwEvent ReadUserData WriteUserData ReadDeviceData WriteDeviceData
+CAPABILITY PowerMgmt SwEvent ReadUserData WriteUserData ReadDeviceData WriteDeviceData CommDD MultimediaDD DRM TrustedUI ProtServ DiskAdmin NetworkControl AllFiles NetworkServices LocalServices Location SurroundingsDD UserEnvironment
 
 SOURCEPATH ../src
 SOURCE 		memspysession.cpp 
 SOURCE 		memspyapiprocess.cpp 
 SOURCE 		memspyapikernelobject.cpp 
 SOURCE		memspyapiheap.cpp 
-SOURCE 		memspyapikernelobjectitem.cpp memspyapithread.cpp
+SOURCE 		memspyapikernelobjectitem.cpp 
+SOURCE		memspyapithread.cpp 
+SOURCE		memspyapithreadinfoitem.cpp
+SOURCE		memspyapimemorytrackingcycle.cpp
 
 USERINCLUDE ../inc
 
@@ -47,7 +50,6 @@
 LIBRARY			eikcore.lib
 LIBRARY			fbscli.lib 
 LIBRARY 		PlatformEnv.lib
-
 LIBRARY         MemSpyEngine.lib
 
-//EXPORTUNFROZEN
\ No newline at end of file
+//EXPORTUNFROZEN
--- a/memspy/MemSpyClient/group/bld.inf	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -23,12 +23,17 @@
 ../inc/memspyprocessdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspyprocessdata.h)
 ../inc/memspykernelobjectdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspykernelobjectdata.h)
 ../inc/memspyheapdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspyheapdata.h)
+../inc/memspythreaddata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreaddata.h)
+../inc/memspythreadinfoitemdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreadinfoitemdata.h)
+../inc/memspymemorytrackingcycledata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspymemorytrackingcycledata.h)
+
 ../inc/memspyapiprocess.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiprocess.h)
 ../inc/memspyapikernelobject.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapikernelobject.h)
 ../inc/memspyapikernelobjectitem.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapikernelobjectitem.h)
 ../inc/memspyapiheap.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiheap.h)
-../inc/memspythreaddata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreaddata.h)
 ../inc/memspyapithread.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithread.h)
+../inc/memspyapithreadinfoitem.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithreadinfoitem.h)
+../inc/memspyapimemorytrackingcycle.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapimemorytrackingcycle.h)
 
 PRJ_MMPFILES
 MemSpyClient.mmp
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspyapimemorytrackingcycle.h	Thu Jul 22 16:50:07 2010 +0100
@@ -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:
+* 
+*/
+
+#ifndef MEMSPYAPIMEMORYTRACKINGCYCLE_H_
+#define MEMSPYAPIMEMORYTRACKINGCYCLE_H_
+
+#include <e32base.h>
+
+class TMemSpyMemoryTrackingCycleData;
+
+class CMemSpyApiMemoryTrackingCycle
+	{
+public: // API
+	IMPORT_C TInt CycleNumber() const;
+	IMPORT_C const TTime& Time() const;
+	IMPORT_C const TDesC& Caption() const;
+	IMPORT_C const TInt64& FreeMemory() const;
+	IMPORT_C TInt64 MemoryDelta() const;
+	IMPORT_C TInt64 PreviousCycleDiff() const;
+	
+public:
+	IMPORT_C ~CMemSpyApiMemoryTrackingCycle();
+	
+	static CMemSpyApiMemoryTrackingCycle* NewL(const TMemSpyMemoryTrackingCycleData& aData);
+
+	static CMemSpyApiMemoryTrackingCycle* NewLC(const TMemSpyMemoryTrackingCycleData& aData);
+	
+private:
+	CMemSpyApiMemoryTrackingCycle();
+	
+	void ConstructL(const TMemSpyMemoryTrackingCycleData& aData);
+	
+private:
+	TMemSpyMemoryTrackingCycleData* iData;
+	
+	};
+
+#endif /* MEMSPYAPIMEMORYTRACKINGCYCLE_H_ */
--- a/memspy/MemSpyClient/inc/memspyapiprocess.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/inc/memspyapiprocess.h	Thu Jul 22 16:50:07 2010 +0100
@@ -45,6 +45,15 @@
 	
 	IMPORT_C TInt ThreadCount() const;
 	
+	IMPORT_C TUint32 SID() const;
+	
+	IMPORT_C TUint32 VID() const;
+	
+	IMPORT_C TProcessPriority Priority() const;
+	
+	IMPORT_C TBool IsDead() const;
+	
+	
 private:
 	CMemSpyApiProcess();
 	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspyapithreadinfoitem.h	Thu Jul 22 16:50:07 2010 +0100
@@ -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:
+* Contains the declaration of  CMemSpyProcess class 
+*/
+
+#ifndef MEMSPYAPITHREADINFOITEM_H
+#define MEMSPYAPITHREADINFOITEM_H
+
+// System includes
+#include <e32base.h>
+
+class TMemSpyThreadInfoItemData;
+
+NONSHARABLE_CLASS( CMemSpyApiThreadInfoItem ) 
+	{
+public:
+	IMPORT_C ~CMemSpyApiThreadInfoItem();
+	
+	static CMemSpyApiThreadInfoItem* NewL(const TMemSpyThreadInfoItemData& aData);
+
+	static CMemSpyApiThreadInfoItem* NewLC(const TMemSpyThreadInfoItemData& aData);
+	
+public:		
+	IMPORT_C const TDesC& Caption() const;	
+	
+	IMPORT_C const TDesC& Value() const;	
+	
+private:
+	CMemSpyApiThreadInfoItem();
+	
+	void ConstructL(const TMemSpyThreadInfoItemData& aData);
+		
+private:
+	TMemSpyThreadInfoItemData *iInfoItem;
+};
+
+	
+#endif // MEMSPYAPITHREADINFOITEM_H
--- a/memspy/MemSpyClient/inc/memspyheapdata.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/inc/memspyheapdata.h	Thu Jul 22 16:50:07 2010 +0100
@@ -39,7 +39,7 @@
 public:
 	TBuf<KBuf> iType;
 	TUint iSize;
-	TUint8 iBaseAddress;
+	TLinAddr iBaseAddress;
 	TBool iShared;
 	TUint iChunkSize;
 	TUint iAllocationsCount;
--- a/memspy/MemSpyClient/inc/memspykernelobjectdata.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/inc/memspykernelobjectdata.h	Thu Jul 22 16:50:07 2010 +0100
@@ -35,7 +35,7 @@
 	
 public:    
     TMemSpyDriverContainerType iType;
-    TBuf<KBufSize> iName;
+    TFullName iName;
     TInt iCount;
     TInt64 iSize;
 	};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspymemorytrackingcycledata.h	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,32 @@
+/*
+* 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 MEMSPYMEMORYTRACKINGCYCLEDATA_H_
+#define MEMSPYMEMORYTRACKINGCYCLEDATA_H_
+
+struct TMemSpyMemoryTrackingCycleData
+	{
+	TInt iCycleNumber;
+	TTime iTime;
+	TFullName iCaption;
+	TInt64 iFreeMemory;
+	TInt64 iMemoryDelta;
+	TInt64 iPreviousCycleDiff;
+	};
+
+#endif /* MEMSPYMEMORYTRACKINGCYCLEDATA_H_ */
--- a/memspy/MemSpyClient/inc/memspyprocessdata.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/inc/memspyprocessdata.h	Thu Jul 22 16:50:07 2010 +0100
@@ -37,8 +37,10 @@
     TExitCategoryName iExitCategory;
     TInt iExitReason;
     TExitType iExitType;
-    TInt iThreadCount; 
-    TMemSpyDriverProcessInfo iInfo;
+    TInt iThreadCount;
+    TUint32 iSID;
+    TUint32 iVID;
+    TBool iIsDead;
 	};
 
 #endif // MEMSPYPROCESSDATA_H
--- a/memspy/MemSpyClient/inc/memspysession.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/inc/memspysession.h	Thu Jul 22 16:50:07 2010 +0100
@@ -25,63 +25,30 @@
 #include <u32std.h>
 
 //user includes
-#include <memspy/engine/memspyprocessdata.h> //for Processes
 #include <memspy/api/memspyapiprocess.h>
-#include <memspy/engine/memspythreaddata.h> //for Threads
+
 #include <memspy/api/memspyapithread.h>
-#include <memspy/engine/memspykernelobjectdata.h> //for KernelObjects
+#include <memspy/api/memspyapithreadinfoitem.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
+#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
+#include <memspy/engine/memspydevicewideoperations.h>
+
 #include <memspy/api/memspyapikernelobject.h>
+
 #include <memspy/api/memspyapikernelobjectitem.h> //for KernelObjectItems
-#include <memspy/engine/memspyheapdata.h> //for Heap
+
 #include <memspy/api/memspyapiheap.h>
 
+#include <memspy/api/memspyapimemorytrackingcycle.h>
+
+#include <memspyengineclientinterface.h>
+#include <memspy/engine/memspyengineoutputsinktype.h>
+
+#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
+
 // Constants
 const TInt KMemSpyVersion           = 2;
 
-// Literal constants 
-_LIT( KMemSpyServer2, "MemSpyServer.exe" );
-
-
-//
-enum TMemSpyOperations
-    {
-	//Output operations
-	
-//	EGetSinkType,
-//	EOutputToDebug,
-//	EOutputToFile,
-//	EOutputKernelObjects,
-//	ESetServerTimeOutStatus,
-//	EOutputProcessInfo,
-	
-	//Processes operations
-	
-	EGetProcessCount,
-	EGetProcesses,
-	EGetThreadCount,
-	EGetThreads,
-	ESetThreadPriority,
-	EProcessSystemPermanentOrCritical,
-	EEndProcess,
-	ESwitchToProcess,
-//	EOpenCloseCurrentProcess
-	
-	//Threads operations
-	EThreadSystemPermanentOrCritical,	
-	EEndThread,
-	ESwitchToThread,
-	
-	//Kernel Objects operations
-	EGetKernelObjectTypeCount,
-	EGetKernelObjects,
-	EGetKernelObjectItemsCount,
-	EGetKernelObjectItems,
-	//EOutputKernelObjects
-	
-	//Heap operations
-	EGetHeap
-    };
-
 enum TSortType
 	{
 	ESortProcById,
@@ -92,12 +59,25 @@
 	ESortProcByStackUsage
 	};
 
-enum TEndType
+enum TMemSpyOutputType
+    {
+    EOutputTypeDebug = 0,
+    EOutputTypeFile
+    };
+
+class TMemSpyDeviceWideOperationProgress 
 	{
-	ETerminate,
-	EKill,
-	EPanic
-};
+public:
+	IMPORT_C TInt Progress() const;
+	IMPORT_C const TDesC& Description() const;
+	
+private:
+	TPckgBuf<TInt> iProgress;
+	TFullName iDescription;
+	
+friend class RMemSpySession;
+	};
+
 
 NONSHARABLE_CLASS( RMemSpySession ) : public RSessionBase
     {
@@ -106,29 +86,118 @@
     IMPORT_C TInt Connect();
     
 public:	//API
-    //Output operations
-    //inline TMemSpySinkType GetSinkType();    
-    //inline void OutputToDebug();
-    //inline void OutputToFile();    
-    //inline void OutputKernelObjects();    
-    //inline void SetServerTimeOutStatus( TUint32 aValue, TBool aEnabled );
-    //inline void OutputProcessInfo( TMemSpyProcess aProcess );
+    //Thread speciifc operations
+    IMPORT_C void OutputKernelHeapDataL(); //EMemSpyClientServerOpHeapData
+    
+    IMPORT_C void OutputKernelHeapData(TRequestStatus& aStatus); //EMemSpyClientServerOpHeapData
+    
+    IMPORT_C void OutputThreadHeapDataL(TThreadId aThreadId); //EMemSpyClientServerOpHeapData
+    
+    IMPORT_C void OutputThreadHeapDataL(const TDesC& aThreadName); //EMemSpyClientServerOpHeapData
+    
+    IMPORT_C void OutputThreadCellListL(TThreadId aThreadId);//EMemSpyClientServerOpHeapCellListing    
+    
+    IMPORT_C void OutputHeapInfoUserL(TThreadId aThreadId);	//EMemSpyClientServerOpHeapInfo
+    
+    IMPORT_C void SwitchOutputSinkL( TMemSpySinkType aType); //EMemSpyClientServerOpSwitchOutputSinkFile / EMemSpyClientServerOpSwitchOutputSinkTrace
+    
+    IMPORT_C void SwitchOutputToTraceL(); // EMemSpyClientServerOpSwitchOutputSinkTrace
+    
+    IMPORT_C void SwitchOutputToFileL(const TDesC& aRootFolder); // EMemSpyClientServerOpSwitchOutputSinkFile
+    
+    IMPORT_C void OutputStackInfoL(TThreadId aThreadId); //EMemSpyClientServerOpStackInfo
+    
+    IMPORT_C void OutputStackDataL(TThreadId aThreadId, TMemSpyDriverDomainType aType ); //EMemSpyClientServerOpStackDataUser / EMemSpyClientServerOpStackDataKernel    
+    
+    IMPORT_C void OutputThreadInfoHandlesL(TThreadId aThreadId); //EMemSpyClientServerOpOutputInfoHandles
+    
+    IMPORT_C void OutputAOListL(TThreadId aId, TMemSpyThreadInfoItemType aType);	//EMemSpyClientServerOpOutputAOList    
+    
+    IMPORT_C void OutputKernelObjectsL();// EMemSpyClientServerOpEnumerateKernelContainerAll
+    
+    IMPORT_C void OutputCompactStackInfoL();// EMemSpyClientServerOpStackInfoCompact
+    
+    IMPORT_C void OutputCompactHeapInfoL();// EMemSpyClientServerOpHeapInfoCompact
     
-    //Processes operations    
-    /**
-     * 
-     */
-    IMPORT_C void GetProcessesL(RArray<CMemSpyApiProcess*> &aProcesses, TSortType aSortType = ESortProcById);        
+    // Device Wide Operations
+    // Synchronous operations - for CLI
+    IMPORT_C void OutputHeapData();
+    
+    // Asynchronous operations
+    IMPORT_C void OutputPhoneInfo(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputDetailedPhoneInfo(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputHeapInfo(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputCompactHeapInfo(TRequestStatus &aStatus);
+    
+    IMPORT_C void OutputHeapCellListing(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputHeapData(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputStackInfo(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputCompactStackInfo(TRequestStatus &aStatus);
+    
+    IMPORT_C void OutputUserStackData(TRequestStatus& aStatus);
+    
+    IMPORT_C void OutputKernelStackData(TRequestStatus& aStatus);
+    
+    IMPORT_C void NotifyDeviceWideOperationProgress(TMemSpyDeviceWideOperationProgress &aProgress, TRequestStatus &aStatus);
+    
+    IMPORT_C void CancelDeviceWideOperationL();
+    
+    // Synchronous operations for MemSpyLauncher
+    IMPORT_C void OutputPhoneInfo();
+    
+    // "Ui" operations 
+    
+    IMPORT_C void GetProcessesL(RArray<CMemSpyApiProcess*> &aProcesses, TSortType aSortType = ESortProcById);
+    
+    IMPORT_C TProcessId GetProcessIdByNameL(const TDesC& aProcessName);
     
     IMPORT_C void GetThreadsL(TProcessId aProcessId, RArray<CMemSpyApiThread*> &aThreads, TSortType aSortType = ESortProcById);
+    
     IMPORT_C TInt ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue ); //aValue -> return value
     
     IMPORT_C void SetThreadPriorityL(TThreadId aId, TInt aPriority);
-    IMPORT_C TInt EndProcess( TProcessId aId, TEndType aType );
+    
+    IMPORT_C TInt EndProcess( TProcessId aId, TMemSpyEndType aType );
     
     IMPORT_C TInt SwitchToProcess( TProcessId aId, TBool aBrought  );
     
-    //inline void OpenCloseCurrentProcess( TProcessId aId, TBool aOpen );
+    //SWMT operations
+    
+    IMPORT_C void GetMemoryTrackingCyclesL(RArray<CMemSpyApiMemoryTrackingCycle*>& aCycles);
+    
+    IMPORT_C void SetSwmtConfig( TMemSpyEngineHelperSysMemTrackerConfig aConfig );    
+    
+    IMPORT_C void SetSwmtAutoStartProcessList( CArrayFixFlat<TUid>* aList );
+    
+    IMPORT_C void SetSwmtFilter( const TDesC& aFilter );            
+    
+    IMPORT_C void SetSwmtCategoriesL(TInt aCategories);
+
+    IMPORT_C void SetSwmtHeapDumpsEnabledL(TBool aEnabled);
+    
+    IMPORT_C void SwmtResetTracking();
+    
+    IMPORT_C void GetOutputSink( TMemSpySinkType aType );
+           
+    IMPORT_C TBool IsSwmtRunningL();
+    
+    IMPORT_C void StartSwmtTimerL(TInt aPeriod);
+    
+    IMPORT_C void StartSwmtTimerL(); // for CLI
+    
+    IMPORT_C void SetSwmtTimerIntervalL(TInt aPeriod); //for CLI
+    
+    IMPORT_C void StopSwmtTimerL();
+    
+    IMPORT_C void ForceSwmtUpdateL();
+    
+    IMPORT_C void ForceSwmtUpdate(TRequestStatus& aStatus);
     
     //Threads operations
     /**
@@ -138,27 +207,42 @@
     
     IMPORT_C TInt ThreadSystemPermanentOrCritical( TThreadId aId, TBool aValue );
         
-    IMPORT_C TInt EndThread( TThreadId aId, TEndType aType );
+    IMPORT_C TInt EndThread( TThreadId aId, TMemSpyEndType aType );
     
     IMPORT_C TInt SwitchToThread( TThreadId aId, TBool aBrought );
     
-    //KernelObjects operations    
-    /**
-     * 
-     */
+    IMPORT_C TInt GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType );
+    
+    IMPORT_C TInt GetThreadInfoItems( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType );
+    
+    IMPORT_C void GetThreadInfoItemsL( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType );
+        
+    
+    //KernelObjects operations
+    
+    IMPORT_C void GetKernelObjectsL( RArray<CMemSpyApiKernelObject*> &aKernelObjects );
+    
     IMPORT_C TInt GetKernelObjects( RArray<CMemSpyApiKernelObject*> &aKernelObjects );
     
+    IMPORT_C void GetKernelObjectItemsL( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer );
+    
     IMPORT_C TInt GetKernelObjectItems( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer );
     
-    /**
-     * 
-     */
-    //IMPORT_C TInt GetHeap( RArray<CMemSpyApiHeap*> &aHeap );
-	//IMPORT_C TInt GetHeap( CMemSpyApiHeap* aHeap );
+    IMPORT_C void OutputAllContainerContents();
+    
+    // Heap 
+    
+    IMPORT_C CMemSpyApiHeap* GetHeapL();
+    
 	IMPORT_C CMemSpyApiHeap* GetHeap();
-    
+	
+	IMPORT_C void DumpKernelHeap();	
+	
 private:
-    TInt StartServer();
+    TInt StartServer();       
+    
+    void SetOutputTypeL(TMemSpyOutputType aOutputType);
+    
     };
 
 #endif // MEMSPYSESSION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspythreadinfoitemdata.h	Thu Jul 22 16:50:07 2010 +0100
@@ -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:
+* Contains the declaration of  TMemSpyProcessData class
+*/
+
+#ifndef MEMSPYTHREADINFOITEMDATA_H
+#define MEMSPYTHREADINFOITEMDATA_H
+
+#include <memspy/driver/memspydriverobjectsshared.h>
+
+// TMemSpyProcess data class holds data to be sent to the UI
+class TMemSpyThreadInfoItemData 
+	{	
+public:
+	//constructor & destructor
+	inline TMemSpyThreadInfoItemData()		
+		{
+		}
+	
+public:
+    TBuf<64> iCaption;
+    TBuf<32> iValue;
+	};
+
+#endif // MEMSPYTHREADINFOITEMDATA_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/src/memspyapimemorytrackingcycle.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* 
+*/
+
+#include <memspy/api/memspyapimemorytrackingcycle.h>
+#include <memspy/engine/memspymemorytrackingcycledata.h>
+
+EXPORT_C TInt CMemSpyApiMemoryTrackingCycle::CycleNumber() const
+	{
+	return iData->iCycleNumber;	
+	}
+
+EXPORT_C const TTime& CMemSpyApiMemoryTrackingCycle::Time() const
+	{
+	return iData->iTime;	
+	}
+
+EXPORT_C const TDesC& CMemSpyApiMemoryTrackingCycle::Caption() const
+	{
+	return iData->iCaption;	
+	}
+
+EXPORT_C const TInt64& CMemSpyApiMemoryTrackingCycle::FreeMemory() const
+	{
+	return iData->iFreeMemory;
+	}
+
+EXPORT_C TInt64 CMemSpyApiMemoryTrackingCycle::MemoryDelta() const
+	{
+	return iData->iMemoryDelta;
+	}
+
+EXPORT_C TInt64 CMemSpyApiMemoryTrackingCycle::PreviousCycleDiff() const
+	{
+	return iData->iPreviousCycleDiff;
+	}
+
+EXPORT_C CMemSpyApiMemoryTrackingCycle::~CMemSpyApiMemoryTrackingCycle()
+	{
+	delete iData;
+	}
+
+CMemSpyApiMemoryTrackingCycle* CMemSpyApiMemoryTrackingCycle::NewL(const TMemSpyMemoryTrackingCycleData& aData)
+	{
+	CMemSpyApiMemoryTrackingCycle* self = CMemSpyApiMemoryTrackingCycle::NewLC(aData);
+	CleanupStack::Pop(self);
+	return (self);
+	}
+
+CMemSpyApiMemoryTrackingCycle* CMemSpyApiMemoryTrackingCycle::NewLC(const TMemSpyMemoryTrackingCycleData& aData)
+	{
+	CMemSpyApiMemoryTrackingCycle* self = new (ELeave) CMemSpyApiMemoryTrackingCycle;
+	CleanupStack::PushL(self);
+	self->ConstructL(aData);
+	return self;
+	}
+
+CMemSpyApiMemoryTrackingCycle::CMemSpyApiMemoryTrackingCycle()
+	{
+	}
+
+void CMemSpyApiMemoryTrackingCycle::ConstructL(const TMemSpyMemoryTrackingCycleData& aData)
+	{
+	iData = new (ELeave) TMemSpyMemoryTrackingCycleData(aData);
+	}
--- a/memspy/MemSpyClient/src/memspyapiprocess.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/src/memspyapiprocess.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -57,6 +57,25 @@
 	return iProcessData->iThreadCount;
 	}
 
+EXPORT_C TUint32 CMemSpyApiProcess::SID() const
+	{
+	return iProcessData->iSID;
+	}
+
+EXPORT_C TUint32 CMemSpyApiProcess::VID() const
+	{
+	return iProcessData->iSID;
+	}
+
+EXPORT_C TProcessPriority CMemSpyApiProcess::Priority() const
+	{
+	return iProcessData->iPriority;
+	}
+
+EXPORT_C TBool CMemSpyApiProcess::IsDead() const
+    {
+    return iProcessData->iIsDead;
+    }
 
 CMemSpyApiProcess::CMemSpyApiProcess() : iProcessData(0)
 	{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/src/memspyapithreadinfoitem.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -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 <memspy/api/memspyapithreadinfoitem.h>
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
+
+EXPORT_C CMemSpyApiThreadInfoItem::~CMemSpyApiThreadInfoItem()
+	{
+	delete iInfoItem;
+	}
+
+EXPORT_C const TDesC& CMemSpyApiThreadInfoItem::Caption() const
+	{
+	return iInfoItem->iCaption;
+	}
+
+EXPORT_C const TDesC& CMemSpyApiThreadInfoItem::Value() const
+	{
+	return iInfoItem->iValue;
+	}
+
+CMemSpyApiThreadInfoItem::CMemSpyApiThreadInfoItem() : iInfoItem(0)
+	{
+	}
+
+void CMemSpyApiThreadInfoItem::ConstructL(const TMemSpyThreadInfoItemData& aData)
+	{
+	iInfoItem = new (ELeave) TMemSpyThreadInfoItemData(aData);
+	}
+
+CMemSpyApiThreadInfoItem* CMemSpyApiThreadInfoItem::NewL(const TMemSpyThreadInfoItemData& aData)
+	{
+	CMemSpyApiThreadInfoItem* self = CMemSpyApiThreadInfoItem::NewLC(aData);
+	CleanupStack::Pop(self);
+	return (self);
+	}
+
+CMemSpyApiThreadInfoItem* CMemSpyApiThreadInfoItem::NewLC(const TMemSpyThreadInfoItemData& aData)
+	{
+	CMemSpyApiThreadInfoItem* self = new (ELeave) CMemSpyApiThreadInfoItem;
+	CleanupStack::PushL(self);
+	self->ConstructL(aData);
+	return (self);
+	}
+
--- a/memspy/MemSpyClient/src/memspysession.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyClient/src/memspysession.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -17,9 +17,14 @@
 
 
 #include "memspysession.h"
-#include <memspy/api/memspyapiprocess.h>
-#include <memspy/api/memspyapikernelobject.h>
-#include <memspy/api/memspyapikernelobjectitem.h>
+
+#include <memspyengineclientinterface.h>
+// API
+#include <memspy/engine/memspyprocessdata.h>
+#include <memspy/engine/memspythreaddata.h> 
+#include <memspy/engine/memspykernelobjectdata.h>
+#include <memspy/engine/memspyheapdata.h>
+#include <memspy/engine/memspymemorytrackingcycledata.h>
 //KernelObjects
 #include <memspy/driver/memspydriverenumerationsshared.h>
 // IMPLEMENTATION
@@ -35,7 +40,7 @@
 	
 	for (TInt i=0; i<2; i++) // Two retries max
 		{
-		TInt error = CreateSession(KMemSpyServer2, TVersion(KMemSpyVersion, 0, 0));
+		TInt error = CreateSession(KMemSpyServerName, TVersion(KMemSpyVersion, 0, 0));
 		
 		if (error != KErrNotFound && error != KErrServerTerminated)
 			return error;
@@ -54,7 +59,7 @@
 	RProcess server;
 	_LIT(KCommand, "start");
 	const TUid KServerUid3 = {0xE5883BC2};
-	TInt error = server.Create(KMemSpyServer2, KCommand);//, KServerUid3);
+	TInt error = server.Create(KMemSpyServerName, KCommand);//, KServerUid3);
 	
 	if (error != KErrNone)
 		return error;
@@ -92,97 +97,16 @@
 	return KErrNone;
 	}
 
-//inline void RMemSpySession::Close()
-//    {
-//    RSessionBase::Close();
-//    }
-//
-//inline TMemSpySinkType RMemSpySession::GetSinkType()
-//	{
-//	TPckgBuf<TMemSpySinkType> OutBuf;
-//	TIpcArgs args( &OutBuf );
-//	SendReceive( EGetSinkType, args );
-//	return OutBuf();
-//	}
-//
-//inline void RMemSpySession::OutputKernelObjects()
-//	{
-//	SendReceive( EOutputKernelObjects );
-//	}
-//
-//inline void RMemSpySession::OutputToDebug()
-//	{
-//	SendReceive( EOutputToDebug );
-//	}
-//
-//inline void RMemSpySession::OutputToFile()
-//	{
-//	SendReceive( EOutputToFile );
-//	}
-//
-//inline void RMemSpySession::SetServerTimeOutStatus( TUint32 aValue, TBool aEnabled )
-//	{
-//	TPckgBuf<TUint32> In1(aValue);
-//	TPckgBuf<TBool> In2(aEnabled);
-//	TIpcArgs args( &In1, &In2 );
-//	SendReceive( ESetServerTimeOutStatus, args );	
-//	}
-
-//inline void RMemSpySession::OutputProcessInfo( TMemSpyProcess aProcess )
-//	{
-//	TProcessId iId = aProcess.iId;
-//	TPckgBuf<TProcessId> In( iId );
-//	TIpcArgs args( &In );
-//	SendReceive( EOutputProcessInfo, args );
-//	}
-
-////Processes operations
-//inline TInt RMemSpySession::ProcessesCount()
-//	{
-//	TPckgBuf<TInt> Out;
-//	TIpcArgs args( &Out );
-//	SendReceive( EProcessesCount, args );
-//	return Out();
-//	}
-//
-//inline TMemSpyProcess RMemSpySession::GetProcessByIndex( TInt aIndex )
-//	{
-//	TPckgBuf<TInt> In( aIndex );
-//	TPckgBuf<TMemSpyProcess> Out;
-//	TIpcArgs args( &In, &Out );
-//	SendReceive( EProcessByIndex, args );
-//	return Out();
-//	}
-//
-//inline TInt RMemSpySession::ProcessIndexById( TProcessId aId )
-//	{
-//	TPckgBuf<TProcessId> In( aId );
-//	TPckgBuf<TInt> Out;
-//	TIpcArgs args( &In, &Out );
-//	SendReceive( EProcessIndexById, args );
-//	return Out();
-//	}
-//
-//inline TBool RMemSpySession::ProcessIsDead( TMemSpyProcess aProcess )
-//	{
-//	TProcessId iId = aProcess.iId;
-//	TPckgBuf<TProcessId> In( iId );
-//	TPckgBuf<TBool> Out;
-//	TIpcArgs args( &In, &Out );
-//	SendReceive( EProcessIsDead, args );
-//	return Out();
-//	}
-
 EXPORT_C void RMemSpySession::GetProcessesL(RArray<CMemSpyApiProcess*> &aProcesses, TSortType aSortType)
 	{
 	TPckgBuf<TInt> count;
-	User::LeaveIfError(SendReceive(EGetProcessCount, TIpcArgs(&count)));
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcessCount, TIpcArgs(&count)));
 	
 	TInt requestedCount = count();
 	HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyProcessData));
 	TPtr8 bufferPtr(buffer->Des());
 	
-	User::LeaveIfError(SendReceive(EGetProcesses, TIpcArgs(&count, &bufferPtr)));
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcesses, TIpcArgs(&count, &bufferPtr)));
 	aProcesses.Reset();
 	
 	TInt receivedCount = Min(count(), requestedCount);
@@ -196,24 +120,33 @@
 	CleanupStack::PopAndDestroy(buffer);
 	}
 
+EXPORT_C TProcessId RMemSpySession::GetProcessIdByNameL(const TDesC& aProcessName)
+	{
+	TPckgBuf<TProcessId> procId;
+	User::LeaveIfError(SendReceive(EMemSpyClienServerOpGetProcessIdByName, 
+			TIpcArgs(&aProcessName, &procId)));
+	
+	return procId();
+	}
+
 EXPORT_C TInt RMemSpySession::ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue )
 	{
 	TPckgBuf<TProcessId> arg1( aId );
 	TPckgBuf<TBool> arg2( aValue );
 	TIpcArgs args( &arg1, &arg2 );
 		
-	TInt error = SendReceive( EProcessSystemPermanentOrCritical, args );
+	TInt error = SendReceive( EMemSpyClientServerOpProcessSystemPermanentOrCritical, args );
 	
 	return error;
 	}
 
-EXPORT_C TInt RMemSpySession::EndProcess( TProcessId aId, TEndType aType )
+EXPORT_C TInt RMemSpySession::EndProcess( TProcessId aId, TMemSpyEndType aType )
 	{
 	TPckgBuf<TProcessId> arg1( aId );
-	TPckgBuf<TEndType> arg2( aType );
+	TPckgBuf<TMemSpyEndType> arg2( aType );
 	TIpcArgs args( &arg1, &arg2 );
 	
-	TInt error = SendReceive( EEndProcess, args );
+	TInt error = SendReceive( EMemSpyClientServerOpEndProcess, args );
 	
 	return error;
 	}
@@ -224,7 +157,7 @@
 	TPckgBuf<TBool> arg2( aBrought );
 	TIpcArgs args( &arg1, &arg2 );
 	
-	TInt error = SendReceive( ESwitchToProcess, args );
+	TInt error = SendReceive( EMemSpyClientServerOpSwitchToProcess, args );
 	
 	return error;	
 	}
@@ -233,13 +166,13 @@
 	{
 	TPckgBuf<TInt> count;
 	TPckgBuf<TProcessId> pid(aProcessId);
-	User::LeaveIfError(SendReceive(EGetThreadCount, TIpcArgs(&count, &pid)));
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreadCount, TIpcArgs(&count, &pid)));
 	
 	TInt requestedCount = count();
 	HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyThreadData));
 	TPtr8 bufferPtr(buffer->Des());
 	
-	User::LeaveIfError(SendReceive(EGetThreads, TIpcArgs(&count, &bufferPtr, &pid)));
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreads, TIpcArgs(&count, &bufferPtr, &pid)));
 	aThreads.Reset();
 	
 	TInt receivedCount = Min(count(), requestedCount);
@@ -258,7 +191,7 @@
 	TPckgBuf<TThreadId> arg1( aId );
 	TPckgBuf<TInt> arg2( aPriority );
 	
-	User::LeaveIfError(SendReceive( ESetThreadPriority, TIpcArgs(&arg1, &arg2)));
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpSetThreadPriority, TIpcArgs(&arg1, &arg2)));
 	}
 
 EXPORT_C TInt RMemSpySession::ThreadSystemPermanentOrCritical( TThreadId aId, TBool aValue )
@@ -267,128 +200,507 @@
 	TPckgBuf<TBool> arg2( aValue );
 	TIpcArgs args( &arg1, &arg2 );
 	
-	TInt error = SendReceive( EThreadSystemPermanentOrCritical, args );
+	TInt error = SendReceive( EMemSpyClientServerOpThreadSystemPermanentOrCritical, args );
 	
 	return error;
 	}
 
-EXPORT_C TInt RMemSpySession::EndThread( TThreadId aId, TEndType aType )
+EXPORT_C TInt RMemSpySession::EndThread( TThreadId aId, TMemSpyEndType aType )
 	{
 	TPckgBuf<TThreadId> arg1( aId );
-	TPckgBuf<TEndType> arg2( aType );
+	TPckgBuf<TMemSpyEndType> arg2( aType );
 	TIpcArgs args( &arg1, &arg2 );
 	
-	TInt error = SendReceive( EEndThread, args );
+	TInt error = SendReceive( EMemSpyClientServerOpEndThread, args );
 	
 	return error;
 	}
 
 EXPORT_C TInt RMemSpySession::SwitchToThread( TThreadId aId, TBool aBrought )
 	{
+	TPckgBuf<TThreadId> arg1( aId );
+	TPckgBuf<TBool> arg2( aBrought );
+	TIpcArgs args( &arg1, &arg2 );
 	
+	TInt error = SendReceive( EMemSpyClientServerOpSwitchToThread, args );
+	
+	return error;	
 	}
-/*
-EXPORT_C TInt RMemSpySession::TerminateThread( TThreadId aId )
+
+EXPORT_C TInt RMemSpySession::GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType )
 	{
-	TPckgBuf<TThreadId> arg( aId );
-	TIpcArgs args( &arg );
+	TPckgBuf<TInt> arg1( aIndex );
+	TPckgBuf<TThreadId> arg2( aId );
+	TPckgBuf<TMemSpyThreadInfoItemType> arg3;
+	TIpcArgs args( &arg1, &arg2, &arg3 );
+		
+	TInt error = SendReceive( EMemSpyClientServerOpGetInfoItemType, args );
 	
-	TInt error = SendReceive( ETerminateThread, args );
+	aType = arg3();
 	
 	return error;
 	}
-*/
 
-//inline void RMemSpySession::SortProcessesBy( TSortType aType )
-//	{
-//	TPckgBuf<TSortType> In( aType );
-//	TIpcArgs args( &In );
-//	SendReceive( ESortProcessesBy, args );
-//	}
+EXPORT_C void RMemSpySession::GetThreadInfoItemsL( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType )
+	{
+	TPckgBuf<TThreadId> id( aId );	
+	TPckgBuf<TMemSpyThreadInfoItemType> type( aType );
+	TPckgBuf<TInt> count;	
+	
+	TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItemsCount, TIpcArgs( &id, &type, &count ) );
+	TInt itemCount = count();
+	
+	if( error == KErrNone )
+		{		
+		if( itemCount == 0 )
+			{
+			aInfoItems.Reset();
+			}
+		else
+			{
+			HBufC8* buffer = HBufC8::NewLC( itemCount * sizeof(TMemSpyThreadInfoItemData) );
+			TPtr8 bufferPtr(buffer->Des());
+			
+			TPckgBuf<TInt> requestedCount( itemCount );
+			
+			TIpcArgs args( &requestedCount, &id, &type, &bufferPtr );
+			TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItems, args );
+			
+			aInfoItems.Reset();
+		
+			for(TInt i=0, offset = 0; i < itemCount; i++, offset+=sizeof(TMemSpyThreadInfoItemData))
+				{
+				TPckgBuf<TMemSpyThreadInfoItemData> data;
+				data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyThreadInfoItemData));
+				aInfoItems.AppendL(CMemSpyApiThreadInfoItem::NewLC(data()));
+				}
+			
+			CleanupStack::Pop(aInfoItems.Count());
+			CleanupStack::PopAndDestroy(buffer);
+			}
+		}
+	
+	User::LeaveIfError(error);
+	}
 
-//inline void RMemSpySession::OpenCloseCurrentProcess( TProcessId aId, TBool  aOpen )
-//	{
-//	TPckgBuf<TProcessId> In1( aId );
-//	TPckgBuf<TBool> In2( aOpen );
-//	TIpcArgs args( &In1, &In2 );
-//	SendReceive( EOpenCloseCurrentProcess, args );
-//	}
+EXPORT_C TInt RMemSpySession::GetThreadInfoItems( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType )
+	{
+	TRAPD(error, GetThreadInfoItemsL(aInfoItems, aId, aType));
+	return error;
+	}
 
 //Kernel Objects specific operations
-EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray<CMemSpyApiKernelObject*> &aKernelObjects )
+EXPORT_C void RMemSpySession::GetKernelObjectsL( RArray<CMemSpyApiKernelObject*> &aKernelObjects )
 	{		
 	TPckgBuf<TInt> count;
-	TInt error = SendReceive( EGetKernelObjectTypeCount, TIpcArgs(&count) );
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectCount, TIpcArgs(&count) ));
+	
+	TInt requestedCount = count();
+	HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyKernelObjectData));
+	TPtr8 bufferPtr(buffer->Des());
+		
+	TIpcArgs args( &count, &bufferPtr );
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjects, args ));
+	
+	aKernelObjects.Reset();
+	
+	for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyKernelObjectData))
+		{
+		TPckgBuf<TMemSpyKernelObjectData> data;
+		data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyKernelObjectData));
+		aKernelObjects.AppendL(CMemSpyApiKernelObject::NewLC(data()));
+		}
 	
-	if( error == KErrNone )
-		{			
-		TInt requestedCount = count();
-		HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyKernelObjectData));
-		TPtr8 bufferPtr(buffer->Des());
-			
-		TPckgBuf<TInt> count(requestedCount);
-		TIpcArgs args( &count, &bufferPtr );
-		TInt error = SendReceive( EGetKernelObjects, args );
-			
-		for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyKernelObjectData))
-			{
-			TPckgBuf<TMemSpyKernelObjectData> data;
-			data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyKernelObjectData));
-			aKernelObjects.AppendL(CMemSpyApiKernelObject::NewL(data()));
-			}
-				
-		CleanupStack::PopAndDestroy(buffer);						
-		}	
-	return KErrNone;		
+	CleanupStack::Pop(aKernelObjects.Count());
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray<CMemSpyApiKernelObject*> &aKernelObjects )
+	{
+	TRAPD(error, GetKernelObjectsL(aKernelObjects));
+	return error;
+	}
+
+EXPORT_C void RMemSpySession::GetKernelObjectItemsL( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer )
+	{
+	TPckgBuf<TInt> count;
+	TPckgBuf<TMemSpyDriverContainerType> type(aForContainer);
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectItemCount, TIpcArgs(&count, &type) ));
+
+	TInt requestedCount = count();
+	HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyDriverHandleInfoGeneric));
+	TPtr8 bufferPtr(buffer->Des());
+	
+	TIpcArgs args( &count, &type, &bufferPtr );
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectItems, args ));
+	
+	aKernelObjectItems.Reset();
+	
+	for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyDriverHandleInfoGeneric))
+		{
+		TPckgBuf<TMemSpyDriverHandleInfoGeneric> data;
+		data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyDriverHandleInfoGeneric));
+		aKernelObjectItems.AppendL( CMemSpyApiKernelObjectItem::NewLC( data() ) );
+		}
+	CleanupStack::Pop(aKernelObjectItems.Count());
+	CleanupStack::PopAndDestroy(buffer);
 	}
 
 EXPORT_C TInt RMemSpySession::GetKernelObjectItems( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer )
 	{
-	TPckgBuf<TInt> count;
-	TPckgBuf<TMemSpyDriverContainerType> type(aForContainer);
-	TInt error = SendReceive( EGetKernelObjectItemsCount, TIpcArgs(&count, &type) );
-		
-	if (error == KErrNone)
-		{
-		TInt requestedCount = count();
-		HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyDriverHandleInfoGeneric));
-		TPtr8 bufferPtr(buffer->Des());
-		
-		TPckgBuf<TInt> count(requestedCount);
-		TIpcArgs args( &count, &type, &bufferPtr );
-		TInt error = SendReceive( EGetKernelObjectItems, args );
-		
-		for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyDriverHandleInfoGeneric))
-			{
-			TPckgBuf<TMemSpyDriverHandleInfoGeneric> data;
-			data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyDriverHandleInfoGeneric));
-			aKernelObjectItems.AppendL( CMemSpyApiKernelObjectItem::NewL( data() ) );
-			}
-						
-		CleanupStack::PopAndDestroy(buffer);				
-		}
-	return KErrNone;
+	TRAPD(error, GetKernelObjectItemsL(aKernelObjectItems, aForContainer));
+	return error;
 	}
 
+EXPORT_C void RMemSpySession::GetMemoryTrackingCyclesL(RArray<CMemSpyApiMemoryTrackingCycle*>& aCycles)
+	{
+	TPckgBuf<TInt> count;
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetMemoryTrackingCycleCount, TIpcArgs(&count) ));
+	
+	TInt requestedCount = count();
+	HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyMemoryTrackingCycleData));
+	TPtr8 bufferPtr(buffer->Des());
+		
+	TIpcArgs args( &count, &bufferPtr );
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetMemoryTrackingCycles, args ));
+	
+	aCycles.Reset();
+	
+	for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyMemoryTrackingCycleData))
+		{
+		TPckgBuf<TMemSpyMemoryTrackingCycleData> data;
+		data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyMemoryTrackingCycleData));
+		aCycles.AppendL(CMemSpyApiMemoryTrackingCycle::NewLC(data()));
+		}
+	
+	CleanupStack::Pop(aCycles.Count());
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+EXPORT_C void RMemSpySession::OutputAllContainerContents()
+	{
+	SendReceive( EMemSpyClientServerOpOutputAllContainerContents );
+	}
+
+
 //Heap specific operations
-EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap()
+
+EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeapL()
 	{
 	CMemSpyApiHeap* aHeap;
-	TInt error = KErrNone;
 	
 	HBufC8* buffer = HBufC8::NewLC( sizeof(TMemSpyHeapData) );
 	TPtr8 bufferPtr(buffer->Des());
 	TIpcArgs args( &bufferPtr );
 	
-	error = SendReceive( EGetHeap, args );
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetHeap, args ));
 	
-	if( error == KErrNone )
-		{
-		TPckgBuf<TMemSpyHeapData> data;
-		data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData));		
-		aHeap = CMemSpyApiHeap::NewL( data() );
-		}
+	TPckgBuf<TMemSpyHeapData> data;
+	data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData));		
+	aHeap = CMemSpyApiHeap::NewL( data() );
+	
 	CleanupStack::PopAndDestroy(buffer);
 		
 	return aHeap;
 	}
+
+EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap()
+	{
+	CMemSpyApiHeap *result = NULL;
+	TRAPD(error, result = GetHeapL());
+	return error == KErrNone ? result : NULL;
+	}
+
+EXPORT_C void RMemSpySession::DumpKernelHeap()
+	{
+	SendReceive( EMemSpyClientServerOpDumpKernelHeap );
+	}
+
+EXPORT_C void RMemSpySession::OutputKernelHeapDataL()
+	{		
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(KMemSpyClientServerThreadIdKernel)));
+	
+	}
+
+EXPORT_C void RMemSpySession::OutputKernelHeapData(TRequestStatus& aStatus)
+	{
+	SendReceive(EMemSpyClientServerOpHeapData,
+		TIpcArgs(KMemSpyClientServerThreadIdKernel),
+		aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputThreadHeapDataL( TThreadId aThreadId)
+	{			
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(aThreadId)));
+	}
+
+EXPORT_C void RMemSpySession::OutputThreadHeapDataL(const TDesC& aThreadName)
+	{	
+	const TIpcArgs args( &aThreadName );
+	        
+	User::LeaveIfError( SendReceive( EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadName, args ));	
+	}
+
+EXPORT_C void RMemSpySession::OutputThreadCellListL(TThreadId aThreadId)
+	{	
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(aThreadId)));
+	}
+
+EXPORT_C void RMemSpySession::OutputHeapInfoUserL(TThreadId aThreadId)
+	{
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpHeapInfo | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(aThreadId)));
+	}
+
+EXPORT_C void RMemSpySession::SwitchOutputSinkL( TMemSpySinkType aType )
+	{
+	TInt op;
+	if( aType == ESinkTypeFile )
+		op = EMemSpyClientServerOpSwitchOutputSinkFile;
+	else
+		op = EMemSpyClientServerOpSwitchOutputSinkTrace;
+			
+	User::LeaveIfError(SendReceive( op ));
+	}
+
+EXPORT_C void RMemSpySession::SwitchOutputToTraceL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSwitchOutputSinkTrace));
+	}
+    
+EXPORT_C void RMemSpySession::SwitchOutputToFileL(const TDesC& aRootFolder)
+	{
+	TIpcArgs args;
+	if (aRootFolder.Length())
+		{
+		args.Set(0, &aRootFolder);
+		}
+	
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSwitchOutputSinkFile, args));
+	}
+
+EXPORT_C void RMemSpySession::OutputStackInfoL(TThreadId aThreadId)
+	{
+	User::LeaveIfError(SendReceive( EMemSpyClientServerOpStackInfo | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(aThreadId)));
+	}
+
+EXPORT_C void RMemSpySession::OutputStackDataL(TThreadId aThreadId, TMemSpyDriverDomainType aType )
+	{
+	TInt op;
+	if( aType == EMemSpyDriverDomainUser )
+		op = EMemSpyClientServerOpStackDataUser;
+	else
+		op = EMemSpyClientServerOpStackDataKernel;
+	
+	User::LeaveIfError(SendReceive( op | KMemSpyOpFlagsIncludesThreadId,
+			TIpcArgs(aThreadId, aType)));
+		
+	}
+
+EXPORT_C void RMemSpySession::OutputThreadInfoHandlesL(TThreadId aThreadId)
+	{
+	TPckgBuf<TThreadId> id(aThreadId);
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpOutputInfoHandles, TIpcArgs( &id )));	
+	}
+
+EXPORT_C void RMemSpySession::OutputAOListL(TThreadId aId, TMemSpyThreadInfoItemType aType)
+	{
+	TPckgBuf<TThreadId> id(aId);
+	TPckgBuf<TMemSpyThreadInfoItemType> type(aType);
+	
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpOutputAOList, TIpcArgs( &id, &type )));
+	}
+
+EXPORT_C void RMemSpySession::OutputKernelObjectsL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpEnumerateKernelContainerAll));
+	}
+
+EXPORT_C void RMemSpySession::OutputCompactStackInfoL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpStackInfoCompact)); 
+	}
+
+EXPORT_C void RMemSpySession::OutputCompactHeapInfoL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapInfoCompact)); 
+	}
+// Asynchronous operations
+EXPORT_C void RMemSpySession::OutputPhoneInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpSummaryInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputDetailedPhoneInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpSummaryInfoDetailed | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputHeapInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpHeapInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputCompactHeapInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpHeapInfoCompact | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputHeapCellListing(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputHeapData(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+// synchronous version of the operation - for CLI
+EXPORT_C void RMemSpySession::OutputHeapData()
+	{
+	SendReceive(EMemSpyClientServerOpHeapData);
+	}
+
+EXPORT_C void RMemSpySession::OutputStackInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpStackInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputCompactStackInfo(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpStackInfoCompact | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputUserStackData(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpStackDataUser | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+EXPORT_C void RMemSpySession::OutputKernelStackData(TRequestStatus& aStatus)
+	{	
+	SendReceive(EMemSpyClientServerOpStackDataKernel | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus);
+	}
+
+// Synchronous operations
+EXPORT_C void RMemSpySession::OutputPhoneInfo()
+	{	
+	SendReceive( EMemSpyClientServerOpSummaryInfo , TIpcArgs() );
+	}
+
+EXPORT_C void RMemSpySession::SetSwmtConfig( TMemSpyEngineHelperSysMemTrackerConfig aConfig )
+	{
+	TPckgBuf<TMemSpyEngineHelperSysMemTrackerConfig> config(aConfig);
+	TIpcArgs args( &config );
+	
+	SendReceive( EMemSpyClientServerOpSetSwmtConfig, args) ;
+	}
+
+EXPORT_C void RMemSpySession::SetSwmtAutoStartProcessList( CArrayFixFlat<TUid>* aList )
+	{
+	TInt count = aList->Count();
+	TIpcArgs args( &aList, &count );
+	
+	SendReceive( EMemSpyClientServerOpSetSwmtAutoStartProcessList, args );
+	}
+
+EXPORT_C void RMemSpySession::SwmtResetTracking()
+	{
+	SendReceive( EMemSpyClientServerOpSystemWideMemoryTrackingReset );
+	}
+
+EXPORT_C void RMemSpySession::GetOutputSink( TMemSpySinkType aType )
+	{
+	TPckgBuf<TMemSpySinkType> type( aType );
+	TIpcArgs args( &type );
+	
+	SendReceive( EMemSpyClientServerOpGetOutputSink, args );
+	}
+
+EXPORT_C void RMemSpySession::NotifyDeviceWideOperationProgress(TMemSpyDeviceWideOperationProgress &aProgress, TRequestStatus &aStatus)
+	{
+	SendReceive(EMemSpyClientServerOpNotifyDeviceWideOperationProgress | KMemSpyOpFlagsAsyncOperation,
+			TIpcArgs(&aProgress.iProgress, &aProgress.iDescription), 
+			aStatus);
+	}
+
+EXPORT_C void RMemSpySession::CancelDeviceWideOperationL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpCancelDeviceWideOperation));
+	}
+
+// SWMT operations
+EXPORT_C void RMemSpySession::SetSwmtCategoriesL(TInt aCategories)
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet,
+			TIpcArgs(aCategories)));
+	}
+
+EXPORT_C void RMemSpySession::SetSwmtHeapDumpsEnabledL(TBool aEnabled)
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet,
+			TIpcArgs(aEnabled)));
+	}
+
+EXPORT_C TBool RMemSpySession::IsSwmtRunningL()
+	{
+	TPckgBuf<TBool> ret;
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpIsSwmtRunning, TIpcArgs(&ret)));
+	
+	return ret();
+	}
+
+EXPORT_C void RMemSpySession::StartSwmtTimerL(TInt aPeriod)
+	{
+	SetSwmtTimerIntervalL(aPeriod);
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart));
+	}
+
+EXPORT_C void RMemSpySession::StartSwmtTimerL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart));
+	}
+
+EXPORT_C void RMemSpySession::SetSwmtTimerIntervalL(TInt aPeriod)
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet,
+			TIpcArgs(aPeriod)));
+	}
+
+EXPORT_C void RMemSpySession::StopSwmtTimerL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop));
+	}
+
+
+EXPORT_C void RMemSpySession::ForceSwmtUpdateL()
+	{
+	User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate));
+	}
+
+EXPORT_C void RMemSpySession::ForceSwmtUpdate(TRequestStatus& aStatus)
+	{
+	SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate, 
+			TIpcArgs(),
+			aStatus);
+	}
+
+EXPORT_C void RMemSpySession::SetSwmtFilter( const TDesC& aFilter )
+	{	
+	TIpcArgs args( &aFilter );
+	User::LeaveIfError( SendReceive( EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet, args ) );
+	}
+
+EXPORT_C TInt TMemSpyDeviceWideOperationProgress::Progress() const 
+	{
+	return iProgress();
+	}
+
+EXPORT_C const TDesC& TMemSpyDeviceWideOperationProgress::Description() const
+	{
+	return iDescription;
+	}
--- a/memspy/MemSpyServer/Include/MemSpyServer.h	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-* MemSpyServer headder file to declare MemSpyServer class
-*
-*/
-
-#ifndef MEMSPYSERVER_H
-#define MEMSPYSERVER_H
-
-// System includes
-#include <e32base.h>
-
-#include <flogger.h>
-
-// User includes
-#include <memspyengineclientinterface.h>
-
-// Classes referenced
-class CMemSpyEngine;
-
-// Literal constants 
-//_LIT( KMemSpyServer2, "MemSpyServer.exe" );
-
-// MemSpyServer class declaration
-NONSHARABLE_CLASS( CMemSpyServer ) : public CServer2
-    {
-    public:
-        static CMemSpyServer* NewL( CMemSpyEngine& aEngine );
-        static CMemSpyServer* NewLC( CMemSpyEngine& aEngine );
-        ~CMemSpyServer();
-
-    private:
-        CMemSpyServer( CMemSpyEngine& aEngine );
-    	void ConstructL();
-
-    protected: // From CServer2
-    	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
-
-    private:
-        CMemSpyEngine& iEngine;
-        
-        RFileLogger iLog;
-    };
-
-#endif
--- a/memspy/MemSpyServer/Include/MemSpyServerSession.h	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-* MemSpyServer headder file to declare MemSpyServer class
-*
-*/
-
-#ifndef MEMSPYSERVERSESSION_H
-#define MEMSPYSERVERSESSION_H
-
-// System includes
-#include <e32base.h>
-#include <BADESCA.H>
-
-// User includes
-#include <memspyengineclientinterface.h>
-#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
-
-    // Classes referenced
-class CMemSpyEngine;
-
-
-NONSHARABLE_CLASS( CMemSpyServerSession ) : public CSession2
-	{
-public:
-	static CMemSpyServerSession* NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage );
-	~CMemSpyServerSession();
-
-private:
-	CMemSpyServerSession( CMemSpyEngine& aEngine );
-	void ConstructL( const RMessage2& aMessage );
-
-private: // From CSession2
-	void ServiceL( const RMessage2& aMessage );
-
-private: // Internal methods
-    void DoServiceL( const RMessage2& aMessage );
-    static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName );
-    void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId );
-    void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName );
-    void HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage );
-    
-private:
-    CMemSpyEngine& iEngine;
-    HBufC* iClientThreadName;
-    TUint32 iClientThreadId;
-    };
-
-#endif
--- a/memspy/MemSpyServer/Source/MemSpyServer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-* Implementation of the new MemSpyServer
-*/
-
-//user includes
-#include "MemSpyServer.h"
-#include "MemSpyServerSession.h"
-
-// System includes
-#include <e32svr.h>
-
-// User includes
-#include <memspy/engine/memspyengine.h>
-#include <memspy/engine/memspyenginelogger.h>
-//#include <memspyengineclientinterface.h>
-#include <memspy/engine/memspyengineobjectthread.h>
-#include <memspy/engine/memspyengineobjectprocess.h>
-#include <memspy/engine/memspyengineobjectcontainer.h>
-#include <memspy/engine/memspyenginehelperchunk.h>
-#include <memspy/engine/memspyenginehelpercodesegment.h>
-#include <memspy/engine/memspyenginehelperheap.h>
-#include <memspy/engine/memspyenginehelperstack.h>
-#include <memspy/engine/memspyenginehelperthread.h>
-#include <memspy/engine/memspyenginehelperprocess.h>
-#include <memspy/engine/memspyenginehelperfilesystem.h>
-#include <memspy/engine/memspyenginehelperram.h>
-#include <memspy/engine/memspyenginehelpersysmemtracker.h>
-#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
-#include <memspy/engine/memspyenginehelperkernelcontainers.h>
-
-#include <memspysession.h>
-
-// ---------------------------------------------------------
-// CMemSpyServer( CMemSpyEngine& aEngine )
-// ---------------------------------------------------------
-//
-CMemSpyServer::CMemSpyServer( CMemSpyEngine& aEngine )
-:   CServer2( EPriorityNormal ), iEngine( aEngine )
-    {
-    }
-
-// ---------------------------------------------------------
-// ~CMemSpyServer()
-// ---------------------------------------------------------
-//
-CMemSpyServer::~CMemSpyServer()
-    {
-	iLog.CloseLog();
-	iLog.Close();
-    }
-
-// ---------------------------------------------------------
-// ConstructL()
-// ---------------------------------------------------------
-//
-void CMemSpyServer::ConstructL()
-    {
-    StartL( KMemSpyServer2 );
-	//TInt error = Start( KMemSpyServerName );
-    RDebug::Printf( "[MemSpy] CMemSpyServer::ConstructL() - server started" );
-    
-    iLog.Connect();
-    iLog.CreateLog(_L("memspy"), _L("server.txt"), EFileLoggingModeAppend);
-    iLog.Write(_L("[MemSpy] CMemSpyServer::ConstructL() - server started"));
-    iLog.Write(_L("[MemSpy] CMemSpyServer::ConstructL() - server name: "));
-    iLog.Write(KMemSpyServer2);
-    }
-
-// ---------------------------------------------------------
-// NewL( CMemSpyEngine& aEngine )
-// Two phased constructor
-// ---------------------------------------------------------
-//
-CMemSpyServer* CMemSpyServer::NewL( CMemSpyEngine& aEngine )
-    {
-	CMemSpyServer* self = CMemSpyServer::NewLC(aEngine);
-	CleanupStack::Pop(self);
-	return (self);
-    }
-
-// ---------------------------------------------------------
-// NewLC( CMemSpyEngine& aEngine )
-// Two phased constructor
-// ---------------------------------------------------------
-//
-CMemSpyServer* CMemSpyServer::NewLC( CMemSpyEngine& aEngine )
-    {
-    CMemSpyServer* self = new(ELeave) CMemSpyServer( aEngine );
-    CleanupStack::PushL( self );
-    self->ConstructL();
-    return self;
-    }
-
-// ---------------------------------------------------------
-// NewSessionL( const TVersion& aVersion, const RMessage2& aMessage )
-// Creates new client server session
-// ---------------------------------------------------------
-//
-CSession2* CMemSpyServer::NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) const
-    {
-	if  ( aVersion.iMajor != KMemSpyClientServerVersion )
-        {
-        RDebug::Printf( "[MemSpy] CMemSpyServerSession::NewSessionL() - BAD VERSION" );
-        User::Leave( KErrNotSupported );
-        }
-    //
-    CMemSpyServerSession* session = CMemSpyServerSession::NewL( iEngine, aMessage );
-	return session;
-    }
-
-// END OF FILE
--- a/memspy/MemSpyServer/Source/MemSpyServerMain.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyServer/Source/MemSpyServerMain.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -24,7 +24,7 @@
 #include <memspy/engine/memspyengine.h>
 
 // User includes
-#include "MemSpyServer.h"
+//#include "MemSpyServer.h"
 
 static void RunServerL()
     {
@@ -42,9 +42,6 @@
     CMemSpyEngine* engine = CMemSpyEngine::NewL(fsSession);
     CleanupStack::PushL(engine);
     
-    // MemSpyServer initialization
-    CMemSpyServer::NewLC(*engine);
-
     // Play nicely with external processes
     RProcess::Rendezvous( KErrNone );       
 
@@ -52,7 +49,7 @@
     CActiveScheduler::Start();
     
     // Tidy up
-    CleanupStack::PopAndDestroy( 4, scheduler );
+    CleanupStack::PopAndDestroy( 3, scheduler );
     }
 
 TInt E32Main()
--- a/memspy/MemSpyServer/Source/MemSpyServerSession.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,949 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-* Implementation of the new MemSpyServer
-*/
-
-// System includes
-#include <e32svr.h>
-#include <e32cmn.h>
-#include <e32base.h>
-#include <w32std.h>
-//#include <apgtask.h>
-//#include <apgwgnam.h>
-
-//user includes
-#include "MemSpyServerSession.h"
-
-// User includes
-#include <memspy/engine/memspyengine.h>
-#include <memspy/engine/memspyenginelogger.h>
-#include <memspyengineclientinterface.h>
-#include <memspy/engine/memspyengineobjectthread.h>
-#include <memspy/engine/memspyengineobjectprocess.h>
-#include <memspy/engine/memspyengineobjectcontainer.h>
-#include <memspy/engine/memspyenginehelperchunk.h>
-#include <memspy/engine/memspyenginehelpercodesegment.h>
-#include <memspy/engine/memspyenginehelperheap.h>
-#include <memspy/engine/memspyenginehelperstack.h>
-#include <memspy/engine/memspyenginehelperthread.h>
-#include <memspy/engine/memspyenginehelperprocess.h>
-#include <memspy/engine/memspyenginehelperfilesystem.h>
-#include <memspy/engine/memspyenginehelperram.h>
-#include <memspy/engine/memspyenginehelpersysmemtracker.h>
-#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
-#include <memspy/engine/memspyenginehelperkernelcontainers.h>
-#include <memspy/engine/memspyenginehelperserver.h>
-
-//cigasto
-#include <memspysession.h>
-//#include <memspy/driver/memspydriverclient.h>
-
-// ---------------------------------------------------------
-// CMemSpyServerSession( CMemSpyEngine& aEngine )
-// ---------------------------------------------------------
-//
-CMemSpyServerSession::CMemSpyServerSession( CMemSpyEngine& aEngine )
-:   iEngine( aEngine )
-    {	
-    }
-
-// ---------------------------------------------------------
-// ~CMemSpyServerSession()
-// ---------------------------------------------------------
-//
-CMemSpyServerSession::~CMemSpyServerSession()
-    {
-#ifdef _DEBUG
-    TPtrC pThreadName( KNullDesC );
-    if  ( iClientThreadName )
-        {
-        pThreadName.Set( *iClientThreadName );
-        }
-
-    RDebug::Print( _L("[MemSpy] CMemSpyServerSession::~CMemSpyServerSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
-#endif
-
-    delete iClientThreadName;
-    }
-
-// ---------------------------------------------------------
-// ConstructL( const RMessage2& aMessage )
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::ConstructL( const RMessage2& aMessage )
-    {
-	RThread thread;
-    const TInt error = aMessage.Client( thread );
-    CleanupClosePushL( thread );
-
-    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::ConstructL() - this: 0x%08x - opening client thread - err: %d", this, error ) );
-
-    User::LeaveIfError( error );
-
-    const TFullName threadName( thread.FullName() );
-    iClientThreadName = threadName.AllocL();
-    iClientThreadId = thread.Id();
-
-    CleanupStack::PopAndDestroy( &thread );
-
-    TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
-    }
-
-// ---------------------------------------------------------
-// NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
-// Two-phased constructor
-// ---------------------------------------------------------
-//
-CMemSpyServerSession* CMemSpyServerSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
-    {
-    CMemSpyServerSession* self = new(ELeave) CMemSpyServerSession( aEngine );
-    CleanupStack::PushL( self );
-    self->ConstructL( aMessage );
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// ---------------------------------------------------------
-// ServiceL( const RMessage2& aMessage )
-// Method from which the clients request arrives
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::ServiceL( const RMessage2& aMessage )
-    {
-    TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - START - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );   
-    
-    TRAPD( error, DoServiceL( aMessage ) );
-    if  ( error != KErrNone )
-        {
-        RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
-        }
-    aMessage.Complete( error );
-
-    TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
-	}
-
-// ---------------------------------------------------------
-// DoServiceL( const RMessage2& aMessage )
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::DoServiceL( const RMessage2& aMessage )
-    {
-    TInt error = KErrNone;
-
-    // Check function attributes
-    const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;    
-    const TInt argSpec = aMessage.Function() & KMemSpyOpFlagsInclusionMask;
-    const TBool byThreadId = ( argSpec == KMemSpyOpFlagsIncludesThreadId );
-    const TBool byThreadName = ( argSpec == KMemSpyOpFlagsIncludesThreadName );
-
-    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - START - unmodified function: 0x%08x, opCode: %d [TID: %d, TN: %d]", aMessage.Function(), function, byThreadId, byThreadName ) );   
-    
-    switch (function)
-    	{
-		case EGetProcessCount:
-			{
-			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
-			break;
-			}
-		case EGetProcesses:
-			{
-			CMemSpyEngineObjectContainer& list = iEngine.Container();
-			
-			TPckgBuf<TInt> a0;
-			aMessage.ReadL(0, a0);
-			TInt realCount = Min(a0(), list.Count());
-			
-			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
-				{
-				CMemSpyProcess& process = iEngine.Container().At(i);
-				TMemSpyProcessData data;
-				data.iId = process.Id();
-				data.iName.Copy(process.Name());
-				
-				TPckgBuf<TMemSpyProcessData> buffer(data);
-				aMessage.WriteL(1, buffer, offset);
-				}
-			
-			a0 = list.Count();
-			aMessage.WriteL(0, a0);
-
-			break;
-			}
-		case EProcessSystemPermanentOrCritical:
-			{
-			TBool ret = EFalse;
-			TPckgBuf<TProcessId> id;
-			aMessage.ReadL( 0, id );
-			
-			CMemSpyEngineObjectContainer& container = iEngine.Container();
-			CMemSpyProcess& process = container.ProcessByIdL( id() );
-			
-			process.Open();
-
-			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
-				{
-				ret = ETrue;
-				}
-			TPckgBuf<TBool> retBuf( ret );
-			aMessage.WriteL( 1, retBuf );
-			
-			break;
-			}
-		case EEndProcess:
-			{
-			TPckgBuf<TProcessId> id;
-			aMessage.ReadL( 0, id );
-			TPckgBuf<TEndType> type;
-			aMessage.ReadL( 1, type );
-					
-			CMemSpyEngineObjectContainer& container = iEngine.Container();			
-			CMemSpyProcess& process = container.ProcessByIdL( id() );
-									
-			switch ( type() )
-				{
-				case ETerminate:
-					{
-					process.TerminateL();
-					break;
-					}
-				case EPanic:
-					{
-					process.PanicL();
-					break;
-					}
-				case EKill:
-					{
-					process.KillL();
-					break;
-					}
-				}																
-			break;
-			}
-		case ESwitchToProcess:
-			{/*
-		    TInt wgCount;
-		    RWsSession wsSession;
-		    User::LeaveIfError( wsSession.Connect() );
-		    CleanupClosePushL( wsSession );
-		    User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
-		    RArray<RWsSession::TWindowGroupChainInfo> wgArray;
-		    CleanupClosePushL( wgArray );
-		    User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
-		    TApaTask task( wsSession );
-		    TBool brought( EFalse );
-		    TInt wgId( KErrNotFound );
-		    TThreadId threadId;
-			
-			TPckgBuf<TProcessId> id;
-			aMessage.ReadL( 0, id );
-			CMemSpyEngineObjectContainer& container = iEngine.Container();
-			CMemSpyProcess& process = container.ProcessByIdL( id() );
-			
-			// loop trough threads in a process
-			for ( TInt i = 0; i < process.MdcaCount(); i++ )
-				{
-				TInt wgCountLocal = wgCount;
-			                
-				// loop trough all window groups and see if a thread id matches
-				while( !brought && wgCountLocal-- )
-					{
-					wgId = wgArray[wgCountLocal].iId;
-					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
-					if ( threadId == process.At( i ).Id() )
-						{
-						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
-						task.SetWgId( wgId );
-						if ( !wgName->Hidden() && task.Exists() )
-							{
-							task.BringToForeground();
-							brought = ETrue;                        
-							}
-						CleanupStack::PopAndDestroy( wgName );
-						}
-					}
-				}
-			
-			TPckgBuf<TBool> ret( brought );
-			aMessage.WriteL( 1, ret );
-			
-			break;*/
-			}
-		case EGetThreadCount:
-			{
-			TPckgBuf<TProcessId> pid;
-			aMessage.ReadL(1, pid);
-			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
-			process.Open();
-			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
-			process.Close();
-			break;
-			}
-		case EGetThreads:
-			{
-			TPckgBuf<TProcessId> pid;
-			aMessage.ReadL(2, pid);
-			
-			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
-			list.Open();
-			
-			TPckgBuf<TInt> a0;
-			aMessage.ReadL(0, a0);
-			TInt realCount = Min(a0(), list.Count());
-			
-			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
-				{
-				CMemSpyThread& thread = list.At(i);
-				thread.Open();
-				
-				TMemSpyThreadData data;
-				data.iId = thread.Id();
-				data.iName.Copy(thread.Name());
-				data.iThreadPriority = thread.Priority();
-				
-				TPckgBuf<TMemSpyThreadData> buffer(data);
-				aMessage.WriteL(1, buffer, offset);
-				
-				thread.Close();
-				}
-			
-			a0 = list.Count();
-			aMessage.WriteL(0, a0);
-			
-			list.Close();
-
-			break;
-			}
-		case ESetThreadPriority:
-			{
-			TPckgBuf<TThreadId> tid;
-			TPckgBuf<TInt> priority;
-			aMessage.ReadL(0, tid);
-			aMessage.ReadL(1, priority);
-			
-			CMemSpyProcess* process = NULL;
-			CMemSpyThread* thread = NULL; 
-			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
-			
-			if (thread)
-				{				
-				thread->Open();
-				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));				
-				thread->Close();
-				}					
-			break;
-			}
-		case EThreadSystemPermanentOrCritical:
-			{
-			TBool ret = EFalse;
-			TPckgBuf<TThreadId> id;
-			aMessage.ReadL( 0, id );
-			
-			CMemSpyEngineObjectContainer& container = iEngine.Container();            
-            CMemSpyProcess* process = NULL;
-            CMemSpyThread* thread = NULL; 
-            User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
-            
-            if ( thread )
-            	{				
-				thread->Open();
-				
-				if  ( thread->IsSystemPermanent() || thread->IsSystemCritical() )
-					{			
-					ret = ETrue;					
-					}
-				thread->Close();
-            	}
-            TPckgBuf<TBool> retBuf( ret );
-            aMessage.WriteL( 1, retBuf );
-            				
-			break;
-			}
-		case EEndThread:
-			{
-			TPckgBuf<TThreadId> id;
-			aMessage.ReadL( 0, id );
-			TPckgBuf<TEndType> type;
-			aMessage.ReadL( 1, type );
-			
-			CMemSpyEngineObjectContainer& container = iEngine.Container();
-			CMemSpyProcess* process = NULL;
-			CMemSpyThread* thread = NULL; 
-			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
-			
-			if( thread )
-				{
-				switch ( type() )
-					{
-					case ETerminate:
-						{
-						thread->TerminateL();
-						break;
-						}
-					case EPanic:
-						{
-						thread->PanicL();
-						break;
-						}
-					case EKill:
-						{
-						thread->KillL();
-						break;
-						}
-					}				
-				}			
-			break;
-			}
-		// --- KernelObjects related functions ---
-		case EGetKernelObjectTypeCount:
-			{
-			TInt iCount = EMemSpyDriverContainerTypeChunk - EMemSpyDriverContainerTypeFirst;
-			//TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
-			TPckgBuf<TInt> ret( iCount );
-			aMessage.WriteL(0, ret);			
-			break;
-			}
-		case EGetKernelObjects:
-			{
-			TPckgBuf<TInt> count;
-			aMessage.ReadL(0, count);
-			
-			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
-			CleanupStack::PushL( model );
-			
-			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
-				{
-				TMemSpyKernelObjectData data;								
-												
-				data.iName.Append( model->At(i).Name() );
-				data.iType = model->At(i).Type();
-				data.iCount = model->At(i).Count();											
-				data.iSize = model->At(i).Count() * model->At(i).Count();
-
-				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
-				aMessage.WriteL(1, buffer, offset);
-				}			
-			aMessage.WriteL(0, count);
-			CleanupStack::PopAndDestroy( model );
-			break;
-			}
-		case EGetKernelObjectItemsCount:
-			{
-			TPckgBuf<TMemSpyDriverContainerType> tempType;
-			aMessage.ReadL(1, tempType); //get type of kernel object
-			TMemSpyDriverContainerType type = tempType();
-			
-			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
-			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
-			CleanupStack::PushL( iObjectList );
-			
-			TInt count = iObjectList->Count();
-			TPckgBuf<TInt> ret( count );
-			aMessage.WriteL( 0, ret );
-			
-			CleanupStack::PopAndDestroy( iObjectList );
-			break;
-			}
-		case EGetKernelObjectItems:
-			{
-			TPckgBuf<TInt> count;
-			TPckgBuf<TMemSpyDriverContainerType> tempType;
-			aMessage.ReadL( 0, count ); //get count of items
-			aMessage.ReadL(1, tempType); //get type of kernel object
-			TInt c = count();
-			
-			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
-			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
-			CleanupStack::PushL( iObjectList );
-			
-			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
-				{
-				TMemSpyDriverHandleInfoGeneric data;								
-															
-				data = iObjectList->At( i );
-				
-				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
-				aMessage.WriteL(2, buffer, offset);
-				}			
-			
-			CleanupStack::PopAndDestroy( iObjectList );			
-			break;
-			}
-		// --- Kernel Heap related functions ---
-		case EGetHeap:
-			{
-			TMemSpyHeapInfo heapInfo;			
-			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
-			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
-			
-			TPckgBuf<TMemSpyHeapData> buffer(data);
-			aMessage.WriteL(0, buffer);
-			
-			break;
-			}
-    	}
-//    else if( function == EProcessByIndex )
-//    	{
-//		TMemSpyProcess iProcess;
-//		TInt in;
-//		TPckgBuf<TInt> index( in );
-//		aMessage.ReadL( 0, index );
-//		CMemSpyProcess& process = iEngine.Container().At( index() );
-//		//fill the data structure
-//		iProcess.iId = process.Id(); //process ID
-//		iProcess.iName.Append( process.Name() ); //raw process name
-//		iProcess.iThreadCount = process.Count(); //thread count
-//		iProcess.iPriority = process.Priority();
-//		//			
-//		TPckgBuf<TMemSpyProcess> buf( iProcess );
-//		aMessage.WriteL( 1, buf );
-//		aMessage.Complete( KErrNone );
-//    	}
-//    else if( function == EProcessIndexById )
-//    	{
-//		TProcessId iId;
-//		TPckgBuf<TProcessId> buf( iId );
-//    	aMessage.ReadL( 0, buf );
-//    	TInt index = iEngine.Container().ProcessIndexById( buf() );
-//    	TPckgBuf<TInt> out( index );
-//    	aMessage.WriteL( 1, out );
-//    	aMessage.Complete( KErrNone );
-//    	}
-//    else if( function == EOutputProcessInfo )
-//    	{
-//		TProcessId iId;
-//		TPckgBuf<TProcessId> buf( iId );
-//		aMessage.ReadL( 0, buf );
-//		CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() );
-//		iEngine.HelperProcess().OutputProcessInfoL( process );
-//    	}
-//    else if( function == EProcessIsDead )
-//    	{
-//		TProcessId iId;
-//		TPckgBuf<TProcessId> buf( iId );
-//		aMessage.ReadL( 0, buf );
-//		CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() );
-//		TBool dead = process.IsDead();
-//		TPckgBuf<TBool> out( dead );
-//		aMessage.WriteL( 1, out );
-//		aMessage.Complete( KErrNone );
-//    	}
-//    else if( function == ESortProcessesBy )
-//    	{
-//		TSortType type;
-//		TPckgBuf<TSortType> buf(type);
-//		aMessage.ReadL( 0, buf );
-//		if( buf() == ESortProcById )
-//			{
-//			iEngine.Container().SortById();
-//			}
-//		else if( buf() == ESortProcByName )
-//			{
-//			iEngine.Container().SortByName();
-//			}
-//		else if( buf() == ESortProcByThreadCount )
-//			{
-//			iEngine.Container().SortByThreadCount();
-//			}
-//		else if( buf() == ESortProcByCodeSegs )
-//			{
-//			iEngine.Container().SortByCodeSegs();
-//			}
-//		else if( buf() == ESortProcByHeapUsage )
-//			{
-//			iEngine.Container().SortByHeapUsage();			
-//			}
-//		else if( buf() == ESortProcByStackUsage )
-//			{
-//			iEngine.Container().SortByStackUsage();
-//			}			
-//    	}
-//    else if( function == EOpenCloseCurrentProcess )
-//    	{
-//		TProcessId id;
-//		TBool open;
-//    	TPckgBuf<TProcessId> buf(id);
-//    	TPckgBuf<TBool> buf2(open);
-//    	aMessage.ReadL( 0, buf );
-//    	aMessage.ReadL( 1, buf2 );
-//    	if( buf2() == 1 )
-//    		{
-//			iEngine.Container().ProcessByIdL( buf() ).Open();
-//    		}
-//    	else
-//    		{
-//			iEngine.Container().ProcessByIdL( buf() ).Close();
-//    		}
-//    	}
-    
-//    // Check function is supported and argument combination is valid
-//    error = ValidateFunction( function, byThreadId, byThreadName );
-//    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - validation result: %d", error ) );
-//    
-//    // Process function request
-//    if  ( error == KErrNone )
-//        {
-//        if  ( byThreadId )
-//            {
-//            TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TID] thread-specific..." ) );
-//            
-//            const TThreadId threadId( aMessage.Int0() );
-//            HandleThreadSpecificOpL( function, threadId );
-//            }
-//        else if ( byThreadName )
-//            {
-//            TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TN] thread-specific..." ) );
-//
-//            error = aMessage.GetDesLength( 0 /*slot 0*/ );
-//        
-//            if  ( error > 0 && error <= KMaxFullName )
-//                {
-//                TFullName* threadName = new(ELeave) TFullName();
-//                CleanupStack::PushL( threadName );
-//                aMessage.ReadL( 0, *threadName );
-//                HandleThreadSpecificOpL( function, *threadName );
-//                CleanupStack::PopAndDestroy( threadName );
-//                }
-//            else
-//                {
-//                error = KErrArgument;
-//                }
-//            }
-//        else
-//            {
-//            TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - thread-agnostic..." ) );
-//
-//            HandleThreadAgnosticOpL( function, aMessage );
-//            }
-//        }
-
-    User::LeaveIfError( error );
-
-    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - HELLOOOOOO" ) );
-    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - END" ) );
-    }
-
-// ---------------------------------------------------------
-// ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName )
-// Validates the MemSpy operation types
-// ---------------------------------------------------------
-//
-TInt CMemSpyServerSession::ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName )
-    {
-    TInt err = KErrNotSupported;
-    
-    // Check the operation is within op-code range
-    if  ( aFunction >= EMemSpyClientServerOpMarkerFirst && aFunction < EMemSpyClientServerOpMarkerLast )
-        {
-        // Check the operation doesn't include unnecessary or not supported information
-        const TBool includesThreadIdentifier = ( aIncludesThreadId || aIncludesThreadName );
-        if  ( includesThreadIdentifier && aFunction >= EMemSpyClientServerOpMarkerThreadAgnosticFirst )
-            {
-            // Passing a thread identifier to a thread agnostic operation
-            err = KErrArgument;
-            }
-        else
-            {
-            err = KErrNone;
-            }
-        }
-    //
-    if  ( err != KErrNone )
-        {
-        RDebug::Printf( "[MemSpy] CMemSpyServerSession::ValidateFunction() - function request did not validate - [withId: %d, withName: %d]", aIncludesThreadId, aIncludesThreadName );
-        }
-    //
-    return err;
-    }
-
-// ---------------------------------------------------------
-// HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId )
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId )
-    {
-//    TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadId: %d", aFunction, (TUint) aThreadId ) );
-//
-//    ASSERT( (TUint) aThreadId != 0 );
-//    TInt error = KErrNone;
-//
-//    // Check if its a kernel thread identifier
-//    const TBool isKernel = ( static_cast<TUint32>( aThreadId ) == KMemSpyClientServerThreadIdKernel );
-//
-//    // Treat as thread specific operation
-//    CMemSpyProcess* process = NULL;
-//    CMemSpyThread* thread = NULL;
-//    if  ( !isKernel )
-//        {
-//        error = iEngine.Container().ProcessAndThreadByThreadId( aThreadId, process, thread );
-//        TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - search result: %d, proc: 0x%08x, thread: 0x%08x", error, process, thread ) );
-//        }
-//    else
-//        {
-//        // Kernel is only supported for a couple of operations
-//        if  ( aFunction == EMemSpyClientServerOpHeapInfo || aFunction == EMemSpyClientServerOpHeapData )
-//            {
-//            }
-//        else
-//            {
-//            TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - trying to call unsupported function for kernel thread!" ) );
-//            error = KErrArgument;
-//            }
-//        }
-//
-//    // Must be no error so far and we must have a valid thread & process when performing a non-kernel op
-//    // or then if we are performing a kernel op, we don't need the thread or process.
-//    if  ( error == KErrNone && ( ( thread && process && !isKernel ) || ( isKernel ) ) )
-//        {
-//#ifdef _DEBUG
-//        if  ( thread )
-//            {
-//            HBufC* threadName = thread->FullName().AllocLC();
-//            _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: %S" );
-//            RDebug::Print( KTrace2, threadName );
-//            CleanupStack::PopAndDestroy( threadName );
-//            }
-//        else if ( isKernel )
-//            {
-//            _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: Kernel" );
-//            RDebug::Print( KTrace2 );
-//            }
-//#endif
-//
-//        // Got a valid thread object - now work out which operation to perform...
-//        switch( aFunction )
-//            {
-//        case EMemSpyClientServerOpSummaryInfo:
-//            iEngine.HelperProcess().OutputProcessInfoL( *process );
-//            break;
-//        case EMemSpyClientServerOpSummaryInfoDetailed:
-//            iEngine.HelperProcess().OutputProcessInfoDetailedL( *process );
-//            break;
-//        case EMemSpyClientServerOpHeapInfo:
-//            if  ( isKernel )
-//                {
-//                iEngine.HelperHeap().OutputHeapInfoKernelL();
-//                }
-//            else
-//                {
-//                iEngine.HelperHeap().OutputHeapInfoUserL( *thread );
-//                }
-//            break;
-//        case EMemSpyClientServerOpHeapCellListing:
-//            iEngine.HelperHeap().OutputCellListingUserL( *thread );
-//            break;
-//        case EMemSpyClientServerOpHeapData:
-//            if  ( isKernel )
-//                {
-//                iEngine.HelperHeap().OutputHeapDataKernelL();
-//                }
-//            else
-//                {
-//                iEngine.HelperHeap().OutputHeapDataUserL( *thread );
-//                }
-//            break;
-//        case EMemSpyClientServerOpStackInfo:
-//            iEngine.HelperStack().OutputStackInfoL( *thread );
-//            break;
-//        case EMemSpyClientServerOpStackDataUser:
-//            iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainUser, EFalse );
-//            break;
-//        case EMemSpyClientServerOpStackDataKernel:
-//            iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainKernel, EFalse );
-//            break;
-//        case EMemSpyClientServerOpOpenFiles:
-//            iEngine.HelperFileSystem().ListOpenFilesL( aThreadId );
-//            break;
-//
-//        default:
-//            error = KErrNotSupported;
-//            break;
-//            }
-//        }
-//
-//    TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadId: %d, error: %d", aFunction, (TUint) aThreadId, error ) );
-//    User::LeaveIfError( error );
-    }
-
-// ---------------------------------------------------------
-// HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName )
-// Gets thread ID from aThreadName 
-// and calls HandleThreadSpecificOpL( , const TThreadId& aThreadId )
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName )
-    {
-//    TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
-//    //
-//    CMemSpyProcess* process = NULL;
-//    CMemSpyThread* thread = NULL;
-//    TInt error = iEngine.Container().ProcessAndThreadByPartialName( aThreadName, process, thread );
-//    User::LeaveIfError( error );
-//    //
-//    const TThreadId threadId( thread->Id() );
-//    HandleThreadSpecificOpL( aFunction, threadId );
-//    //
-//    TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
-    }
-
-// ---------------------------------------------------------
-// HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
-// ---------------------------------------------------------
-//
-void CMemSpyServerSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
-    {
-//    TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - START" ) );
-//    //
-//    if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
-//        iEngine.HelperHeap().OutputHeapInfoForDeviceL();
-//        }
-//    else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
-//        iEngine.HelperStack().OutputStackInfoForDeviceL();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
-//        iEngine.HelperSysMemTracker().StartL();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop") );
-//        iEngine.HelperSysMemTracker().StopL();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingReset )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingReset") );
-//        iEngine.HelperSysMemTracker().Reset();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate") );
-//        iEngine.HelperSysMemTracker().CheckForChangesNowL();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet") );
-//        
-//        // Get current config
-//        TMemSpyEngineHelperSysMemTrackerConfig config;
-//        iEngine.HelperSysMemTracker().GetConfig( config );
-//
-//        // Set new timer value
-//        config.iTimerPeriod = aMessage.Int0();
-//
-//        // And update config... which will leave if the config is invalid
-//        iEngine.HelperSysMemTracker().SetConfigL( config );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet") );
-//        // Get current config
-//        TMemSpyEngineHelperSysMemTrackerConfig config;
-//        iEngine.HelperSysMemTracker().GetConfig( config );
-//
-//        // Set new categories
-//        config.iEnabledCategories = aMessage.Int0();
-//
-//        // And update config... which will leave if the config is invalid
-//        iEngine.HelperSysMemTracker().SetConfigL( config );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") );
-//        // Get current config
-//        TMemSpyEngineHelperSysMemTrackerConfig config;
-//        iEngine.HelperSysMemTracker().GetConfig( config );
-//
-//        // Set new filter
-//        RBuf buf;
-//        buf.CleanupClosePushL();
-//        TInt len = aMessage.GetDesLength( 0 );
-//        if ( len > 0 )
-//            {
-//            buf.CreateL( len );
-//            aMessage.ReadL( 0, buf, 0 );
-//            config.iThreadNameFilter.Copy( buf );            
-//            }
-//        else
-//            {
-//            config.iThreadNameFilter.Zero();
-//            }
-//        CleanupStack::PopAndDestroy( &buf );
-//
-//        // And update config... which will leave if the config is invalid
-//        iEngine.HelperSysMemTracker().SetConfigL( config );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet )
-//        {
-//        // Get current config
-//        TMemSpyEngineHelperSysMemTrackerConfig config;
-//        iEngine.HelperSysMemTracker().GetConfig( config );
-//        
-//        // Set new Heap Dump value
-//        config.iDumpData = aMessage.Int0();
-//        
-//        // And update config... which will leave if the config is invalid
-//        iEngine.HelperSysMemTracker().SetConfigL( config );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
-//        iEngine.InstallSinkL( ESinkTypeDebug );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
-//        iEngine.InstallSinkL( ESinkTypeFile );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
-//        {
-//        const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
-//
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainer - type: %d", type ) );
-//
-//        CMemSpyEngineGenericKernelObjectList* model = iEngine.HelperKernelContainers().ObjectsForSpecificContainerL( type );
-//        CleanupStack::PushL( model );
-//        model->OutputL( iEngine.Sink() );
-//        CleanupStack::PopAndDestroy( model );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainerAll )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainerAll") );
-//        CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL();
-//        CleanupStack::PushL( model );
-//        model->OutputL( iEngine.Sink() );
-//        CleanupStack::PopAndDestroy( model );
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpOpenFiles )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpOpenFiles") );
-//        iEngine.ListOpenFilesL();
-//        }
-//    else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
-//        iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
-//        }
-//    else
-//        {
-//        TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
-//        iEngine.NotifyClientServerOperationRequestL( aFunction );
-//        }
-//    //
-//    TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - END" ) );
-    }
--- a/memspy/MemSpyServer/group/MemSpyServer.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/MemSpyServer/group/MemSpyServer.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -21,15 +21,15 @@
 
 TARGETTYPE EXE
 TARGET MemSpyServer.exe
-EPOCSTACKSIZE 0x4000
-EPOCHEAPSIZE 0x100000 0x4000000
 UID 0 0x2002EA8D
 SECUREID     0xE5883BC2
 VENDORID	 0x101FB657 // Nokia
 
+EPOCSTACKSIZE 0x4000
+EPOCHEAPSIZE 0x100000 0x4000000
+
+
 SOURCEPATH ../Source
-SOURCE 		MemSpyServer.cpp 
-SOURCE		MemSpyServerSession.cpp 
 SOURCE		MemSpyServerMain.cpp 
 
 USERINCLUDE ../Include
@@ -38,6 +38,8 @@
 
 OS_LAYER_SYSTEMINCLUDE
 
+APP_LAYER_SYSTEMINCLUDE
+
 LIBRARY         MemSpyDriverClient.lib
 LIBRARY         MemSpyEngine.lib
 
@@ -52,5 +54,5 @@
 LIBRARY			fbscli.lib 
 LIBRARY 		PlatformEnv.lib
 LIBRARY 		flogger.lib
-LIBRARY			apgrfx.lib	
-LIBRARY			apparc.lib	
+LIBRARY			apgrfx.lib
+
--- a/memspy/group/ReleaseNotes_MemSpy.txt	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/group/ReleaseNotes_MemSpy.txt	Thu Jul 22 16:50:07 2010 +0100
@@ -1,7 +1,7 @@
 ===============================================================================
 
-RELEASE NOTES - MEMSPY v1.2.0
-RELEASED 27th October 2009 
+RELEASE NOTES - MEMSPY v2.1.0
+RELEASED 15th June 2010 
 
 SUPPORTS S60 5.0+
 
@@ -28,17 +28,15 @@
 
 ===============================================================================
 
-What's New in v1.2.0
+What's New in v2.1.0
 ====================
-- Feature: Tracking modes introduced for simplify System Wide Memory Tracking
-  settings.
-- Feature: System Wide Memory Tracking categories can now be selected.
-- Feature: Heap data captured during System Wide Memory Tracking can be
-  filtered by thread name.
-- Feature: Shared heaps can now be detected with S60 UI and trace output.
-- Feature: Batch files for running MemSpy functions can now be executed from
-  command line.
-- Change: Command line interface documented in User's Guide.
+- Feature: Folder where log files are saved can now be set in settings.
+- Feature: Introduced new Orbit based user interface.
+- Change: Servers, Ecom, Window groups, System info and Automatic Capture were
+  removed.
+- Change: Console interface was removed.
+- Change: Command line interface commands were changed to be more user 
+  friendly.
 
 ===============================================================================
 
@@ -101,6 +99,18 @@
 Version History:
 ================
 
+Version 1.2.0 - 27th October 2009 
+---------------------------------
+- Feature: Tracking modes introduced for simplify System Wide Memory Tracking
+  settings.
+- Feature: System Wide Memory Tracking categories can now be selected.
+- Feature: Heap data captured during System Wide Memory Tracking can be
+  filtered by thread name.
+- Feature: Shared heaps can now be detected with S60 UI and trace output.
+- Feature: Batch files for running MemSpy functions can now be executed from
+  command line.
+- Change: Command line interface documented in User's Guide.
+
 Version 1.1.0 - 22nd July 2009
 ------------------------------
 - Fix: Browsing chunk list resulted in a crash.
--- a/memspy/group/bld.inf	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/group/bld.inf	Thu Jul 22 16:50:07 2010 +0100
@@ -29,9 +29,6 @@
 // Commandline includes
 #include "../CommandLine/group/bld.inf"
 
-// Console UI
-#include "../Console/group/bld.inf"
-
 // MemSpyServer
 #include "../MemSpyServer/group/bld.inf"
 
--- a/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h	Thu Jul 22 16:50:07 2010 +0100
@@ -45,11 +45,12 @@
 const TInt KMemSpyOpFlagsInclusionMask          = 0xFFFF0000;
 const TInt KMemSpyOpFlagsIncludesThreadId       = 0x00010000;
 const TInt KMemSpyOpFlagsIncludesThreadName     = 0x00020000;
-
+const TInt KMemSpyOpFlagsAsyncOperation         = 0x00040000;
 // Literal constants
 _LIT( KMemSpyServerName, "MemSpyServer" );
+_LIT( KMemSpyProcessName0, "MemSpyServer.exe" );
 _LIT( KMemSpyProcessName1, "MemSpyUI.exe" );
-_LIT( KMemSpyProcessName2, "MemSpyConsole.exe" );
+//_LIT( KMemSpyProcessName2, "MemSpyConsole.exe" );
 
 //
 // Supported MemSpy operation types
@@ -258,12 +259,104 @@
     EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet,
     
     /**
-     * [INTERNAL REQUEST]
-     */
+	 * [INTERNAL REQUEST]
+	 */
+	EMemSpyClientServerOpMarkerUiFirst,
+	
+	EMemSpyClientServerOpGetProcessCount = EMemSpyClientServerOpMarkerUiFirst,
+	
+	EMemSpyClientServerOpGetProcesses,
+	
+	EMemSpyClienServerOpGetProcessIdByName,
+	
+	EMemSpyClientServerOpGetThreadCount,
+	
+	EMemSpyClientServerOpGetThreads,
+	
+	EMemSpyClientServerOpSetThreadPriority,
+	
+	EMemSpyClientServerOpProcessSystemPermanentOrCritical,
+	
+	EMemSpyClientServerOpEndProcess,
+	
+	EMemSpyClientServerOpSwitchToProcess,
+	
+	//Threads operations
+	EMemSpyClientServerOpThreadSystemPermanentOrCritical,
+	
+	EMemSpyClientServerOpEndThread,
+	
+	EMemSpyClientServerOpSwitchToThread,
+	
+	EMemSpyClientServerOpGetInfoItemType,
+	
+	EMemSpyClientServerOpGetThreadInfoItemsCount,
+	
+	EMemSpyClientServerOpGetThreadInfoItems,
+	
+	EMemSpyClientServerOpOutputInfoHandles,
+	
+	EMemSpyClientServerOpOutputAOList,
+		
+	
+	//Kernel Objects operations
+	EMemSpyClientServerOpGetKernelObjectCount,
+	
+	EMemSpyClientServerOpGetKernelObjects,
+	
+	EMemSpyClientServerOpGetKernelObjectItemCount,
+	
+	EMemSpyClientServerOpGetKernelObjectItems,
+	
+	EMemSpyClientServerOpGetHeap,
+	
+	EMemSpyClientServerOpGetMemoryTrackingCycleCount,
+	
+	EMemSpyClientServerOpGetMemoryTrackingCycles,
+	
+	/**
+	 * [INTERNAL REQUEST]
+	 * Register for notifications of device wide operation progress.
+	 */
+	EMemSpyClientServerOpNotifyDeviceWideOperationProgress,
+	
+	/**
+	 * [INTERNAL REQUEST]
+	 * Cancel current device wide operation
+	 */
+	EMemSpyClientServerOpCancelDeviceWideOperation,	
+	
+	EMemSpyClientServerOpOutputAllContainerContents,
+	    
+	EMemSpyClientServerOpDumpKernelHeap,
+	
+	EMemSpyClientServerOpSetSwmtConfig,
+	
+	EMemSpyClientServerOpSetSwmtAutoStartProcessList,
+		
+	EMemSpyClientServerOpGetOutputSink,
+	
+	/**
+	 * [INTERNAL REQUEST]
+	 * Check if system wide memory tracking timer is running.
+	 */
+	EMemSpyClientServerOpIsSwmtRunning,
+	
+	EMemSpyClientServerOpMarkerUiLast,		
+	
+	/**
+	 * [INTERNAL REQUEST]
+	 */
     EMemSpyClientServerOpMarkerLast,
     };
 
 
+enum TMemSpyEndType
+	{
+	ETerminate,
+	EKill,
+	EPanic
+	};
 
 
 
--- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverEnumerationsShared.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverEnumerationsShared.h	Thu Jul 22 16:50:07 2010 +0100
@@ -24,12 +24,24 @@
 // Enumerations
 enum TMemSpyDriverCellType
 	{
-	EMemSpyDriverGoodAllocatedCell = 0,
-	EMemSpyDriverGoodFreeCell,
-	EMemSpyDriverBadAllocatedCellSize,
-	EMemSpyDriverBadAllocatedCellAddress,
-	EMemSpyDriverBadFreeCellAddress,
-	EMemSpyDriverBadFreeCellSize
+	EMemSpyDriverAllocatedCellMask	= 0x000000FF,
+	EMemSpyDriverFreeCellMask		= 0x0000FF00,
+	EMemSpyDriverBadCellMask		= 0xFF000000,
+
+	EMemSpyDriverHeapAllocation		= 0x00000001,
+	EMemSpyDriverDlaAllocation		= 0x00000002,
+	EMemSpyDriverPageAllocation		= 0x00000003,
+	EMemSpyDriverSlabAllocation		= 0x00000004,
+	
+	EMemSpyDriverHeapFreeCell		= 0x00000100,
+	EMemSpyDriverDlaFreeCell		= 0x00000200,
+	EMemSpyDriverSlabFreeCell		= 0x00000300, // Used to track free cells in partially-filled slabs
+	EMemSpyDriverSlabFreeSlab		= 0x00000400, // Used to track entirely empty slabs (that don't have a specific cell size)
+
+	EMemSpyDriverHeapBadFreeCellAddress			= 0x01000000,
+	EMemSpyDriverHeapBadFreeCellSize			= 0x02000000,
+	EMemSpyDriverHeapBadAllocatedCellSize		= 0x03000000,
+	EMemSpyDriverHeapBadAllocatedCellAddress	= 0x04000000,
 	};
 
 
--- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsShared.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsShared.h	Thu Jul 22 16:50:07 2010 +0100
@@ -349,7 +349,8 @@
     enum THeapImplementationType
         {
         ETypeUnknown = 0,
-        ETypeRHeap
+        ETypeRHeap = 1,
+		ETypeRHybridHeap = 2,
         };
 
 public: // Constructor & destructor
@@ -426,17 +427,19 @@
     };
 
 
-
 /**
- * Free cell information
+ * cell information
  */
 class TMemSpyDriverFreeCell
-    {
+	{
 public:
-    TInt iType;
-    TAny* iAddress;
-    TInt iLength;
-    };
+	TMemSpyDriverCellType iType;
+	TAny* iAddress;
+	TInt iLength;
+	};
+
+// For compatibility I can't change TMemSpyDriverCell to be the class and typdef/derive TMemSpyDriverFreeCell. Sigh...
+typedef TMemSpyDriverFreeCell TMemSpyDriverCell;
 
 
 /** 
--- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsSharedRHeap.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsSharedRHeap.h	Thu Jul 22 16:50:07 2010 +0100
@@ -35,80 +35,6 @@
 class CTrapCleanup;
 
 
-
-class TMemSpyHeapObjectDataRHeap
-    {
-public:
-    inline TMemSpyHeapObjectDataRHeap()
-        : iAccessCount( 0 ),
-          iHandleCount( 0 ),
-          iHandles( NULL ),
-          iFlags( 0 ),
-          iCellCount( 0 ),
-          iTotalAllocSize ( 0 ),
-          //
-          iMinLength( 0 ),
-          iMaxLength( 0 ),
-          iOffset ( 0 ),
-          iGrowBy( 0 ),
-          iChunkHandle ( 0 ),
-          iBase( NULL ),
-          iTop( NULL ),
-          iAlign( 0 ),
-          iMinCell( 0 ),
-          iPageSize( 0 ),
-          iNestingLevel( 0 ),
-          iAllocCount( 0 ),
-          iFailRate( 0 ),
-          iFailed( EFalse ),
-          iFailAllocCount( 0 ),
-          iRand( 0 ),
-          iTestData( NULL )
-        {
-        }
-
-public: // API
-    inline TUint8* Base() const { return iBase; }
-    inline TUint Size() const { return iTop - iBase; }
-
-public: // From RAllocator
-	TInt iAccessCount;
-	TInt iHandleCount;
-	TInt* iHandles;
-	TUint32 iFlags;
-	TInt iCellCount;
-	TInt iTotalAllocSize;
-
-public: // From RHeap
-	TInt iMinLength;
-	TInt iMaxLength;
-	TInt iOffset;
-	TInt iGrowBy;
-	TInt iChunkHandle;
-    RFastLock iLock;
-	TUint8* iBase;
-	TUint8* iTop;
-	TInt iAlign;
-	TInt iMinCell;
-	TInt iPageSize;
-#ifdef __SYMBIAN_KERNEL_HYBRID_HEAP__
-	struct SCell { TInt len; SCell* next; };
-    SCell iFree;
-#else
-    RHeap::SCell iFree;
-#endif
-	TInt iNestingLevel;
-	TInt iAllocCount;
-    RAllocator::TAllocFail iFailType;
-	TInt iFailRate;
-	TBool iFailed;
-	TInt iFailAllocCount;
-	TInt iRand;
-	TAny* iTestData;
-    };
-
-
-
 /**
  * Base class for MemSpy RHeap statistics
  */
@@ -205,33 +131,6 @@
     TUint32 iChecksum;
     };
 
-
-
-
-
-/**
- * RHeap statistics for common cell types
- */
-class TMemSpyHeapStatisticsRHeapCommon
-    {
-public: // Constructors
-    inline TMemSpyHeapStatisticsRHeapCommon()
-        : iTotalCellCount( 0 )
-        {
-        }
-
-public:
-    inline TUint TotalCellCount() const { return iTotalCellCount; }
-    inline void SetTotalCellCount( TUint aValue ) { iTotalCellCount = aValue; }
-
-private:
-    TUint iTotalCellCount;
-    };
-
-
-
-
-
 /**
  * RHeap statistics class
  */
@@ -239,6 +138,7 @@
     {
 public: // Constructors
     inline TMemSpyHeapStatisticsRHeap()
+		: iCommittedFreeSpace(0)
         {
         }
 
@@ -248,14 +148,14 @@
     //
     inline TMemSpyHeapStatisticsRHeapAllocated& StatsAllocated() { return iStatisticsAllocated; }
     inline const TMemSpyHeapStatisticsRHeapAllocated& StatsAllocated() const { return iStatisticsAllocated; }
-    //
-    inline TMemSpyHeapStatisticsRHeapCommon& StatsCommon() { return iStatisticsCommon; }
-    inline const TMemSpyHeapStatisticsRHeapCommon& StatsCommon() const { return iStatisticsCommon; }
+
 
 private: // Data members
-    TMemSpyHeapStatisticsRHeapCommon iStatisticsCommon;
     TMemSpyHeapStatisticsRHeapFree iStatisticsFree;
     TMemSpyHeapStatisticsRHeapAllocated iStatisticsAllocated;
+
+public: // I am fed up of all these pointless inline accessors...
+	TInt iCommittedFreeSpace; // The amount of committed memory that isn't payload data in allocated or free cells
     };
 
 
@@ -275,10 +175,15 @@
           iChunkHandle( NULL ),
           iChunkBaseAddress( NULL ),
           iDebugAllocator( EFalse ),
-          iHeaderSizeFree( 0 ),
-          iHeaderSizeAllocated( 0 ),
+          //iHeaderSizeFree( 0 ),
+          //iHeaderSizeAllocated( 0 ),
           iIsUserThread( ETrue ),
-          iSharedHeap( EFalse )
+		  iVTable(0),
+          iSharedHeap( EFalse ),
+          iHeapSize(0),
+          iAllocatorAddress(NULL),
+		  iMinHeapSize(0),
+		  iMaxHeapSize(0)
         {
         }
 
@@ -358,12 +263,6 @@
     inline TAny* ChunkBaseAddress() const { return iChunkBaseAddress; }
     inline void SetChunkBaseAddress( TAny* aValue ) { iChunkBaseAddress = aValue; }
     //
-    inline TUint HeaderSizeFree() const { return iHeaderSizeFree; }
-    inline void SetHeaderSizeFree( TUint aValue ) { iHeaderSizeFree = aValue; }
-    //
-    inline TUint HeaderSizeAllocated() const { return iHeaderSizeAllocated; }
-    inline void SetHeaderSizeAllocated( TUint aValue ) { iHeaderSizeAllocated = aValue; }
-    //
     inline TBool IsDebugAllocator() const { return iDebugAllocator; }
     inline void SetDebugAllocator( TBool aValue ) { iDebugAllocator = aValue; }
     //
@@ -375,30 +274,24 @@
     //
     inline TUint VTable() const { return iVTable; }
     inline void SetVTable( TUint aValue ) { iVTable = aValue; }
-    //
-    inline TUint ClassSize() const { return iClassSize; }
-    inline void SetClassSize( TUint aValue ) { iClassSize = aValue; }
 
 private: // Data members
     TBuf8< KMaxFullName * 2 > iChunkName;
+public:
     TUint iChunkSize;
     TAny* iChunkHandle;
     TAny* iChunkBaseAddress;
     TBool iDebugAllocator;
-    TUint iHeaderSizeFree;
-    TUint iHeaderSizeAllocated;
     TBool iSharedHeap;
     TBool iIsUserThread;
     TUint iVTable;
-    TUint iClassSize;
+	TUint iHeapSize; // Committed size - generally the same as iChunkSize (except maybe for kernel heap)
+	TAny* iAllocatorAddress; // replacement for things using the RHeap base address
+	TUint iMinHeapSize; // Minimum committed size
+	TUint iMaxHeapSize; // Max committed size
     };
 
 
-
-
-
-
-
 /**
  *
  */
@@ -413,15 +306,17 @@
     inline TMemSpyHeapMetaDataRHeap& MetaData() { return iMetaData; }
     inline const TMemSpyHeapMetaDataRHeap& MetaData() const { return iMetaData; }
     //
-    inline TMemSpyHeapObjectDataRHeap& ObjectData() { return iObjectData; }
-    inline const TMemSpyHeapObjectDataRHeap& ObjectData() const { return iObjectData; }
+    //inline TMemSpyHeapObjectDataRHeap& ObjectData() { return iObjectData; }
+    //inline const TMemSpyHeapObjectDataRHeap& ObjectData() const { return iObjectData; }
     //
     inline TMemSpyHeapStatisticsRHeap& Statistics() { return iStatistics; }
     inline const TMemSpyHeapStatisticsRHeap& Statistics() const { return iStatistics; }
 
+	inline TInt Overhead() const { return iMetaData.iHeapSize - iStatistics.StatsAllocated().TypeSize() - iStatistics.iCommittedFreeSpace; }
+
 private: // Data members
     TMemSpyHeapMetaDataRHeap iMetaData;
-    TMemSpyHeapObjectDataRHeap iObjectData;
+    //TMemSpyHeapObjectDataRHeap iObjectData;
     TMemSpyHeapStatisticsRHeap iStatistics;
     };
 
--- a/memspy/memspy_plat/memspy_api/include/memspy/driver/user/MemSpyDriverClient.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/user/MemSpyDriverClient.h	Thu Jul 22 16:50:07 2010 +0100
@@ -157,6 +157,7 @@
      */
     IMPORT_C TInt GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid );
     IMPORT_C TInt GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray<TMemSpyDriverFreeCell>& aFreeCells );
+	IMPORT_C TInt GetHeapInfoUser(TMemSpyHeapInfo& aInfo, TUint aTid, RArray<TMemSpyDriverCell>& aCells, TBool aCollectAllocatedCellsAsWellAsFree);
 
     /**
      *
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperFbServ.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperFbServ.h	Thu Jul 22 16:50:07 2010 +0100
@@ -74,7 +74,7 @@
     HBufC8* LocateBitmapArrayHeapCellDataLC( TAny*& aArrayCellAddress, TInt aArrayAllocCount );
     void ReadCObjectConInfoL( TAny* aCellAddress, RArray<TAny*>& aContainerObjects, TInt& aCount, TInt& aAllocated );
     static void ParseCellDataAndExtractHandlesL( const TDesC8& aData, RArray<TInt>& aHandles, TInt aArrayEntryCount );
-    static TBool VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapSize );
+    static TBool VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapMaxSize );
     static TUint OffsetToCObjectConBitmapCon();
     static TUint OffsetToCObjectConFontCon();
     static TUint OffsetToBitmapHandleArray();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperHeap.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperHeap.h	Thu Jul 22 16:50:07 2010 +0100
@@ -47,7 +47,8 @@
     void ConstructL();
 
 public: // API - User Heap 
-    IMPORT_C void GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells = NULL );
+    IMPORT_C void GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverCell>* aCells = NULL );
+	IMPORT_C void GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverCell>* aCells, TBool aCollectAllocatedCellsAsWellAsFree);
     IMPORT_C void GetHeapInfoUserL( const CMemSpyProcess& aProcess, RArray<TMemSpyHeapInfo >& aInfos );
     IMPORT_C void OutputHeapInfoUserL( const CMemSpyThread& aThread );
     IMPORT_C void OutputHeapDataUserL( const CMemSpyThread& aThread );
@@ -60,10 +61,10 @@
     IMPORT_C void OutputHeapDataKernelL();
 
 public: // API - Common
-    IMPORT_C void OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray<TMemSpyDriverFreeCell>* aFreeCells = NULL );
+    IMPORT_C void OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray<TMemSpyDriverCell>* aCells = NULL );
     IMPORT_C void OutputHeapInfoForDeviceL( TBool aIncludeKernel = ETrue );
     IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryShortLC( const TMemSpyHeapInfo& aInfo );
-    IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverFreeCell>* aFreeCells = NULL );
+    IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells = NULL );
     //cigasto    
     IMPORT_C TMemSpyHeapData NewHeapRawInfo( const TMemSpyHeapInfo& aInfo ); //not formatted heap info
 
@@ -75,9 +76,8 @@
 private:
     static TUint DescriptorAsDWORD( const TDesC8& aItem );
     void AppendMetaDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList );
-    void AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList );
     void AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList );
-    void AppendFreeCellsL( const RArray<TMemSpyDriverFreeCell>& aFreeCells, CMemSpyEngineOutputList& aList );
+	void AppendCellsL(const RArray<TMemSpyDriverCell>& aCells, CMemSpyEngineOutputList& aList);
     void OutputCSVEntryL( TInt aIndex, const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const TDesC& aProcessName );
     void UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo );
 
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h	Thu Jul 22 16:50:07 2010 +0100
@@ -60,6 +60,7 @@
     {
 public:
     IMPORT_C static CMemSpyEngine* NewL( RFs& aFsSession );
+    IMPORT_C static CMemSpyEngine* NewL( RFs& aFsSession, TBool aStartServer );
     IMPORT_C ~CMemSpyEngine();
 
 private:
@@ -80,6 +81,8 @@
     IMPORT_C CMemSpyEngineOutputSink& Sink();
     IMPORT_C TMemSpySinkType SinkType();
     IMPORT_C void InstallSinkL( TMemSpySinkType aType );
+    IMPORT_C void InstallDebugSinkL();
+    IMPORT_C void InstallFileSinkL( const TDesC& aRootFolder );
 
 public: // Misc
     IMPORT_C void ListOpenFilesL();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h	Thu Jul 22 16:50:07 2010 +0100
@@ -80,6 +80,7 @@
     CMemSpyEngineOutputSink& Sink();
     TMemSpySinkType SinkType();
     void InstallSinkL( TMemSpySinkType aType );
+    void InstallSinkL( TMemSpySinkType aType, const TDesC& aRootFolder );
 
 public: // Misc
     void ListOpenFilesL();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Sink/MemSpyEngineOutputSink.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Sink/MemSpyEngineOutputSink.h	Thu Jul 22 16:50:07 2010 +0100
@@ -48,13 +48,16 @@
     IMPORT_C static CMemSpyEngineSinkMetaData* NewL();
     IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp );
     IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp );
+    IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp );
+    IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp );
     IMPORT_C ~CMemSpyEngineSinkMetaData();
 
 private:
     CMemSpyEngineSinkMetaData( TBool aOverwrite, TBool aUseTimeStamp );
-    void ConstructL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime );
+    void ConstructL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime );
 
 public: // Access
+    inline const TDesC& Root() const { return *iRoot; }
     inline const TDesC& Context() const { return *iContext; }
     inline const TDesC& Folder() const { return *iFolder; }
     inline const TDesC& Extension() const { return *iExtension; }
@@ -63,6 +66,7 @@
     inline const TBool UseFileTimeStamp() const { return iUseFileTimeStamp; }
 
 private: // Data members
+    HBufC* iRoot;
     HBufC* iContext;
     HBufC* iFolder;
     HBufC* iExtension;
@@ -146,4 +150,4 @@
 
 
 
-#endif
\ No newline at end of file
+#endif
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTracker.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTracker.h	Thu Jul 22 16:50:07 2010 +0100
@@ -58,9 +58,10 @@
     //
     IMPORT_C const RPointerArray< CMemSpyEngineHelperSysMemTrackerCycle >& CompletedCycles() const;
 
+    IMPORT_C void CheckForChangesNowL();
+
 public: // But not exported
     void Reset();
-    void CheckForChangesNowL();
 
 public: // From MDesCArray
     IMPORT_C TInt MdcaCount() const;
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTrackerConfig.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTrackerConfig.h	Thu Jul 22 16:50:07 2010 +0100
@@ -22,7 +22,8 @@
 #include <e32base.h>
 
 // Constants
-const TInt KMemSpySysMemTrackerConfigMinTimerPeriod = 30; // Seconds
+const TInt KMemSpySysMemTrackerConfigMinTimerPeriod = 5; // Seconds
+const TInt KMemSpySysMemTrackerConfigMaxTimerPeriod = 60; // Seconds
 
 
 NONSHARABLE_CLASS( TMemSpyEngineHelperSysMemTrackerConfig )
@@ -90,4 +91,4 @@
     };
 
 
-#endif
\ No newline at end of file
+#endif
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectProcess.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectProcess.h	Thu Jul 22 16:50:07 2010 +0100
@@ -65,7 +65,11 @@
     IMPORT_C TBool IsDead() const;
     IMPORT_C TUint32 SID() const;
     IMPORT_C TUint32 VID() const;
-
+    IMPORT_C TProcessPriority Priority() const;
+    IMPORT_C TExitCategoryName ExitCategory() const;
+    IMPORT_C TInt ExitReason() const;
+    IMPORT_C TExitType ExitType() const;
+    
 public: // API - misc
     IMPORT_C void KillL();
     IMPORT_C void TerminateL();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.h	Thu Jul 22 16:50:07 2010 +0100
@@ -98,6 +98,8 @@
 public: // From MDesCArray
     IMPORT_C TInt MdcaCount() const;
     IMPORT_C TPtrC MdcaPoint(TInt aIndex) const;
+    IMPORT_C TPtrC Caption(TInt aIndex ) const;
+    IMPORT_C TPtrC Value(TInt aIndex ) const;
 
 protected:
     class CItem : public CBase
--- a/memspy/rom/memspy.iby	Mon Jun 21 22:45:06 2010 +0100
+++ b/memspy/rom/memspy.iby	Thu Jul 22 16:50:07 2010 +0100
@@ -30,8 +30,8 @@
 file=ABI_DIR\BUILD_DIR\MemSpy.exe									            SHARED_LIB_DIR\MemSpy.exe
 
 // Console UI
-file=ABI_DIR\BUILD_DIR\MemSpyConsole.exe										SHARED_LIB_DIR\MemSpyConsole.exe
-data=ZPRIVATE\\2002129E\MemSpyEComInterfaceIds.xml							    \private\2002129E\MemSpyEComInterfaceIds.xml
-data=ZPRIVATE\\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml		    \private\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml
+//file=ABI_DIR\BUILD_DIR\MemSpyConsole.exe										SHARED_LIB_DIR\MemSpyConsole.exe
+//data=ZPRIVATE\\2002129E\MemSpyEComInterfaceIds.xml							    \private\2002129E\MemSpyEComInterfaceIds.xml
+//data=ZPRIVATE\\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml		    \private\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml
 
 #endif
--- a/osrndtools_info/osrndtools_metadata/osrndtools_metadata.mrp	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
-# which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
-#
-# Initial Contributors:
-# Nokia Corporation - initial contribution.
-#
-# Contributors:
-#
-# Description: 
-#
-
-component           osrndtools_metadata
-source   \sf\os\osrndtools\osrndtools_info\osrndtools_metadata 
-source   \sf\os\osrndtools\package_definition.xml
-source   \sf\os\osrndtools\distribution.policy.s60
-notes_source      \component_defs\release.src
-ipr T 
--- a/package_definition.xml	Mon Jun 21 22:45:06 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SystemDefinition schema="3.0.0">
- <package id="osrndtools" name="OS R&amp;D tools" levels="fw trace">
-  <collection id="stif" name="STIF" level="fw">
-   <component id="testinterface" filter="s60" name="Test Interface" purpose="development">
-    <unit bldFile="stif/testinterface/group"/>
-   </component>
-   <component id="testserver" filter="s60" name="Test Server" purpose="development">
-    <unit bldFile="stif/testserver/group"/>
-   </component>
-   <component id="testengine" filter="s60" name="Test Engine" purpose="development">
-    <unit bldFile="stif/testengine/group"/>
-   </component>
-   <component id="testserverstarter" filter="s60" name="Test Server Starter" purpose="development">
-    <unit bldFile="stif/testserverstarter/group"/>
-   </component>
-   <component id="stiftfwif" filter="s60" name="STIF Test Framework Interface" purpose="development">
-    <unit bldFile="stif/stiftfwif/group"/>
-   </component>
-   <component id="consoleui" filter="s60" name="Console UI" purpose="development">
-    <unit bldFile="stif/consoleui/group"/>
-   </component>
-   <component id="testcombiner" filter="s60" name="Test Combiner" purpose="development">
-    <unit bldFile="stif/testcombiner/group"/>
-   </component>
-   <component id="demomodule" filter="s60" name="Demo Module" purpose="development">
-    <unit bldFile="stif/demomodule/group"/>
-   </component>
-   <component id="atslogger" filter="s60" name="ATS Logger" purpose="development">
-    <unit bldFile="stif/atslogger/group"/>
-   </component>
-   <component id="atsinterface" filter="s60" name="ATS Interface" purpose="development">
-    <unit bldFile="stif/atsinterface/group"/>
-   </component>
-   <component id="testscripter" filter="s60" name="Test Scripter" purpose="development">
-    <unit bldFile="stif/testscripter/group"/>
-   </component>
-   <component id="suevent" filter="s60" name="SU Event" purpose="development">
-    <unit bldFile="stif/suevent/group"/>
-   </component>
-   <component id="stifkerneltestclassbase" filter="s60" name="STIF Kernel Test Class Base" purpose="development">
-    <unit bldFile="stif/stifkerneltestclassbase/group"/>
-   </component>
-   <component id="examples" filter="s60" name="STIF Examples" purpose="development">
-    <!-- <unit bldFile="stif/examples/stiftestmeasurementstub/group"/> -->
-    <!-- <unit bldFile="stif/examples/stifhwresetstub/group"/> -->
-   </component>
-   <component id="testmoduletemplates" filter="s60" name="Test Module Templates" purpose="development">
-    <!-- <unit bldFile="stif/testmoduletemplates/templatescriptxxx/group"/> -->
-    <!-- <unit bldFile="stif/testmoduletemplates/templatekernelscriptxxx/group"/> -->
-    <!-- <unit bldFile="stif/testmoduletemplates/capsmodifierxxx/group"/> -->
-    <!-- <unit bldFile="stif/testmoduletemplates/testmodulexxx/group"/> -->
-    <!-- <unit bldFile="stif/testmoduletemplates/stifunitxxx/group"/> -->
-    <!-- <unit bldFile="stif/testmoduletemplates/hardcodedtestmodulexxx/group"/> -->
-   </component>
-   <component id="stif_build" filter="s60" name="STIF Build" purpose="development">
-    <unit bldFile="stif/group"/>
-   </component>
-  </collection>
-  <collection id="memspy" name="Memspy" level="trace">
-   <component id="driver" filter="s60" name="Memspy Driver" purpose="development">
-    <unit bldFile="memspy/driver/group"/>
-   </component>
-   <component id="memspy_engine" filter="s60" name="Memspy Engine" purpose="development">
-    <unit bldFile="memspy/engine/group"/>
-   </component>
-   <component id="commandline" filter="s60" name="Memspy Command Line" purpose="development">
-    <unit bldFile="memspy/commandline/group"/>
-   </component>
-   <component id="console" filter="s60" name="Memspy Console" purpose="development">
-    <unit bldFile="memspy/console/group"/>
-   </component>
-   <component id="memspy_build" filter="s60" name="Memspy Build" purpose="development">
-    <unit bldFile="memspy/group"/>
-   </component>
-  </collection>
-  <collection id="hti" name="Harmonized Test Interface" level="trace">
-   <component id="htiframework" filter="s60" name="HTI Framework" purpose="development">
-    <unit bldFile="hti/htiframework/group"/>
-   </component>
-   <component id="hticfg" filter="s60" name="HTI Config" purpose="development">
-    <unit bldFile="hti/hticfg/group"/>
-   </component>
-   <component id="htiautostart" filter="s60" name="HTI Autostart" purpose="development">
-    <unit bldFile="hti/htiautostart/group"/>
-   </component>
-   <component id="htifilehlp" filter="s60" name="HTI File Help" purpose="development">
-    <unit bldFile="hti/htifilehlp/group"/>
-   </component>
-   <component id="htiwatchdog" filter="s60" name="HTI Watchdog" purpose="development">
-    <unit bldFile="hti/htiwatchdog/group"/>
-   </component>
-   <component id="hti_build" filter="s60" name="HTI Build" purpose="development">
-    <unit bldFile="hti/group"/>
-   </component>
-  </collection>
-    <collection id="testexecfw1" name="Test Execution Framework v1" level="fw">
-      <component id="cinidata" name="CINI Data" purpose="development">
-        <unit bldFile="testexecfw1/cinidata" mrp="testexecfw1/cinidata/tools_cinidata.mrp"/>
-      </component>
-      <component id="testexecute" name="Test Execute" deprecated="^2" purpose="development">
-        <unit bldFile="testexecfw1/testexecute/Group" mrp="testexecfw1/testexecute/Group/tools_testexecute.mrp"/>
-      </component>
-    </collection>
-    <collection id="osrndtools_info" name="OS R&amp;D tools Info" level="trace">
-      <component id="osrndtools_plat" filter="s60" name="OS R&amp;D tools Platform Interfaces" class="api" purpose="development">
-        <unit bldFile="osrndtools_plat/group"/>
-          <!-- need to #include the next bld.inf  in the above one -->
-        <unit bldFile="osrndtools_plat/hti_api/group"/>
-      </component>
-      <component id="osrndtools_metadata" name="OS R&amp;D tools Metadata" class="config" introduced="^2" purpose="development" target="desktop">
-        <unit mrp="osrndtools_info/osrndtools_metadata/osrndtools_metadata.mrp"/>
-      </component>
-    </collection>
-  </package>
-</SystemDefinition>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/ProfilerEngine.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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	Thu Jul 22 16:50:07 2010 +0100
@@ -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/ATSInterface/inc/ATSInterface.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ATSInterface/inc/ATSInterface.h	Thu Jul 22 16:50:07 2010 +0100
@@ -188,5 +188,5 @@
 
 
 #endif // ATS_INTERFACE_H
-    
+
 // End of File
--- a/stif/ATSInterface/inc/ATSInterfaceRunner.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ATSInterface/inc/ATSInterfaceRunner.h	Thu Jul 22 16:50:07 2010 +0100
@@ -253,5 +253,5 @@
     };
 
 #endif // ATS_INTERFACE_RUNNER_H
-    
+
 // End of File
--- a/stif/ATSInterface/src/ATSInterface.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ATSInterface/src/ATSInterface.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1106,6 +1106,4 @@
     return err;
     }
 
-//  End of File
-
 // End of File
--- a/stif/ATSInterface/src/ATSInterfaceRunner.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ATSInterface/src/ATSInterfaceRunner.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -565,6 +565,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
-
 // End of File
--- a/stif/ATSLogger/src/atslogger.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ATSLogger/src/atslogger.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1113,5 +1113,4 @@
 		}
 	}
 
-
 // End of File
--- a/stif/ConsoleUI/inc/CallBack.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ConsoleUI/inc/CallBack.h	Thu Jul 22 16:50:07 2010 +0100
@@ -207,5 +207,5 @@
     };
 
 #endif      // CALLBACK_H  
-            
+
 // End of File
--- a/stif/ConsoleUI/inc/ConsoleMenus.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ConsoleUI/inc/ConsoleMenus.h	Thu Jul 22 16:50:07 2010 +0100
@@ -1246,6 +1246,7 @@
 _LIT( KSetLoad,         "Load test set" );
 
 _LIT( KSetShow,         "Show started test sets" );
+_LIT( KSetUnload,       "Unload test set" );
 _LIT( KSetRemove,       "Remove test set" );
 _LIT( KSetCaseAdd,      "Add test case to test set" );
 _LIT( KSetCaseRemove,   "Remove test case from test set" );
@@ -1281,6 +1282,7 @@
             ESetStartPar,
             //ESetStartRep,
  
+            ESetUnload,
             ESetRemove,
             ESetSave,
             ESetCaseAdd,
--- a/stif/ConsoleUI/src/Consolemenus.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/ConsoleUI/src/Consolemenus.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -3875,6 +3875,10 @@
             {
             return KErrNoMemory;
             }
+        if( aArray.Append( KSetUnload ) != KErrNone )
+            {
+            return KErrNoMemory;
+            }                        
         if( aArray.Append( KSetRemove ) != KErrNone )
             {
             return KErrNoMemory;
@@ -4026,11 +4030,19 @@
                                         this, 
                                         _L("Started test sets menu"));
                 return iSubMenu;
+            case ESetUnload:
+                ret = iMain->UIStore().UnloadTestSet( iTestSetName );
+                if( ret != KErrNone )
+                    {
+                    User::InfoPrint( _L("Test set unload failed") );
+                    }
+                iTestSetCreated = EFalse;                  
+                break;
             case ESetRemove: 
                 ret = iMain->UIStore().RemoveTestSet( iTestSetName );
                 if( ret != KErrNone )
                     {
-                    User::InfoPrint( _L("Test set creation failed") );
+                    User::InfoPrint( _L("Test set remove failed") );
                     }
                 iTestSetCreated = EFalse;  
                 break;
@@ -4067,17 +4079,6 @@
                     User::InfoPrint( _L("Test set saving failed at saving test set") );
                     } 
                 
-                ret = iMain->UIStore().RemoveTestSet( currSetName );
-                if( ret != KErrNone )
-                    {
-                    User::InfoPrint( _L("Test set saving failed at removing old test set") );
-                    }             
-                
-                ret = iMain->UIStore().LoadTestSet( iTestSetName );
-                if( ret != KErrNone )
-                    {
-                    User::InfoPrint( _L("Test set saving failed at reloding test set") );
-                    }   
                 break;
   
   			default:          
@@ -4268,7 +4269,12 @@
     {
 
    TInt ret = iMain->UIStore().GetTestSetsList( aArray );
-  
+
+	if ( ret != KErrNone )
+		{
+		return ret;
+		}
+
    iFileList.ResetAndDestroy();
    TRAPD( err,
 	//Assign aArray to iFileList, it is used in LoadTestSet
@@ -4391,8 +4397,6 @@
                 {           
                 if(iPosOnScreen < iFileList.Count())
                     {
-                    const TDesC& aSetName = iFileList.operator [](iPosOnScreen)->Des();
-                
                     ret = iMain->UIStore().LoadTestSet( iFileList.operator [](iPosOnScreen)->Des() );
                     if (ret == KErrNone)
                         {
@@ -5692,4 +5696,5 @@
         }
     iTestCaseMenu = aTestCaseMenu;
     }
-// End of file
+
+// End of File
--- a/stif/DemoModule/src/DemoModule.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/DemoModule/src/DemoModule.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -591,5 +591,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/Logger/inc/DataLogger.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/inc/DataLogger.h	Thu Jul 22 16:50:07 2010 +0100
@@ -122,4 +122,4 @@
 
 #endif      // DATALOGGER_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/Logger/src/FileOutput.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/FileOutput.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1211,4 +1211,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Logger/src/HtmlLogger.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/HtmlLogger.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -567,4 +567,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Logger/src/LoggerOverFlow.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/LoggerOverFlow.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -293,4 +293,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Logger/src/NullOutput.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/NullOutput.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -229,4 +229,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Logger/src/Output.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/Output.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -240,4 +240,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Logger/src/RDebugOutput.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Logger/src/RDebugOutput.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -681,4 +681,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/Parser/inc/ParserTracing.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/inc/ParserTracing.h	Thu Jul 22 16:50:07 2010 +0100
@@ -43,5 +43,5 @@
 #endif
 
 #endif // STIFPARSERTRACING_H
-    
+
 // End of File
--- a/stif/Parser/inc/cstackdeprecated.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/inc/cstackdeprecated.h	Thu Jul 22 16:50:07 2010 +0100
@@ -52,3 +52,5 @@
 #pragma warning ( default : 4127 ) // conditional expression is constant
 
 #endif // __CSTACK_HDEPRECATED__
+
+// End of File
--- a/stif/Parser/inc/cstackdeprecated.inl	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/inc/cstackdeprecated.inl	Thu Jul 22 16:50:07 2010 +0100
@@ -103,3 +103,5 @@
 	
 
 #endif // __CSTACKDEPRECATED_INL__
+
+// End of File
--- a/stif/Parser/src/StifItemParser.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/src/StifItemParser.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1244,4 +1244,4 @@
 
 // ================= OTHER EXPORTED FUNCTIONS =================================
 
-//  End of File
+// End of File
--- a/stif/Parser/src/StifParser.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/src/StifParser.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -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,70 +862,30 @@
     {
     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() );
 
     }
 
-//  End of File
+// End of File
--- a/stif/Parser/src/StifSectionParser.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/Parser/src/StifSectionParser.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1104,4 +1104,4 @@
 
 // ================= OTHER EXPORTED FUNCTIONS =================================
 
-//  End of File
+// End of File
--- a/stif/SUEvent/inc/SUEvent.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/SUEvent/inc/SUEvent.h	Thu Jul 22 16:50:07 2010 +0100
@@ -314,4 +314,4 @@
 
 #endif      // SUEVENT_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/SUEvent/src/SUEvent.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/SUEvent/src/SUEvent.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -361,6 +361,4 @@
 
     }
 
-
-
-//  End of File
+// End of File
--- a/stif/SUEvent/src/SUEventCases.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/SUEvent/src/SUEventCases.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -309,4 +309,5 @@
 
     }
 */
-//  End of File
+
+// End of File
--- a/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -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/StifKernelTestClassBase/src/StifKernelTestClassBase.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifKernelTestClassBase/src/StifKernelTestClassBase.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -291,5 +291,4 @@
     
     }
 
-    
-//  End of File
+// End of File
--- a/stif/StifTFwIf/Bwins/STIFTFWIFU.DEF	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/Bwins/STIFTFWIFU.DEF	Thu Jul 22 16:50:07 2010 +0100
@@ -60,4 +60,5 @@
 	?ReadFiltersL@CUIStore@@QAEXAAV?$RPointerArray@VTDesC16@@@@@Z @ 59 NONAME ; void CUIStore::ReadFiltersL(class RPointerArray<class TDesC16> &)
 	?GetTestSetsList@CUIStore@@QAEHAAV?$RRefArray@VTDesC16@@@@@Z @ 60 NONAME ; int CUIStore::GetTestSetsList(class RRefArray<class TDesC16> &)
 	?SaveTestSet2@CUIStore@@QAEHAAVTDes16@@@Z @ 61 NONAME ; int CUIStore::SaveTestSet2(class TDes16 &)
+	?UnloadTestSet@CUIStore@@QAEHABVTDesC16@@@Z @ 62 NONAME ; int CUIStore::UnloadTestSet(class TDesC16 const &)
 
--- a/stif/StifTFwIf/eabi/StifTFwIfu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/eabi/StifTFwIfu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -99,4 +99,5 @@
 	_ZN8CUIStore12ReadFiltersLER13RPointerArrayI7TDesC16E @ 98 NONAME
 	_ZN8CUIStore15GetTestSetsListER9RRefArrayI7TDesC16E @ 99 NONAME
 	_ZN8CUIStore12SaveTestSet2ER6TDes16 @ 100 NONAME
+	_ZN8CUIStore13UnloadTestSetERK7TDesC16 @ 101 NONAME
 
--- a/stif/StifTFwIf/inc/UIEngineError.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIEngineError.h	Thu Jul 22 16:50:07 2010 +0100
@@ -135,5 +135,5 @@
     };
 
 #endif // UI_ENGINE_ERROR_H
-    
+
 // End of File
--- a/stif/StifTFwIf/inc/UIEngineEvent.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIEngineEvent.h	Thu Jul 22 16:50:07 2010 +0100
@@ -174,5 +174,5 @@
 
 
 #endif // STIF_TFW_IF_EVENT_H
-    
+
 // End of File
--- a/stif/StifTFwIf/inc/UIEnginePrinter.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIEnginePrinter.h	Thu Jul 22 16:50:07 2010 +0100
@@ -143,5 +143,5 @@
 
 
 #endif // STIF_TFW_IF_PRINTER_H
-    
+
 // End of File
--- a/stif/StifTFwIf/inc/UIEngineRemote.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIEngineRemote.h	Thu Jul 22 16:50:07 2010 +0100
@@ -161,5 +161,5 @@
 
 
 #endif // STIF_TFW_IF_REMOTE_H
-    
+
 // End of File
--- a/stif/StifTFwIf/inc/UIEngineRunner.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIEngineRunner.h	Thu Jul 22 16:50:07 2010 +0100
@@ -146,5 +146,5 @@
 
 
 #endif // STIF_TFW_IF_RUNNER_H
-    
+
 // End of File
--- a/stif/StifTFwIf/inc/UIStorePopup.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/inc/UIStorePopup.h	Thu Jul 22 16:50:07 2010 +0100
@@ -178,5 +178,5 @@
 
 
 #endif // STIF_TFW_IF_REMOTE_H
-    
+
 // End of File
--- a/stif/StifTFwIf/src/StifTFwIf.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/StifTFwIf.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1842,4 +1842,4 @@
     iMasterArray.Reset();
     }
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngine.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngine.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1307,4 +1307,4 @@
     
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngineContainer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngineContainer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -609,4 +609,4 @@
 
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngineError.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngineError.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -272,4 +272,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngineEvent.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngineEvent.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -478,4 +478,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEnginePrinter.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEnginePrinter.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -287,4 +287,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngineRemote.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngineRemote.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -415,4 +415,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIEngineRunner.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIEngineRunner.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -285,4 +285,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/StifTFwIf/src/UIStore.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIStore.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -46,7 +46,6 @@
 
 _LIT( KUIStoreSetStart, "[TestSetStart]" );
 _LIT( KUIStoreSetEnd, "[TestSetEnd]" );
-_LIT( KUIStoreSetName, "TestSetName=" );
 _LIT( KUIStoreSetCaseStart, "[TestSetCaseStart]" );
 _LIT( KUIStoreSetCaseEnd, "[TestSetCaseEnd]" );
 _LIT( KUIStoreCaseModuleName, "ModuleName=" );
@@ -1032,7 +1031,53 @@
 */ 
 EXPORT_C TInt CUIStore::RemoveTestSet( const TDesC& aSetName )
     {
-    
+    TInt err = UnloadTestSet( aSetName );
+    if ( err != KErrNone )
+        {
+        return err;
+        }
+    
+    TFileName setfile;
+    setfile.Append(KUIStoreDefaultDir);
+    setfile.Append(aSetName);
+    RFs fs;
+    err = fs.Connect();
+    if( err != KErrNone )
+        {
+        fs.Close();
+        return err;
+        }
+    err = fs.Delete( setfile );
+    if ( err != KErrNone )
+        {
+        fs.Close();
+        return err;    
+        }
+    
+    return KErrNone;   
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: CUIStore
+
+    Method: UnloadTestSet
+
+    Description: Unloads active test set.
+
+    Parameters: TDesC& aSetName: in: test set name (Max length is KMaxName)
+    
+    Return Values: Symbian OS error code
+
+    Errors/Exceptions: None
+
+    Status: Draft
+
+-------------------------------------------------------------------------------
+*/ 
+EXPORT_C TInt CUIStore::UnloadTestSet( const TDesC& aSetName )
+    {    
     TPtrC setName;
     TFileName tmp;
     TInt ret = ParseTestSetName( aSetName, setName, tmp );
@@ -1071,9 +1116,8 @@
         }
     
     delete setInfo;
-
-    return KErrNone;
-    
+    
+    return KErrNone;    
     }
 
 /*
@@ -1321,27 +1365,65 @@
 EXPORT_C TInt CUIStore::SaveTestSet2( TDes& aSetName )
     {
     
+    RRefArray<TDesC> testsets;
+    
+    GetTestSetsList(testsets);
+    TBool isexist(EFalse);
+    for(TInt i=0;i<testsets.Count();i++)
+    {
+       if(testsets[i]==aSetName)
+           {
+           isexist=ETrue;
+           break;
+           }
+    
+    }
+    testsets.Reset();
+    if(!isexist)
+    {
+        TTime current;
+        TDateTime date_rep;
+        current.HomeTime();
+        date_rep = current.DateTime();
+        TBuf<32> currSetName;
+        _LIT(f_ext,".set");
+        
+        //create "test set name" string
+        currSetName.AppendNum(date_rep.Year());
+        currSetName.Append('_');
+        currSetName.AppendNum(date_rep.Month()+1); // Incrimination necessary, because Day and Month fields of TDateTime class are 0 based
+        currSetName.Append('_');
+        currSetName.AppendNum(date_rep.Day()+1);
+        currSetName.Append('_');
+        currSetName.AppendNum(date_rep.Hour());
+        currSetName.Append('_');
+        currSetName.AppendNum(date_rep.Minute());
+        currSetName.Append('_');
+        currSetName.AppendNum(date_rep.Second());
+        currSetName.Append(f_ext);
+        
+        for(TInt i=0;i<iTestSets.Count();i++)
+        {
+            if(iTestSets[i]->Name()==aSetName)
+                {
+                iTestSets[i]->RenameTestSet(currSetName);
+                
+                }
+        
+        }
+        
+        
+        
+        aSetName.Zero();
+        aSetName.Copy(currSetName);
+       
+        
+    
+    }
     TPtrC setName;
     TFileName tmp;
 
-    TTime current;
-    TDateTime date_rep;
-    current.HomeTime();
-    date_rep = current.DateTime();
-    TBuf<32> currSetName;
-    _LIT(f_ext,".set");
-    
-    //create "test set name" string
-     currSetName.AppendNum(date_rep.Year());
-     currSetName.Append('_');
-     currSetName.AppendNum(date_rep.Month()+1); // Incrimination necessary, because Day and Month fields of TDateTime class are 0 based
-     currSetName.Append('_');
-     currSetName.AppendNum(date_rep.Day()+1);
-     currSetName.Append('_');
-     currSetName.AppendNum(date_rep.Hour());
-     currSetName.Append('_');
-     currSetName.AppendNum(date_rep.Minute());
-     currSetName.Append(f_ext);
+    
 
     TInt ret = ParseTestSetName( aSetName, setName, tmp );
     if( ret != KErrNone )
@@ -1357,10 +1439,10 @@
         }
      
     TRAPD( err,
-        SaveTestSetL( *setInfo, currSetName );
+        SaveTestSetL( *setInfo, aSetName );
         );
     
-    aSetName.Copy(currSetName);
+   
     
     return err;
     
@@ -1387,7 +1469,6 @@
 */
 EXPORT_C TInt CUIStore::LoadTestSet( const TDesC& aSetName )
     {
-    
     TPtrC setName;
     TFileName tmp;
     TInt ret = ParseTestSetName( aSetName, setName, tmp );
@@ -1395,8 +1476,28 @@
         {
         return ret;
         }
-        
-    TRAPD( err,
+    CTestSetInfo* setInfo= NULL;
+    
+    FindSetByName( setName, setInfo );
+    if(setInfo != NULL)
+        {
+        return KErrNone;
+        }
+    
+    TRAPD( err, 
+        setInfo = CTestSetInfo::NewL( aSetName );
+        );
+    if( err != KErrNone )
+        {
+        return err;
+        }
+    if( iTestSets.Append( setInfo ) != KErrNone )
+        {
+        delete setInfo;
+        return KErrNoMemory;
+        }
+
+    TRAP( err,
         LoadTestSetL( setName, aSetName );
         );
     
@@ -1848,7 +1949,7 @@
 
 -------------------------------------------------------------------------------
 */
-void CUIStore::LoadTestSetL( const TDesC& aSetName, const TDesC& aSetFileName )
+void CUIStore::LoadTestSetL( const TDesC& aSetName, const TDesC& /*aSetFileName*/ )
     {
     
     TPtrC tmp;
@@ -1856,15 +1957,8 @@
     TInt high;
     TInt64 interval;
     
-    CStifParser* parser = NULL;
-    
-    TRAPD( err,
-        parser = CStifParser::NewL( _L(""), aSetFileName );
-        );
-    if( err != KErrNone )
-        {
-        parser = CStifParser::NewL( KUIStoreDefaultDir, aSetName );
-        }
+    CStifParser* parser = CStifParser::NewL( KUIStoreDefaultDir, aSetName );
+
         
     CleanupStack::PushL( parser );
     
@@ -1872,24 +1966,8 @@
         parser->SectionL( KUIStoreSetStart, KUIStoreSetEnd );
     CleanupStack::PushL( section );
     
-    CStifItemParser* item = section->GetItemLineL( KUIStoreSetName );
-    CleanupStack::PushL( item );
-    
-    User::LeaveIfError( item->GetString( KUIStoreSetName, tmp ) );
-    
-	// get the standard method
-	TCollationMethod method = *Mem::CollationMethodByIndex(0);
-	// ignore case
-    method.iFlags |= TCollationMethod::EFoldCase;
-    
-	TInt compare = aSetName.CompareC( tmp, 3, &method );
-	if( compare != KErrNone )
-        {
-        User::LeaveIfError( KErrNotFound );
-        }
-        
-    CleanupStack::PopAndDestroy( item );
-        
+    CStifItemParser* item;
+
     // Get started test case (if possible)
     TUint lastStartedCaseIndex = 0;
     item = section->GetItemLineL(KUIStoreLastStartedCaseIndex);
@@ -1908,7 +1986,6 @@
         __TRACE(KInit, (_L("Could not find [%S] from test set file."), &KUIStoreLastStartedCaseIndex));
         }
 
-    User::LeaveIfError( CreateTestSet( aSetName ) );
     
     CTestSetInfo* setInfo = NULL;
     User::LeaveIfError( FindSetByName( aSetName, setInfo ) );
@@ -2048,8 +2125,6 @@
         // Saving
         buffer.Format(_L("%S"), &KUIStoreSetStart);
         WriteLineL(file, buffer);
-        buffer.Format(_L("%S %S"), &KUIStoreSetName,&aSetFileName);
-        WriteLineL(file, buffer);
 
         // Saving test set causes reset of index
         aSetInfo.SetLastStartedCaseIndex(0);
@@ -4737,6 +4812,31 @@
     return iLastStartedCaseIndex;
     }    
 
+/*
+-------------------------------------------------------------------------------
+
+    Class: CTestSetInfo
+
+    Method: RenameTestSet
+
+    Description:  rename test set
+        
+    Parameters: aTestSetName : new TestSetName
+
+    Return Values: TInt: KErrNone if success.
+
+    Errors/Exceptions: None
+
+    Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestSetInfo::RenameTestSet(const TDesC& aTestSetName)
+    {
+    delete iName;
+    iName=NULL;
+    iName=aTestSetName.AllocL();
+    }
 // ================= OTHER EXPORTED FUNCTIONS =================================
 
 // End of File
--- a/stif/StifTFwIf/src/UIStoreContainer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIStoreContainer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -902,5 +902,5 @@
     CleanupStack::PopAndDestroy( tmp );
     
     }
-    
+
 // End of File
--- a/stif/StifTFwIf/src/UIStorePopup.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/StifTFwIf/src/UIStorePopup.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -307,4 +307,4 @@
 // ================= OTHER EXPORTED FUNCTIONS ================================= 
 // None
 
-//  End of File
+// End of File
--- a/stif/TestCombiner/inc/StifPythonFunComb.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/StifPythonFunComb.h	Thu Jul 22 16:50:07 2010 +0100
@@ -43,4 +43,4 @@
 
 #endif        // STIFPYTHONFUNCOMB_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestCombiner/inc/TestCase.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/TestCase.h	Thu Jul 22 16:50:07 2010 +0100
@@ -207,8 +207,8 @@
                                   TDesC& aModuleName,
                                   TDesC& aTestId,
                                   TInt aExpectedResult,
-                                  TFullTestResult::TCaseExecutionResult
-                                        aCategory,
+                                  TFullTestResult::TCaseExecutionResult aCategory,
+                                  const TDesC& aTestCaseArguments,
                                   CTCTestModule* aModule ); //--PYTHON--
 
         /**
@@ -228,6 +228,11 @@
         const TDesC& ModuleName(){ return *iModuleName; }
 
         /**
+         * Get test case arguments
+         */
+        const TDesC& TestCaseArguments() const;
+        
+        /**
         * Get reference to RTestExecution.
         */
         RTestExecution& TestExecution(){ return iTestExecution; }
@@ -274,7 +279,7 @@
         /**
         * By default Symbian OS constructor is private.
         */
-        void ConstructL( TDesC& aModuleName, TDesC& aTestId );
+        void ConstructL( TDesC& aModuleName, TDesC& aTestId, const TDesC& aTestCaseArguments );
 
         /**
         * Start complete the testcase(Complete2 make the final complete).
@@ -298,6 +303,9 @@
         // Module name
         HBufC*                  iModuleName;
 
+        // Test case arguments
+        HBufC*                  iTestCaseArguments;
+        
         // Handle to test case execution
         RTestExecution          iTestExecution;
 
@@ -589,5 +597,5 @@
     };
     
 #endif        // TESTCASE_H  
-                
+
 // End of File
--- a/stif/TestCombiner/inc/TestCaseNotify.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/TestCaseNotify.h	Thu Jul 22 16:50:07 2010 +0100
@@ -526,6 +526,5 @@
     };
 
 #endif // TEST_CASE_NOTIFY_H
-     
-                
+
 // End of File
--- a/stif/TestCombiner/inc/TestCombinerEvent.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/TestCombinerEvent.h	Thu Jul 22 16:50:07 2010 +0100
@@ -132,5 +132,5 @@
     };
 
 #endif      // TESTCOMBINEREVENT_H
-            
+
 // End of File
--- a/stif/TestCombiner/inc/TestCombinerUtils.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/TestCombinerUtils.h	Thu Jul 22 16:50:07 2010 +0100
@@ -91,6 +91,11 @@
         */
         void SetTitleL(TDesC& aTitle);
 
+        /**
+         * Sets test case arguments.
+         */
+        void SetTestCaseArgumentsL( const TDesC& aTestCaseArguments );
+
     private:
         /**
         * C++ default constructor.
@@ -112,6 +117,7 @@
         TFullTestResult::TCaseExecutionResult iCategory;
         TInt    iTimeout;
         TPtrC   iTitle;
+		TPtrC   iTestCaseArguments;
         
     private:
         HBufC*  iModuleBuf;
@@ -119,7 +125,7 @@
         HBufC*  iConfigBuf;
         HBufC*  iTestIdBuf;
         HBufC*  iTitleBuf;
-    
+        HBufC*  iTestCaseArgumentsBuf;
     };
     
 // CLASS DECLARATION
@@ -239,5 +245,5 @@
     };
     
 #endif        // TESTCOMBINERUTILS_H
-                
-// End of File
\ No newline at end of file
+
+// End of File
--- a/stif/TestCombiner/inc/TestKeywords.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/inc/TestKeywords.h	Thu Jul 22 16:50:07 2010 +0100
@@ -82,6 +82,7 @@
             ECategory,
             ECaseTimeout,
             ECaseTitle,
+            EArgs,			
             };
 
         // pause keyword optional arguments
--- a/stif/TestCombiner/src/StifPythonFunComb.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/StifPythonFunComb.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -71,4 +71,4 @@
 //
 // ============================ MEMBER FUNCTIONS ===============================
 
-//  End of File
+// End of File
--- a/stif/TestCombiner/src/TestCase.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/TestCase.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -365,12 +365,13 @@
 */
 
 void CTCTestCase::ConstructL( TDesC& aModuleName,
-                              TDesC& aTestId )
+                              TDesC& aTestId,
+                              const TDesC& aTestCaseArguments )
     {
     __ASSERT_ALWAYS( aModuleName.Length() < KMaxFileName, User::Leave( KErrArgument ) );
     CTestCase::ConstructL( aTestId );
     iModuleName = aModuleName.AllocL();
-    
+    iTestCaseArguments = aTestCaseArguments.AllocL();
     }
 
 /*
@@ -397,8 +398,8 @@
                                 TDesC& aModuleName,
                                 TDesC& aTestId,
                                 TInt aExpectedResult,
-                                TFullTestResult::TCaseExecutionResult
-                                    aCategory,
+                                TFullTestResult::TCaseExecutionResult aCategory,
+                                const TDesC& aTestCaseArguments,
                                 CTCTestModule* aModule ) //--PYTHON
     {
     CTCTestCase* self = new (ELeave) CTCTestCase( testCombiner,
@@ -407,7 +408,7 @@
                                                    aModule ); //--PYTHON
      
     CleanupStack::PushL( self );
-    self->ConstructL( aModuleName, aTestId );
+    self->ConstructL( aModuleName, aTestId, aTestCaseArguments );
     CleanupStack::Pop();
     return self;
      
@@ -475,6 +476,7 @@
     
     delete iProgress;
     delete iModuleName;
+    delete iTestCaseArguments;
     
     delete iCommand;
     }
@@ -484,6 +486,34 @@
 
      Class: CTCTestCase
 
+     Method: TestCaseArguments
+
+     Description: Get test case arguments
+
+     Parameters: None.
+
+     Return Values: Test case arguments.
+
+     Errors/Exceptions: None.
+
+     Status: Proposal
+    
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTCTestCase::TestCaseArguments() const 
+    {
+    if ( iTestCaseArguments !=NULL ) 
+        {
+        return *iTestCaseArguments; 
+        }
+    return KNullDesC;
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+     Class: CTCTestCase
+
      Method: DoCancel
 
      Description: Derived from CActive, handles the Cancel.
@@ -1174,4 +1204,4 @@
 
     }
 
-//  End of File
+// End of File
--- a/stif/TestCombiner/src/TestCaseNotify.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/TestCaseNotify.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1492,7 +1492,7 @@
     {
     __TRACE(KMessage, (_L("CTestEventNotifier::StartL (combiner)")));
 
-    TInt res = iTestCase->TestExecution().NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone);
+    iTestCase->TestExecution().NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone);
     SetActive();
     }
 
--- a/stif/TestCombiner/src/TestCombiner.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/TestCombiner.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1652,6 +1652,7 @@
                            aStartInfo.iTestId, 
                            aStartInfo.iExpectedResult, 
                            aStartInfo.iCategory,
+                           aStartInfo.iTestCaseArguments,
                            module ); //--PYTHON--
 
     CleanupStack::PushL( tc );
@@ -1694,7 +1695,14 @@
          &aStartInfo.iTestId, &aStartInfo.iModule, &aStartInfo.iIniFile, 
          &aStartInfo.iConfig, aStartInfo.iCaseNum, aStartInfo.iExpectedResult );
 
-    tc->TestExecution().RunTestCase( tc->iResultPckg, tc->iStatus );
+    if ( tc->TestCaseArguments().Length() > 0 )
+        {
+        tc->TestExecution().RunTestCase( tc->iResultPckg, tc->TestCaseArguments(), tc->iStatus );
+        }
+    else
+        {
+        tc->TestExecution().RunTestCase( tc->iResultPckg, tc->iStatus );
+        }
 
     iRunningTests++;
 
@@ -3286,6 +3294,12 @@
                 aStartInfo.SetTitleL(val);
                 break;
            	    }
+            case TTCKeywords::EArgs:
+                {
+                __TRACE( KMessage, (_L("case arguments=%S"), &val));
+                aStartInfo.SetTestCaseArgumentsL( val );
+                }
+                break;				
             default:
 				{
                 __TRACE( KError, (_L("Unknown or illegal keyword")));
@@ -6602,6 +6616,4 @@
     return CTestCombiner::NewL();
     }
 
-
-
-//  End of File
+// End of File
--- a/stif/TestCombiner/src/TestCombinerUtils.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/TestCombinerUtils.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -86,7 +86,8 @@
     iIniFileBuf(0),
     iConfigBuf(0),
     iTestIdBuf(0),
-    iTitleBuf(0)
+    iTitleBuf(0),
+	iTestCaseArgumentsBuf(0)
     {
 
     iCategory = TFullTestResult::ECaseExecuted; 
@@ -177,6 +178,7 @@
     delete iConfigBuf;
     delete iTestIdBuf;
     delete iTitleBuf;
+	delete iTestCaseArgumentsBuf;
     }
 
 /*
@@ -355,6 +357,34 @@
 /*
 -------------------------------------------------------------------------------
 
+     Class: CStartInfo
+
+     Method: SetTestCaseArguments
+
+     Description: Sets test case arguments
+     
+     Parameters:  const TDesC& aTestCaseArguments: in: test case arguments.
+     
+     Return Values: None
+
+     Errors/Exceptions: None
+
+     Status: Proposal
+    
+-------------------------------------------------------------------------------
+*/        
+void CStartInfo::SetTestCaseArgumentsL( const TDesC& aTestCaseArguments )
+    {
+    delete iTestCaseArgumentsBuf;
+	iTestCaseArgumentsBuf = NULL;
+    iTestCaseArgumentsBuf = aTestCaseArguments.AllocL();
+	iTestCaseArguments.Set( iTestCaseArgumentsBuf->Des() );
+    }
+
+
+/*
+-------------------------------------------------------------------------------
+
     DESCRIPTION
 
     This module contains the implementation of CSlaveInfo class 
@@ -962,4 +992,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/TestCombiner/src/TestKeywords.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestCombiner/src/TestKeywords.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -139,6 +139,7 @@
         (TText*)L"category",
         (TText*)L"timeout",
         (TText*)L"title",
+        (TText*)L"args",
         };
 
     if( aArg >= (TInt)(sizeof( runOptArgs )/sizeof(TText*)) )
--- a/stif/TestEngine/BWINS/STIFTESTENGINEU.DEF	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/BWINS/STIFTESTENGINEU.DEF	Thu Jul 22 16:50:07 2010 +0100
@@ -61,4 +61,5 @@
 	?StoreEngineSettings@RSettingServer@@QAEHAAUTEngineSettings@@@Z @ 60 NONAME ; int RSettingServer::StoreEngineSettings(struct TEngineSettings &)
 	?GetFormatL@CSTIFTestFrameworkSettings@@QAEHPAVCStifSectionParser@@VTPtrC16@@AAW4TLoggerType@CStifLogger@@AAH@Z @ 61 NONAME ; int CSTIFTestFrameworkSettings::GetFormatL(class CStifSectionParser *, class TPtrC16, enum CStifLogger::TLoggerType &, int &)
 	?AddTestCaseResultToTestReport@RTestEngine@@QAEHABVTTestInfo@@ABVTFullTestResult@@H@Z @ 62 NONAME ; int RTestEngine::AddTestCaseResultToTestReport(class TTestInfo const &, class TFullTestResult const &, int)
+	?RunTestCase@RTestCase@@QAEXAAV?$TPckg@VTFullTestResult@@@@ABVTDesC16@@AAVTRequestStatus@@@Z @ 63 NONAME ; void RTestCase::RunTestCase(class TPckg<class TFullTestResult> &, class TDesC16 const &, class TRequestStatus &)
 
--- a/stif/TestEngine/eabi/StifTestEngineu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/eabi/StifTestEngineu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -110,4 +110,5 @@
 	_ZTV21CTestEngineSubSession @ 109 NONAME ; #<VT>#
 	_ZN26CSTIFTestFrameworkSettings10GetFormatLEP18CStifSectionParser7TPtrC16RN11CStifLogger11TLoggerTypeERi @ 110 NONAME
 	_ZN11RTestEngine29AddTestCaseResultToTestReportERK9TTestInfoRK15TFullTestResulti @ 111 NONAME
+	_ZN9RTestCase11RunTestCaseER5TPckgI15TFullTestResultERK7TDesC16R14TRequestStatus @ 112 NONAME
 
--- a/stif/TestEngine/inc/SettingServer.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/inc/SettingServer.h	Thu Jul 22 16:50:07 2010 +0100
@@ -301,5 +301,5 @@
     };
 
 #endif // SETTING_SERVER_H
-    
+
 // End of File
--- a/stif/TestEngine/inc/StifPythonFunEng.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/inc/StifPythonFunEng.h	Thu Jul 22 16:50:07 2010 +0100
@@ -43,4 +43,4 @@
 
 #endif        // STIFPYTHONFUNENG_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestEngine/inc/TestCaseController.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/inc/TestCaseController.h	Thu Jul 22 16:50:07 2010 +0100
@@ -176,6 +176,9 @@
         // Test Info
         TTestInfo           iTestInfo;
 
+        // Test case arguments
+		HBufC*              iTestCaseArguments;
+        
         // Internal state
         TTestCaseStatus     iState;
 
--- a/stif/TestEngine/inc/TestEngineCommon.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/inc/TestEngineCommon.h	Thu Jul 22 16:50:07 2010 +0100
@@ -56,4 +56,4 @@
 
 #endif // TEST_ENGINE_COMMON_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestEngine/inc/TestEngineEvent.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/inc/TestEngineEvent.h	Thu Jul 22 16:50:07 2010 +0100
@@ -142,4 +142,4 @@
 
 #endif      // TESTENGINEEVENT_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestEngine/src/STIFTestFrameworkSettings.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/STIFTestFrameworkSettings.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -669,4 +669,4 @@
 // ================= OTHER EXPORTED FUNCTIONS =================================
 // None
 
-//  End of File
+// End of File
--- a/stif/TestEngine/src/SettingServer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/SettingServer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -568,4 +568,4 @@
 
     }
 
-//  End of File
+// End of File
--- a/stif/TestEngine/src/SettingServerSession.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/SettingServerSession.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -947,4 +947,4 @@
     return KErrNone;
     }
 
-//  End of File
+// End of File
--- a/stif/TestEngine/src/StifPythonFunEng.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/StifPythonFunEng.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -70,4 +70,4 @@
 //
 // ============================ MEMBER FUNCTIONS ===============================
 
-//  End of File
+// End of File
--- a/stif/TestEngine/src/TestCaseController.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/TestCaseController.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -219,7 +219,7 @@
 
     delete iRDebugLogger;
     delete iTimeout;
-
+    delete iTestCaseArguments;
     }
 
 /*
@@ -253,10 +253,23 @@
 
     iState = ETestCaseRunning;
     
+    delete iTestCaseArguments;
+    iTestCaseArguments = NULL;
+    
+    TInt testCaseArgumentsLength = iMessage.GetDesLength( 1 );
+    if ( ( testCaseArgumentsLength != KErrArgument ) && ( testCaseArgumentsLength != KErrBadDescriptor ) )
+        {
+        iTestCaseArguments = HBufC::NewL( testCaseArgumentsLength );
+        TPtr testCaseArgumentsPtr( iTestCaseArguments->Des() );
+        User::LeaveIfError( iMessage.Read( 1, testCaseArgumentsPtr ) );
+        iTestExecution.RunTestCase( iResultPckg, *iTestCaseArguments, iStatus );        
+        }
+    else
+        {    
+        iTestExecution.RunTestCase( iResultPckg, iStatus );
+        }
     SetActive();
 
-    iTestExecution.RunTestCase( iResultPckg, iStatus );    
-
     // If testcase has timeout (handler), then start it
     if ( iTimeout )
         {
@@ -2771,7 +2784,7 @@
     {
     __TRACE(KVerbose, (_L("CTestEventNotifier::StartL")));
 
-    TInt res = iTestExecution.NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone);
+    iTestExecution.NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone);
     SetActive();
     }
 
--- a/stif/TestEngine/src/TestEngine.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/TestEngine.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -755,6 +755,15 @@
 */
 void CTestEngine::ConstructL( CTestEngineServer* aServer )
     {
+    // Log version info
+    TInt majorV;
+    TInt minorV;
+    TInt buildV;
+    TBuf<30> relDate;
+    TStifUtil::STIFVersion(majorV, minorV, buildV, relDate);
+    RDebug::Print(_L( "STIF startup... version %d.%d.%d (%S)"), majorV, minorV, buildV, &relDate);
+
+
     // Second-phase construct base class
     //CSession2::CreateL();
 
@@ -769,6 +778,7 @@
     // Initialize the object container from Server
     iContainer = iTestEngineServer->NewContainerL();
 
+    __TRACE(KInit, (_L( "STIF startup... version %d.%d.%d (%S)"), majorV, minorV, buildV, &relDate));
     __TRACE( KInit, ( _L( "CTestEngine::ConstructL: Test Engine Created" ) ) );
 
    
@@ -6201,5 +6211,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestEngine/src/TestEngineClient.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/TestEngineClient.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -661,6 +661,37 @@
 
     Class: RTestCase
 
+    Method: RunTestCase
+
+    Description: Run a test case asynchronously.
+
+    Parameters: TFullTestResultPckg& aTestResult : TFullTestResult :
+                 Test Result package
+                const TDesC& aTestCaseArgs: Test case arguments
+                TRequestStatus& aStatus : Request status
+
+    Return Values: TInt KErrNone : Test case could be run
+                        Other error code : Reason the test case couldn't be run
+
+    Errors/Exceptions: None
+
+    Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+EXPORT_C void RTestCase::RunTestCase( TFullTestResultPckg& aTestResult,
+                                      const TDesC& aTestCaseArgs,
+                                      TRequestStatus& aStatus )
+    {
+    TIpcArgs args( &aTestResult, &aTestCaseArgs, TIpcArgs::ENothing );
+    SendReceive( ETestCaseRunTestCase, args, aStatus );
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: RTestCase
+
     Method: Pause
 
     Description: Pause suspends the execution of the test case.
--- a/stif/TestEngine/src/TestModuleController.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/TestModuleController.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -3104,4 +3104,4 @@
 
 // None
 
-//  End of File
+// End of File
--- a/stif/TestEngine/src/TestReport.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestEngine/src/TestReport.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -125,6 +125,8 @@
 _LIT(KXMLTotalTagEnd,            "</Total>");
 _LIT(KXMLVersionTag,             "<Version>");
 _LIT(KXMLVersionTagEnd,          "</Version>");
+_LIT(KXMLSTIFVersionTag,         "<STIFVersion>");
+_LIT(KXMLSTIFVersionTagEnd,      "</STIFVersion>");
 
 // LOCAL CONSTANTS AND MACROS
 // None
@@ -614,6 +616,21 @@
         WriteLineL( _L( "%S" ), &date );
         WriteLineL( _L( "%S" ), &clock );
         }
+
+    // Add STIF version info
+    TInt majorV;
+    TInt minorV;
+    TInt buildV;
+    TBuf<30> relDate;
+    TStifUtil::STIFVersion(majorV, minorV, buildV, relDate);
+    if(iXML)
+        {
+        WriteLineL(_L("%S%d.%d.%d (%S)%S"), &KXMLSTIFVersionTag, majorV, minorV, buildV, &relDate, &KXMLSTIFVersionTagEnd);
+        }
+    else
+        {
+        WriteLineL(_L("v.%d.%d.%d (%S)"), majorV, minorV, buildV, &relDate);
+        }
     
     if ( iReportMode & ETestReportSummary )
         {
--- a/stif/TestInterface/BWINS/STIFTESTINTERFACEU.DEF	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestInterface/BWINS/STIFTESTINTERFACEU.DEF	Thu Jul 22 16:50:07 2010 +0100
@@ -137,4 +137,5 @@
 	?GetLocalValue@CScriptBase@@IAEHABVTDesC16@@AAH@Z @ 136 NONAME ; int CScriptBase::GetLocalValue(class TDesC16 const &, int &)
 	?GetLocalValue@CScriptBase@@IAEHABVTDesC16@@AAN@Z @ 137 NONAME ; int CScriptBase::GetLocalValue(class TDesC16 const &, double &)
 	?GetLocalValue@CScriptBase@@IAEHABVTDesC16@@AAVTDes16@@@Z @ 138 NONAME ; int CScriptBase::GetLocalValue(class TDesC16 const &, class TDes16 &)
+	?GetTestCaseArguments@CTestModuleIf@@QBEABVTDesC16@@XZ @ 139 NONAME ; class TDesC16 const & CTestModuleIf::GetTestCaseArguments(void) const
 
--- a/stif/TestInterface/eabi/StifTestInterfaceu.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestInterface/eabi/StifTestInterfaceu.def	Thu Jul 22 16:50:07 2010 +0100
@@ -183,4 +183,5 @@
 	_ZN11CScriptBase13SetLocalValueERK7TDesC16S2_ @ 182 NONAME
 	_ZN11CScriptBase13SetLocalValueERK7TDesC16d @ 183 NONAME
 	_ZN11CScriptBase13SetLocalValueERK7TDesC16i @ 184 NONAME
+	_ZNK13CTestModuleIf20GetTestCaseArgumentsEv @ 185 NONAME
 
--- a/stif/TestInterface/src/TestInterface.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestInterface/src/TestInterface.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -616,4 +616,5 @@
 	aBuildV = STIF_BUILD_VERSION;
 	aRelDate = TO_UNICODE(STIF_REL_DATE);
 	}
-//  End of File
+
+// End of File
--- a/stif/TestInterface/src/TestModuleIf.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestInterface/src/TestModuleIf.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1403,6 +1403,30 @@
 
     Class: CTestModuleIf
 
+    Method: GetTestCaseArguments
+
+    Description: Returns test case arguments.
+
+    Parameters: none
+
+    Return Values: test case arguments.
+
+    Errors/Exceptions: None
+
+    Status: proposal
+
+-------------------------------------------------------------------------------
+*/
+EXPORT_C const TDesC& CTestModuleIf::GetTestCaseArguments() const
+    {
+    return iTestExecution->GetTestCaseArguments();
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: CTestModuleIf
+
     Method: UITesting
 
     Description: Gets information if it is UI test or not
@@ -1719,4 +1743,4 @@
 
     }
 
-//  End of File
+// End of File
--- a/stif/TestInterference/src/StifTestInterference.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestInterference/src/StifTestInterference.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1996,4 +1996,4 @@
 // ========================== OTHER EXPORTED FUNCTIONS =========================
 // None
 
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXX.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXX.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -438,5 +438,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXXCases.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXXCases.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -268,3 +268,5 @@
     }
 */
 //  [End of File] - do not remove
+
+// End of File
--- a/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXX.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXX.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -121,4 +121,4 @@
 #undef STIFUNIT_OOMTESTFINALIZEL
 #endif
 
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXXCases.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXXCases.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -86,3 +86,5 @@
 /**
  * END OF TEST CASES SECTION
  */
+
+// End of File
--- a/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXX.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXX.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -79,5 +79,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXXBlocks.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXXBlocks.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -143,4 +143,4 @@
 // ========================== OTHER EXPORTED FUNCTIONS =========================
 // None
 
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXX.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXX.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -195,5 +195,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXXBlocks.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXXBlocks.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -160,3 +160,5 @@
 // None
 
 //  [End of File] - Do not remove
+
+// End of File
Binary file stif/TestModuleTemplates/TestModuleTemplates.zip has changed
--- a/stif/TestModuleTemplates/TestModuleXXX/src/TestModuleXXX.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestModuleTemplates/TestModuleXXX/src/TestModuleXXX.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -442,5 +442,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestScripter/src/TestScripter.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestScripter/src/TestScripter.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -3875,7 +3875,7 @@
         User::Leave( KErrArgument ); // Error in parsing => Leave    	
     	}
     // Convert idle time from milli to micro seconds
-   	idle = time * 1000.0;
+   	idle = static_cast<TInt>( time * 1000.0);
 
     if( idle < 0 )
     	{
@@ -3901,7 +3901,7 @@
     	}
     
     // Convert active time from milli to micro seconds
-   	active = time * 1000.0;
+   	active = static_cast<TInt>( time * 1000.0 );
    	
     if( active < 0 )
     	{
@@ -5166,5 +5166,4 @@
     
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestScripter/src/TestScripterInternal.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestScripter/src/TestScripterInternal.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -387,4 +387,4 @@
     return ret;
     }
 
-//  End of File
+// End of File
--- a/stif/TestServer/BWINS/STIFTESTSERVERU.DEF	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/BWINS/STIFTESTSERVERU.DEF	Thu Jul 22 16:50:07 2010 +0100
@@ -29,4 +29,5 @@
 	?StartNewServer@@YAHABV?$TBuf@$0BAA@@@AAV1@HVRSemaphore@@HPAVCTestThreadContainerRunnerFactory@@@Z @ 28 NONAME ; int StartNewServer(class TBuf<256> const &, class TBuf<256> &, int, class RSemaphore, int, class CTestThreadContainerRunnerFactory *)
 	?UITesting@CTestThreadContainer@@QAEHXZ @ 29 NONAME ; int CTestThreadContainer::UITesting(void)
 	?NotifyCommand2@RTestExecution@@QAEHAAV?$TPckg@W4TCommand@@@@AAVTDes8@@AAVTRequestStatus@@H@Z @ 30 NONAME ; int RTestExecution::NotifyCommand2(class TPckg<enum TCommand> &, class TDes8 &, class TRequestStatus &, int)
+	?RunTestCase@RTestExecution@@QAEXAAV?$TPckg@VTFullTestResult@@@@ABVTDesC16@@AAVTRequestStatus@@@Z @ 31 NONAME ; void RTestExecution::RunTestCase(class TPckg<class TFullTestResult> &, class TDesC16 const &, class TRequestStatus &)
 
--- a/stif/TestServer/eabi/StifTestServeru.def	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/eabi/StifTestServeru.def	Thu Jul 22 16:50:07 2010 +0100
@@ -60,4 +60,5 @@
 	_ZN14RTestExecution14NotifyCommand2ER5TPckgI8TCommandER5TDes8R14TRequestStatusi @ 59 NONAME
 	_ZTI11CCommandDef @ 60 NONAME ; #<TI>#
 	_ZTV11CCommandDef @ 61 NONAME ; #<VT>#
+	_ZN14RTestExecution11RunTestCaseER5TPckgI15TFullTestResultERK7TDesC16R14TRequestStatus @ 62 NONAME
 
--- a/stif/TestServer/inc/PrintQueue.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/inc/PrintQueue.h	Thu Jul 22 16:50:07 2010 +0100
@@ -188,4 +188,4 @@
 
 #endif  // PRINTQUEUE_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestServer/inc/TestServer.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/inc/TestServer.h	Thu Jul 22 16:50:07 2010 +0100
@@ -1681,5 +1681,5 @@
     };
 
 #endif // TEST_SERVER_H
-    
+
 // End of File
--- a/stif/TestServer/inc/TestServerCommon.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/inc/TestServerCommon.h	Thu Jul 22 16:50:07 2010 +0100
@@ -51,4 +51,4 @@
 
 #endif // TEST_SERVER_COMMON_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/TestServer/inc/TestServerEvent.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/inc/TestServerEvent.h	Thu Jul 22 16:50:07 2010 +0100
@@ -172,5 +172,5 @@
     };
 
 #endif      // TESTSERVEREVENT_H
-            
-// End of File
\ No newline at end of file
+
+// End of File
--- a/stif/TestServer/src/TestExecutionThread.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/TestExecutionThread.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -2141,7 +2141,7 @@
 
 -------------------------------------------------------------------------------
 */
-void CTestThreadContainer::IsServerAlive()
+void CTestThreadContainer::IsServerAlive() const
     {
         
     if( iServerThread.ExitType() != EExitPending ) 
@@ -2172,7 +2172,7 @@
 
 -------------------------------------------------------------------------------
 */
-CTestExecution& CTestThreadContainer::TestExecution()
+CTestExecution& CTestThreadContainer::TestExecution() const
     { 
     
     IsServerAlive();
@@ -2184,7 +2184,32 @@
     return *execution;
     
     };
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: CTestThreadContainer
+
+    Method: GetTestCaseArguments
+
+    Description: Get test case arguments
+
+    Parameters: None
     
+    Return Values: test case arguments
+
+    Errors/Exceptions: 
+
+    Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTestThreadContainer::GetTestCaseArguments() const
+    {
+    return TestExecution().GetTestCaseArguments();
+    }
+
+
 /*
 -------------------------------------------------------------------------------
 
@@ -2864,4 +2889,4 @@
 	return iModuleContainer->GetTestModule()->GetTestServer()->GetUiEnvProxy();
 	}
 
-//  End of File
+// End of File
--- a/stif/TestServer/src/TestServer.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/TestServer.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -973,5 +973,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/TestServer/src/TestServerClient.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/TestServerClient.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -827,6 +827,36 @@
 
     Class: RTestExecution
 
+    Method: RunTestCase
+
+    Description: Runs a test case
+
+    Parameters: TFullTestResultPckg& aResult  :out: Case result
+                const TDesC& aTestCaseArgs: Test case arguments
+                TRequestStatus& aStatus       :out: Request to be completed
+
+    Return Values: None
+
+    Errors/Exceptions: None
+
+    Status: Approved
+    
+-------------------------------------------------------------------------------
+*/
+EXPORT_C void RTestExecution::RunTestCase( TFullTestResultPckg& aResult,
+                                           const TDesC& aTestCaseArgs,
+                                           TRequestStatus& aStatus 
+                                         )
+    {
+    TIpcArgs args( &aResult, &aTestCaseArgs, TIpcArgs::ENothing );
+    SendReceive( ETestExecutionRunTestCase, args, aStatus );
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: RTestExecution
+
     Method: NotifyProgress
 
     Description: Notify about test case progress, i.e test case prints.
--- a/stif/TestServer/src/TestServerEvent.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/TestServerEvent.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -405,4 +405,4 @@
     
     } 
 
-//  End of File
+// End of File
--- a/stif/TestServer/src/TestThreadContainerRunner.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/TestThreadContainerRunner.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -531,6 +531,8 @@
 		    delete iTestThreadContainer;
 			}
 			break;
+		case ENone:
+			break;
 		}
 		
 	iCurrentOperation = ENone;
--- a/stif/TestServer/src/Testexecution.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/Testexecution.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -191,7 +191,10 @@
     // Delete name buffer
     delete iConfigNameBuffer;
     iConfigNameBuffer = NULL;
-    
+
+    delete iTestCaseArgs;
+    iTestCaseArgs = NULL;
+        
     iStateEvents.ResetAndDestroy();
     iStateEvents.Close();
 
@@ -338,15 +341,51 @@
 
     __TRACE ( KInit, ( _L( "CTestExecution::RunTestCase in" ) ) );
 
+    TInt ret = KErrNone;
+    
     // Store message to be completed when case is finished
     iTestExeMessage = aMessage;
 
     iFullResult.iStartTime.HomeTime();
 
+    delete iTestCaseArgs;
+    iTestCaseArgs = NULL;
+    
+    TInt testCaseArgsLength = iTestExeMessage.GetDesLength( 1 );
+    if ( ( testCaseArgsLength != KErrArgument ) && ( testCaseArgsLength != KErrBadDescriptor ) )
+        {
+        iTestCaseArgs = HBufC::New( testCaseArgsLength );
+        if ( iTestCaseArgs == NULL )
+            {
+            _LIT(KRunError,"Can't allocate memory for test case arguments");
+            __TRACE ( KError, ( CStifLogger::ERed, KRunError() ) );
+            CompleteTestExecution( KErrNone,
+                                   TFullTestResult::ECaseException,
+                                   KErrNoMemory,
+                                   KErrGeneral,
+                                   KRunError );
+            return KErrNone;        
+            }
+            
+        TPtr testCaseArgsPtr( iTestCaseArgs->Des() );
+        TRAP( ret, iTestExeMessage.Read( 1, testCaseArgsPtr ) );
+        if ( ret != KErrNone )
+            {
+            _LIT(KRunError,"Can't read test case arguments");
+            __TRACE ( KError, ( CStifLogger::ERed, KRunError() ) );
+            CompleteTestExecution( KErrNone,
+                                   TFullTestResult::ECaseException,
+                                   ret,
+                                   KErrGeneral,
+                                   KRunError );
+            return KErrNone;
+            }
+        }
+
     // Get a test module, which executes the test case.
     // The test module will be freed either when the test case
     // completes, or the test case is aborted.
-    TInt ret = iModuleSession->GetTestModule( iModuleContainer, iConfig );
+    ret = iModuleSession->GetTestModule( iModuleContainer, iConfig );
     if ( ret != KErrNone || iModuleContainer == NULL )
         {
         _LIT(KRunError,"Can't get test module");
@@ -2117,6 +2156,34 @@
 
     Class: CTestExecution
 
+    Method: GetTestCaseArguments
+
+    Description: Get test case arguments
+
+    Parameters: None
+
+    Return Values: Test case arguments
+
+    Errors/Exceptions: None
+
+    Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTestExecution::GetTestCaseArguments() const
+    {
+    if ( iTestCaseArgs != NULL )
+        {
+        return *iTestCaseArgs;
+        }
+    return KNullDesC;
+    }
+
+/*
+-------------------------------------------------------------------------------
+
+    Class: CTestExecution
+
     Method: CancelTestRequest
 
     Description: Cancel test execution request.
@@ -4751,4 +4818,4 @@
 
 	}
 
-//  End of File
+// End of File
--- a/stif/TestServer/src/Testserversession.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TestServer/src/Testserversession.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -1670,6 +1670,4 @@
     return iTestServer;
     }
 
-
-
-//  End of File
+// End of File
--- a/stif/TouchConsoleUI/group/TouchConsoleUI.mmp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TouchConsoleUI/group/TouchConsoleUI.mmp	Thu Jul 22 16:50:07 2010 +0100
@@ -21,10 +21,10 @@
 
 TARGET          TouchConsoleUI.exe
 TARGETTYPE      exe
-
+UID			 0 0x2002C347
 CAPABILITY	AllFiles CommDD
-VENDORID 	0x101FB657
-SECUREID    0x102073DA
+//VENDORID 	0x101FB657
+//SECUREID    0x102073DA
 
 USERINCLUDE     ../inc
 USERINCLUDE     ../../inc
--- a/stif/TouchConsoleUI/inc/CallBack.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TouchConsoleUI/inc/CallBack.h	Thu Jul 22 16:50:07 2010 +0100
@@ -207,5 +207,5 @@
     };
 
 #endif      // CALLBACK_H  
-            
+
 // End of File
--- a/stif/TouchConsoleUI/inc/ConsoleMenus.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TouchConsoleUI/inc/ConsoleMenus.h	Thu Jul 22 16:50:07 2010 +0100
@@ -1237,6 +1237,7 @@
 _LIT( KSetLoad,         "Load test set" );
 
 _LIT( KSetShow,         "Show started test sets" );
+_LIT( KSetUnload,       "Unload test set" );
 _LIT( KSetRemove,       "Remove test set" );
 _LIT( KSetCaseAdd,      "Add test case to test set" );
 _LIT( KSetCaseRemove,   "Remove test case from test set" );
@@ -1271,7 +1272,8 @@
             ESetStartSeq,
             ESetStartPar,
             //ESetStartRep,
- 
+
+            ESetUnload, 
             ESetRemove,
             ESetSave,
             ESetCaseAdd,
--- a/stif/TouchConsoleUI/src/Consolemenus.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/TouchConsoleUI/src/Consolemenus.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -3884,6 +3884,10 @@
             {
             return KErrNoMemory;
             }
+        if( aArray.Append( KSetUnload ) != KErrNone )
+            {
+            return KErrNoMemory;
+            }                        			
         if( aArray.Append( KSetRemove ) != KErrNone )
             {
             return KErrNoMemory;
@@ -3992,7 +3996,7 @@
 */
 CMenu* CTestSetMenu::SelectL( TKeyCode aSelection, TBool& aContinue )
     {
-    TBuf<32> currSetName;
+    
     MapKeyCode(aSelection);    
     
     if( ( aSelection != EKeyRightArrow ) &&
@@ -4034,11 +4038,19 @@
                                         this, 
                                         _L("Started test sets menu"));
                 return iSubMenu;
+            case ESetUnload:
+                ret = iMain->UIStore().UnloadTestSet( iTestSetName );
+                if( ret != KErrNone )
+                    {
+                    User::InfoPrint( _L("Test set unload failed") );
+                    }
+                iTestSetCreated = EFalse;                  
+                break;
             case ESetRemove: 
                 ret = iMain->UIStore().RemoveTestSet( iTestSetName );
                 if( ret != KErrNone )
                     {
-                    User::InfoPrint( _L("Test set creation failed") );
+                    User::InfoPrint( _L("Test set remove failed") );
                     }
                 iTestSetCreated = EFalse;  
                 break;
@@ -4064,28 +4076,11 @@
                                 
                 return iSubMenu;  
             case ESetSave: 
-                // during the save operation default set name (ConsoleUI.set) is replaced with
-                // new name created base on current date.
-                // Set is the reloaded to make sure that 
-                // old test set with default name will not affect test execution
-                currSetName.Copy( iTestSetName );
                 ret = iMain->UIStore().SaveTestSet2( iTestSetName );
                 if( ret != KErrNone )
                     {
-                    User::InfoPrint( _L("Test set saving failed at saving test set") );
-                    } 
-                
-                ret = iMain->UIStore().RemoveTestSet( currSetName );
-                if( ret != KErrNone )
-                    {
-                    User::InfoPrint( _L("Test set saving failed at removing old test set") );
-                    }             
-                
-                ret = iMain->UIStore().LoadTestSet( iTestSetName );
-                if( ret != KErrNone )
-                    {
-                    User::InfoPrint( _L("Test set saving failed at reloding test set") );
-                    }    
+                    User::InfoPrint( _L("Test set saving failed") );
+                    }   
                 break;
   
   			default:          
@@ -5697,4 +5692,5 @@
         }
     iTestCaseMenu = aTestCaseMenu;
     }
-// End of file
+
+// End of File
--- a/stif/examples/STIFTestMeasurementStub/inc/STIFTestMeasurementStub.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/examples/STIFTestMeasurementStub/inc/STIFTestMeasurementStub.h	Thu Jul 22 16:50:07 2010 +0100
@@ -153,4 +153,4 @@
 
 #endif      // STIFTESTMEASUREMENTSTUB_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/examples/STIFTestMeasurementStub/src/STIFTestMeasurementStub.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/examples/STIFTestMeasurementStub/src/STIFTestMeasurementStub.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -179,5 +179,4 @@
 
     }
 
-
-//  End of File
+// End of File
--- a/stif/examples/StifHWResetStub/inc/StifHWResetStub.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/examples/StifHWResetStub/inc/StifHWResetStub.h	Thu Jul 22 16:50:07 2010 +0100
@@ -127,4 +127,4 @@
 
 #endif // STIFHWRESETSTUB_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/examples/StifHWResetStub/src/StifHWResetStub.cpp	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/examples/StifHWResetStub/src/StifHWResetStub.cpp	Thu Jul 22 16:50:07 2010 +0100
@@ -322,5 +322,4 @@
 
     }
 
-
 // End of File
--- a/stif/group/ReleaseNote.txt	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/group/ReleaseNote.txt	Thu Jul 22 16:50:07 2010 +0100
@@ -1,5 +1,5 @@
 ========================================================================
-RELEASE NOTE FOR STIF - STIF_201016 (7.3.31)
+RELEASE NOTE FOR STIF - STIF_201024 (7.3.35)
 SUPPORTING SERIES 60 3.0 ->
 ========================================================================
 
--- a/stif/inc/StifKernelTestClass.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/StifKernelTestClass.h	Thu Jul 22 16:50:07 2010 +0100
@@ -108,4 +108,4 @@
 
 #endif      // STIFKERNELTESTCLASS_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/inc/StifKernelTestClass.inl	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/StifKernelTestClass.inl	Thu Jul 22 16:50:07 2010 +0100
@@ -75,5 +75,5 @@
     }
 
 #endif      // STIFKERNELTESTCLASS_INL
-            
-// End of File
\ No newline at end of file
+
+// End of File
--- a/stif/inc/StifPython.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/StifPython.h	Thu Jul 22 16:50:07 2010 +0100
@@ -45,4 +45,4 @@
 
 #endif        // STIFPYTHON_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/inc/TestModuleInfo.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/TestModuleInfo.h	Thu Jul 22 16:50:07 2010 +0100
@@ -289,4 +289,4 @@
 
 #endif      // TESTMODULEINFO_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/inc/TestServerModuleIf.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/TestServerModuleIf.h	Thu Jul 22 16:50:07 2010 +0100
@@ -415,6 +415,11 @@
         */
         TInt CancelCommandRequest();
 
+        /**
+         * Get test case arguments.
+         */
+        const TDesC& GetTestCaseArguments() const;
+
     public: // Functions that are called from test thread
 
         /**
@@ -574,6 +579,8 @@
         TInt iCaseNumber;                        // Case to be executed
         TPtr iConfig;                            // Configuration file name
         HBufC* iConfigNameBuffer;                // HBuffer for configuration file;
+        HBufC* iTestCaseArgs;                    // HBuffer for test case arguments
+		
         RMessage2 iTestExeMessage;               // Test execution message
         TTestState iThreadState;                 // Thread state
 
--- a/stif/inc/TestThreadContainer.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/TestThreadContainer.h	Thu Jul 22 16:50:07 2010 +0100
@@ -222,9 +222,15 @@
         virtual void DoNotifyCommand(TCommand aCommand, const TDesC8& aParamsPckg);
 
         /**
+         * Get test case execution arguments
+         */
+        virtual const TDesC& GetTestCaseArguments() const;        
+        
+        
+        /**
         * Obtain title of currently running test case.
         */
-        virtual void GetTestCaseTitleL(TDes& aTestCaseTitle);
+        virtual void GetTestCaseTitleL(TDes& aTestCaseTitle);        
 
         /**
          * Sets thread logger.
@@ -308,7 +314,7 @@
         /**
         * Check that server is alive.
         */ 
-        void IsServerAlive();
+        void IsServerAlive() const;
 
         /**
         * Exception handler
@@ -360,13 +366,17 @@
         /** 
         * C++ default constructor.
         */
-        CTestThreadContainer( CTestModuleContainer* aModuleContainer );
-                              
+        CTestThreadContainer( CTestModuleContainer* aModuleContainer );                              
+
+        /**
+         * Get module container.
+         */
+        CTestModuleContainer& ModuleContainer();        
+
         /**
         * Handles to parent.
         */
-        CTestExecution& TestExecution();
-        CTestModuleContainer& ModuleContainer();
+        CTestExecution& TestExecution() const;
         
     public:     // Data
         
@@ -433,5 +443,5 @@
     };
 
 #endif // TEST_THREAD_CONTAINER_H
-    
+
 // End of File
--- a/stif/inc/version.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/inc/version.h	Thu Jul 22 16:50:07 2010 +0100
@@ -20,10 +20,12 @@
 
 #define STIF_MAJOR_VERSION 7
 #define STIF_MINOR_VERSION 3
-#define STIF_BUILD_VERSION 31
+#define STIF_BUILD_VERSION 35
 
-#define STIF_REL_DATE "19th Apr 2010"
+#define STIF_REL_DATE "15th June 2010"
 
 #define TO_UNICODE(text) _L(text) 
 
 #endif /*VERSION_H_*/
+
+// End of File
Binary file stif/sis/Stif_31.sis has changed
--- a/stif/stif_plat/inc/NormalHardcodedAssert.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/NormalHardcodedAssert.h	Thu Jul 22 16:50:07 2010 +0100
@@ -242,3 +242,5 @@
 	}
 
 #endif
+
+// End of File
--- a/stif/stif_plat/inc/StifItemParser.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifItemParser.h	Thu Jul 22 16:50:07 2010 +0100
@@ -287,4 +287,4 @@
 
 #endif      // STIF_ITEM_PARSER_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/stif_plat/inc/StifKernelTestClassBase.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifKernelTestClassBase.h	Thu Jul 22 16:50:07 2010 +0100
@@ -145,5 +145,5 @@
     };
 
 #endif      // STIFKERNELTESTCLASSBASE_H
-            
-// End of File
\ No newline at end of file
+
+// End of File
--- a/stif/stif_plat/inc/StifSectionParser.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifSectionParser.h	Thu Jul 22 16:50:07 2010 +0100
@@ -283,4 +283,4 @@
 
 #endif      // STIF_SECTION_PARSER_H
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/stif_plat/inc/StifTFwIf.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifTFwIf.h	Thu Jul 22 16:50:07 2010 +0100
@@ -276,4 +276,4 @@
 
 #endif      // STIF_TFW_IF_H 
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/stif_plat/inc/StifTestEventInterface.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifTestEventInterface.h	Thu Jul 22 16:50:07 2010 +0100
@@ -180,5 +180,5 @@
 typedef TPckg<TEventIf> TEventIfPckg;
  
 #endif      // TESTEVENTINTERFACE_H
-            
-// End of File
\ No newline at end of file
+
+// End of File
--- a/stif/stif_plat/inc/StifTestModule.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifTestModule.h	Thu Jul 22 16:50:07 2010 +0100
@@ -787,6 +787,11 @@
         TInt Command(TCommand aCommand, const TDesC8& aParamsPckg);
 
         /**
+         * Get test case execution arguments
+         */
+        IMPORT_C const TDesC& GetTestCaseArguments() const;        
+
+        /**
         * GetTestCaseTitleL function is used to obtain test case title.
         */
         IMPORT_C void GetTestCaseTitleL(TDes& aTestCaseTitle);
--- a/stif/stif_plat/inc/StifUnitMacros.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifUnitMacros.h	Thu Jul 22 16:50:07 2010 +0100
@@ -213,3 +213,5 @@
 #include <StifUnitUtils.inl>
 
 #endif
+
+// End of File
--- a/stif/stif_plat/inc/StifUnitUtils.inl	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/StifUnitUtils.inl	Thu Jul 22 16:50:07 2010 +0100
@@ -91,8 +91,5 @@
 		}
 	return ETrue;
 	}
-	
 
-
-
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/stif_plat/inc/TestEngineClient.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/TestEngineClient.h	Thu Jul 22 16:50:07 2010 +0100
@@ -376,6 +376,19 @@
                                     TRequestStatus& aStatus );
 
         /**
+        * RunTestCase is asynchronous method and it is completed when the test
+        * case is completed. Result of the test case is returned to 
+        * aTestResult. The aTestResult is TFullTestResultPckg that is a
+        * packaged TFullTestResult.
+        * The aStatus will have the completion result of this function. If the
+        * test case could be run (despite of succesfully or not) the KErrNone 
+        * is returned to aStatus.
+        */
+        IMPORT_C void RunTestCase( TFullTestResultPckg& aTestResult,
+                                   const TDesC& aTestCaseArgs,
+                                   TRequestStatus& aStatus );        
+
+        /**
         * Pause suspends the execution of the test case. The subsession where
         * the test case is run is suspended and thus the test case execution is
         * suspended. Test case execution can be later resumed by calling 
--- a/stif/stif_plat/inc/TestEngineClient.inl	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/TestEngineClient.inl	Thu Jul 22 16:50:07 2010 +0100
@@ -300,4 +300,4 @@
 
 #endif      // TEST_ENGINE_CLIENT_INL
 
-// End of File
\ No newline at end of file
+// End of File
--- a/stif/stif_plat/inc/TestServerClient.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/TestServerClient.h	Thu Jul 22 16:50:07 2010 +0100
@@ -351,6 +351,16 @@
                                    TRequestStatus& aStatus );
 
         /**
+       * RunTestCase is used to execute the test case previously initialized by
+       * Open method. RunTestCase is asynchronous method and it is completed
+       * when the test case is completed.
+       * The result of the test case is returned to aStatus.
+       */
+       IMPORT_C void RunTestCase( TFullTestResultPckg& aResult,
+                                  const TDesC& aTestCaseArgs,
+                                  TRequestStatus& aStatus );
+
+        /**
         * Pause suspends the execution of the test case. The subsession where
         * the test case is run will be suspended and thus the test case
         * execution is suspended. The test case execution can be later resumed
@@ -460,6 +470,5 @@
     
 
 #endif // TEST_SERVER_CLIENT_H
-    
-            
+
 // End of File
--- a/stif/stif_plat/inc/TestThreadContainerRunnerFactory.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/TestThreadContainerRunnerFactory.h	Thu Jul 22 16:50:07 2010 +0100
@@ -144,3 +144,5 @@
 
 
 #endif /*TESTTHREADCONTAINERRUNNERFACTORY_H_*/
+
+// End of File
--- a/stif/stif_plat/inc/TestclassAssert.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/TestclassAssert.h	Thu Jul 22 16:50:07 2010 +0100
@@ -227,3 +227,5 @@
 	}
 
 #endif
+
+// End of File
--- a/stif/stif_plat/inc/UIEngineContainer.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/UIEngineContainer.h	Thu Jul 22 16:50:07 2010 +0100
@@ -239,5 +239,5 @@
 
 
 #endif      // STIF_TFW_IF_CONTAINER_H 
-            
+
 // End of File
--- a/stif/stif_plat/inc/UIStore.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/UIStore.h	Thu Jul 22 16:50:07 2010 +0100
@@ -268,6 +268,14 @@
         IMPORT_C TInt LoadTestSet( const TDesC& aSetName );
 
         /**
+        * Unload active test set.
+        *
+        * Returns Symbian OS error code.
+        */
+        IMPORT_C TInt UnloadTestSet( const TDesC& aSetName );
+        
+        
+        /**
         * Load saved test cases.
         *
         * Returns Symbian OS error code.
--- a/stif/stif_plat/inc/UIStoreIf.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/UIStoreIf.h	Thu Jul 22 16:50:07 2010 +0100
@@ -221,6 +221,10 @@
         * Gets the info which test case has been started lately.
         */
         TUint GetLastStartedCaseIndex(void);
+        /**
+        * rename test set
+        */
+        void RenameTestSet(const TDesC& aTestSetName);
                 
     public: // Functions from base classes
 
--- a/stif/stif_plat/inc/atslogger.h	Mon Jun 21 22:45:06 2010 +0100
+++ b/stif/stif_plat/inc/atslogger.h	Thu Jul 22 16:50:07 2010 +0100
@@ -577,3 +577,5 @@
 };
 
 #endif// End of File
+
+// End of File