sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/ui/MainView.java
changeset 1 1050670c6980
child 6 f65f740e69f9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/ui/MainView.java	Thu Feb 11 15:22:14 2010 +0200
@@ -0,0 +1,3283 @@
+/*
+ * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:  Definitions for the class MainView
+ *
+ */
+
+package com.nokia.s60tools.analyzetool.ui;
+
+import java.io.FileInputStream;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.ViewPart;
+
+import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
+import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration;
+import com.nokia.carbide.cdt.builder.project.ICarbideProjectInfo;
+import com.nokia.s60tools.analyzetool.Activator;
+import com.nokia.s60tools.analyzetool.AnalyzeToolHelpContextIDs;
+import com.nokia.s60tools.analyzetool.builder.BuilderUtil;
+import com.nokia.s60tools.analyzetool.engine.AnalysisItem;
+import com.nokia.s60tools.analyzetool.engine.AnalyzeFactory;
+import com.nokia.s60tools.analyzetool.engine.CallstackItem;
+import com.nokia.s60tools.analyzetool.engine.EpocReader;
+import com.nokia.s60tools.analyzetool.engine.IMemoryActivityModel;
+import com.nokia.s60tools.analyzetool.engine.MMPInfo;
+import com.nokia.s60tools.analyzetool.engine.ParseAnalyzeData;
+import com.nokia.s60tools.analyzetool.engine.ParseXMLFileSAX;
+import com.nokia.s60tools.analyzetool.engine.ProjectResults;
+import com.nokia.s60tools.analyzetool.engine.RunResults;
+import com.nokia.s60tools.analyzetool.engine.UseAtool;
+import com.nokia.s60tools.analyzetool.engine.statistic.ProcessInfo;
+import com.nokia.s60tools.analyzetool.engine.statistic.ReadFile;
+import com.nokia.s60tools.analyzetool.global.Constants;
+import com.nokia.s60tools.analyzetool.global.Util;
+import com.nokia.s60tools.analyzetool.internal.ui.graph.ChartContainer;
+import com.nokia.s60tools.analyzetool.ui.actions.DropDownMenu;
+import com.nokia.s60tools.analyzetool.ui.actions.FileActionHistory;
+import com.nokia.s60tools.analyzetool.ui.statistic.StatisticView;
+
+/**
+ * Class to display memory analysis results also provides all the
+ * functionalities what AnalyzeTool has.
+ *
+ * @author kihe
+ *
+ */
+public class MainView extends ViewPart implements ISelectionListener,
+		ITreeViewerListener, IActionListener, ISelectionChangedListener, KeyListener {
+
+	/**
+	 * Sorts tree view objects.
+	 *
+	 * @author kihe
+	 */
+	public static class NameSorter extends ViewerSorter {
+
+		/**
+		 * Compares view items.
+		 *
+		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
+		 *      java.lang.Object, java.lang.Object)
+		 *
+		 * @param viewer
+		 *            Viewer
+		 * @param e1
+		 *            Object
+		 * @param e2
+		 *            Object
+		 * @return int Always return 0
+		 */
+		@Override
+		public int compare(final Viewer viewer, final Object e1, final Object e2) {
+			return 0;
+		}
+	}
+
+	/**
+	 * The content provider class is responsible for providing objects to the
+	 * view. It can wrap existing objects in adapters or simply return objects
+	 * as-is. These objects may be sensitive to the current input of the view,
+	 * or ignore it and always show the same content (like Task List, for
+	 * example).
+	 */
+	class ViewContentProvider implements ITreeContentProvider {
+
+		/**
+		 *
+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+		 */
+		public void dispose() {
+			// MethodDeclaration/Block[count(BlockStatement) = 0 and
+			// @containsComment = 'false']
+		}
+
+		/**
+		 *
+		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+		 */
+		public Object[] getChildren(Object parent) {
+			if (parent instanceof TreeParent) {
+				return ((TreeParent) parent).getChildren();
+			}
+			return new Object[0];
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+		 */
+		public Object[] getElements(Object parent) {
+			if (parent.equals(getViewSite())) {
+				if (invisibleRoot == null) {
+					getStartupContent();
+				}
+				return getChildren(invisibleRoot);
+			}
+			return getChildren(parent);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+		 */
+		public Object getParent(Object child) {
+			if (child instanceof TreeObject) {
+				return ((TreeObject) child).getParent();
+			}
+			return null;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+		 */
+		public boolean hasChildren(Object parent) {
+			if (parent instanceof TreeParent) {
+				return ((TreeParent) parent).hasChildren();
+			}
+			return false;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
+		 *      java.lang.Object, java.lang.Object)
+		 */
+		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+			// MethodDeclaration/Block[count(BlockStatement) = 0 and
+			// @containsComment = 'false']
+		}
+
+	}
+
+	/**
+	 * Provides elements of tree view.
+	 *
+	 * @author kihe
+	 *
+	 */
+	public class ViewLabelProvider extends LabelProvider {
+
+		/**
+		 * Used when tree model item is TreeParent.
+		 */
+		private final Image folder;
+
+		/**
+		 * Default element only used to show error situations.
+		 */
+		private final Image element;
+
+		/**
+		 * Used when tree model item is part of the module which is build with
+		 * AnalyzeTool.
+		 */
+		private final Image build;
+
+		/**
+		 * Used when tree model item is part of the project but not build with
+		 * with AnalyzeTool.
+		 */
+		private final Image notBuild;
+
+		/**
+		 * Used when tree model item is outside of the project modules.
+		 */
+		public Image outside;
+
+		/**
+		 * Constructor. Created all the images which is used in the AnalyzeTool
+		 * tree model.
+		 */
+		public ViewLabelProvider() {
+			// create images
+			folder = PlatformUI.getWorkbench().getSharedImages().getImage(
+					ISharedImages.IMG_OBJ_FOLDER);
+			element = PlatformUI.getWorkbench().getSharedImages().getImage(
+					ISharedImages.IMG_OBJ_ELEMENT);
+			build = Activator.getImageDescriptor(Constants.ICON_BUILD)
+					.createImage();
+			notBuild = Activator.getImageDescriptor(Constants.ICON_NOT_BUILD)
+					.createImage();
+			outside = Activator.getImageDescriptor(Constants.ICON_OUTSIDE)
+					.createImage();
+		}
+
+		/**
+		 * Gets current tree object image.
+		 *
+		 * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+		 *
+		 * @param obj
+		 *            Current tree model item
+		 * @return Corresponding image of tree view object
+		 */
+		@Override
+		public Image getImage(final Object obj) {
+
+			// if object is TreeParent return "folder" icon
+			if (obj instanceof TreeParent) {
+				return folder;
+			}
+
+			// if object is TreeObject, need to change icon to match object
+			// state
+			else if (obj instanceof TreeObject) {
+				// get TreeObject
+				TreeObject tempObject = (TreeObject) obj;
+
+				// change object icon if module belongs to selected project
+				if (tempObject.isBelongs()) {
+					// if module is built with AnalyzeTool
+					if (tempObject.isBuild()) {
+						return build;
+					}
+					// module not build with AnalyzeTool
+					return notBuild;
+				}
+				// module not belong to selected project
+				return outside;
+			}
+
+			return element;
+		}
+
+		/**
+		 * Gets current tree view object name.
+		 *
+		 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+		 *
+		 * @return Current tree view object name
+		 */
+		@Override
+		public final String getText(final Object obj) {
+			return obj.toString();
+		}
+	}
+
+	/** Is trace actions enabled. */
+	public static boolean enableTrace;
+
+	/** Title of the AnalyzeTool view */
+	private String viewTitle = Constants.ANALYZE_TOOL_TITLE;
+
+	/** Line feed character. */
+	private static String lineFeed = "\n";
+
+	/** Contains information of test runs. */
+	public TreeViewer runView;
+
+	/** Contains one memory leak call stack addresses. */
+	private TreeViewer callstackView;
+
+	/** Tree parent object which not shown to user. */
+	private TreeParent invisibleRoot;
+
+	/** Double click action. */
+	private Action doubleClickAction;
+	/** Click action. */
+	private Action clickAction;
+	/** Change detail level action. */
+	public Action changeDetails;
+	/** Select S60 log file action. */
+	private Action s60LogTargetAction;
+	/** Select Tracing utility connection action. */
+	private Action externalLogTargetAction;
+	/** Select fast data gathering mode */
+	private Action externalFastLogTargetAction;
+	/** Select Ask always action. */
+	private Action askLogTargetAction;
+	/** Save report file action. */
+	private Action saveReportAction;
+	/** Save test run action. */
+	private Action saveDataFileAction;
+	/** AnalyzeTool results action. */
+	private Action analyzeResults;
+	/** Activate AnalyzeTool build action. */
+	public Action buildWithAtool;
+	/** Clean AnalyzeTool changes action. */
+	private Action cleanAtoolChanges;
+	/** Start/Stop trace action. */
+	public Action traceAction;
+	/** Start subtest action. */
+	private Action startSubtest;
+	/** Stop subtest action. */
+	private Action stopSubtest;
+	/**Refresh(re-creates) project results*/
+	private Action refreshResults;
+	/**Copies selected memory leak item info to the clipboard.*/
+	private Action copyAction;
+	/** Action to open AnalyzeTool preference page.*/
+	private Action openPrefs;
+	/**
+	 * Clears selected project results without removing temporary files
+	 */
+	private Action clearProjectResults;
+
+	/** Selected project reference. */
+	public IProject project;
+
+	/** Previously select project reference. */
+	public IProject lastProjectRef;
+
+	/** Project reference for active trace. */
+	private IProject traceStartedProjectRef;
+
+	/** Contains detailed information of selected run or memory leak. */
+	public Label informationLabel;
+
+	/** Memory analysis parser. */
+	public ParseAnalyzeData parser;
+
+	/** Used data file. */
+	public String usedDataFileName = null;
+
+	/** Is trace active. */
+	private boolean traceActive = false;
+
+	/** Last active memory leak tree item. */
+	private TreeObject activeTreeItem;
+
+	/** Contains workbench (all project) related cpp file info. */
+	private final AbstractList<String> cppFileNames;
+
+	/** Contains started subtest information. */
+	private final AbstractList<ActiveSubtests> startedSubtest;
+
+	/** Contains project related module results. */
+	private final ProjectResults projectResults;
+
+	/** Job for analyzing data files. */
+	private Job analyzeJob;
+
+	/** Last selected tree item. */
+	private Object lastSelectedObject;
+
+	/** Contains information of which files is opened. */
+	public FileActionHistory fileOpenHistory;
+
+	/** File open drop down menu. */
+	private DropDownMenu fileOpenMenu;
+
+	/** Log target action drop down menu. */
+	private DropDownMenu logTargetMenu;
+
+	/** Save file drop down menu. */
+	private DropDownMenu saveFileMenu;
+
+	/** Tab item for the "Top allocation locations" tab */
+	CTabItem memoryTab;
+
+	/** Tab item for the memory results tab*/
+	CTabItem mainTab;
+
+	/** StatisticView reference */
+	StatisticView statisticView;
+
+	/** Contains project related modules */
+	private final Hashtable<IProject, AbstractList<MMPInfo>> projectModules;
+
+	/**Reads epocwind.out file*/
+	EpocReader listeningJob;
+	
+	/** The chart view composite */
+	protected ChartContainer chart;
+
+
+	/**
+	 * The constructor.
+	 */
+	public MainView() {
+		parser = new ParseAnalyzeData(true, false);
+		cppFileNames = new ArrayList<String>();
+		startedSubtest = new ArrayList<ActiveSubtests>();
+		projectResults = new ProjectResults();
+		fileOpenHistory = new FileActionHistory(Constants.HISTORY_LEVEL);
+		projectModules = new Hashtable<IProject, AbstractList<MMPInfo>>();
+	}
+
+	/**
+	 * Activates AnalyzeTool custom build if it is not activated.
+	 */
+	public final void activateAnalysisBuild() {
+		// check project validity
+		if (checkProjectValidity()) {
+			// add AnalyzeTool custom builder natures to project build nature
+			BuilderUtil bUtil = new BuilderUtil();
+			if (bUtil.isNatureEnabled(project)) {
+				bUtil.disableNatures(project);
+			} else {
+				bUtil.enableNatures(project);
+			}
+
+		}
+
+		// update build state
+		updateBuildState(project);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see com.nokia.s60tools.analyzetool.ui.IActionListener#allModulesBuilt()
+	 */
+	public final void buildStateChanged(final IProject projRef) {
+
+		//check validity
+		if(!project.equals(projRef) || projectResults == null) {
+			return;
+		}
+
+
+		final String datafile = projectResults.getDataFileName(projRef);
+
+		// if trace is captured or data file is opened
+		if (datafile != null && runView != null) {
+
+			// need to check is data file available in the disk
+			FileInputStream fis = null;
+			try {
+
+				// get existing file stream
+				fis = new FileInputStream(datafile);
+
+				// if file is empty => do nothing
+				if (fis.available() == 0) {
+					return;
+				}
+			} catch (java.io.FileNotFoundException fnfe) {
+				fnfe.printStackTrace();
+				return;
+			} catch (java.io.IOException ioe) {
+				ioe.printStackTrace();
+				return;
+			} finally { // finally close input stream
+				try {
+					if (fis != null) {
+						fis.close();
+						fis = null;
+					}
+				} catch (java.io.IOException ioe) {
+					ioe.printStackTrace();
+				}
+			}
+
+
+			//data file is available
+			int dataFileType = UseAtool.checkFileType(datafile);
+
+			if( dataFileType == Constants.DATAFILE_INVALID || dataFileType == Constants.DATAFILE_XML || dataFileType == Constants.DATAFILE_EMPTY ) {
+				return;
+			}
+			boolean reGenerate = Util.openConfirmationDialog(Constants.BUILD_STATE_CHANGED);
+
+			if( reGenerate ) {
+				// sync with UI thread
+				runView.getControl().getDisplay().asyncExec(new Runnable() {
+					public void run() {
+						analyzeDataFile(Constants.ANALYZE_USE_DATA_FILE, datafile,
+								false);
+					}
+				});
+			}
+
+		}
+	}
+
+
+	/**
+	 * Opens file dialog and analyzing data file for given location.
+	 *
+	 * @param type
+	 *            Type to define is data file asked from the user or using the
+	 *            give data file
+	 * @param existingDataFile
+	 *            Data file path
+	 * @param showErrorInfo
+	 *            Flag to determinate that displaying error info or not
+	 */
+	public final void analyzeDataFile(final int type,
+			final String existingDataFile, final boolean showErrorInfo) {
+
+		// is project selected
+		if (!checkProjectValidity()) {
+			return;
+		}
+
+		// user selected file
+		final String selectedFile;
+
+		// ask for user data file
+		if (type == Constants.ANALYZE_ASK_FOR_USER) {
+			selectedFile = Util.openFileDialog(getSite().getShell(),
+					Constants.DIALOG_SELECT_DATA_FILE, project.getLocation()
+							.toOSString());
+		} else if (existingDataFile == null) {
+			selectedFile = parser.getDataFileName();
+		} else {
+			selectedFile = existingDataFile;
+		}
+
+		// if user select some file
+		if (selectedFile != null) {
+
+			// clear previous data
+			projectResults.clearProjectData(project);
+			activeTreeItem = null;
+			clearCallstackViewContent();
+			updateInformationLabel("");
+			runView.setInput(getStartupContent());
+			changeViewTitle(viewTitle);
+
+			AbstractList<MMPInfo> modules = Util.loadProjectTargetsInfo(project);
+			projectModules.put(project, modules);
+
+			boolean xmlFile = Util.isFileXML(selectedFile);
+			// if file is xml file
+			// no need to analyze data file
+			// => just create results from xml file
+			if (xmlFile) {
+				Job analyzingXMLJob = new Job(Constants.ANALYZE_TOOL_TITLE) {
+					@Override
+					protected IStatus run(IProgressMonitor monitor) {
+
+						// update progress monitor state
+						monitor.beginTask(Constants.PROGRESSDIALOG_TITLE,
+								IProgressMonitor.UNKNOWN);
+						// Parse the data file
+						ParseXMLFileSAX dataFileParser = new ParseXMLFileSAX(project, selectedFile, projectResults);
+						boolean ret = dataFileParser.parse();
+
+						// set used datafile name
+						usedDataFileName = selectedFile;
+
+						fileOpenHistory.setFileName(selectedFile);
+
+						// if parsing success
+						// display memory leak results
+						if (ret) {
+							// update project results
+							projectResults.setProjectModules(project, projectModules.get(project), dataFileParser.getModules());
+						} else {
+							fileOpenHistory.removeFileName(selectedFile);
+							if (showErrorInfo) {
+								showErrorMessage(Constants.INFO_FILE_INVALID);
+							}
+						}
+						updateChangeDetailState(project);
+						refreshView();
+						dataFileParser = null;
+						return new Status(IStatus.OK,
+								Constants.ANALYZE_CONSOLE_ID, IStatus.OK,
+								Constants.PROGRESSDIALOG_ANALYZE_COMPLETE, null);
+					}
+				};
+				analyzingXMLJob.setUser(true);
+				analyzingXMLJob.schedule();
+
+			} else {
+				try{
+					analyzeWithAtool(project, selectedFile, showErrorInfo);
+				}
+				catch( Exception e ) {
+					analyzeJob = null;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Analyzing memory analysis results using atool.exe.
+	 *
+	 * @param projectRef
+	 *            Project reference
+	 * @param usedFile
+	 *            Data file which contains memory analyze data
+	 * @param showErrorInfo
+	 *            Flag to determinate that displaying error info or not
+	 */
+	public final void analyzeWithAtool(final IProject projectRef,
+			final String usedFile, final boolean showErrorInfo) {
+		// check that no existing job running
+		if (analyzeJob == null
+				|| analyzeJob.getResult().getCode() == IStatus.CANCEL
+				|| analyzeJob.getResult().getCode() == IStatus.ERROR) {
+			analyzeJob = new Job(Constants.ANALYZE_TOOL_TITLE) {
+				@Override
+				protected IStatus run(IProgressMonitor monitor) {
+					// inform progressdialog that task execution starts
+					// this make progressdialog visible on the UI
+					monitor.beginTask(Constants.PROGRESSDIALOG_ATOOL,
+							IProgressMonitor.UNKNOWN);
+
+					fileOpenHistory.setFileName(usedFile);
+					// add2UserActionHistory( "File opened: " + usedFile );
+
+					// set used datafile name
+					usedDataFileName = usedFile;
+
+					// create atool object and execute atool
+					UseAtool atool = new UseAtool();
+
+					// create xml file
+					Constants.COMMAND_LINE_ERROR_CODE errorCode = atool.createXMLFileToCarbide(
+							monitor, projectRef, usedFile, "-a");
+					String xmlFileLocation = null;
+					xmlFileLocation = atool.getDataFileName();
+						
+					// if some error occurs display it to user.
+					if( errorCode != Constants.COMMAND_LINE_ERROR_CODE.OK ) {
+						fileOpenHistory.removeFileName(usedFile);
+						Util.displayCommandLineError(errorCode);					
+					}
+					// if XML file generation failed => info to the user
+					else if (xmlFileLocation == null) {
+						fileOpenHistory.removeFileName(usedFile);
+						if (showErrorInfo) {
+							showErrorMessage(Constants.INFO_FILE_INVALID);
+						}
+					} else {
+						// Parse the xml file
+						ParseXMLFileSAX dataFileParser = new ParseXMLFileSAX(project,
+								xmlFileLocation, projectResults);
+						boolean error = dataFileParser.parse();
+						if (showErrorInfo && !error) {
+							fileOpenHistory.removeFileName(usedFile);
+							showErrorMessage(Constants.INFO_FILE_INVALID);
+						}
+
+						projectResults.setProjectModules(project, projectModules.get(project), dataFileParser.getModules());
+						projectResults.setDataFileName(projectRef, usedDataFileName);
+						// update display
+						refreshView();
+					}
+
+					updateChangeDetailState(projectRef);
+					
+//					//this only generates statistics and this feature is currently disabled
+//					if( !monitor.isCanceled() ) {
+//
+//						IPreferenceStore store = Activator.getPreferences();
+//						boolean generateStatistic = store.getBoolean(Constants.CREATE_STATISTIC);
+//						//used file data file create statistic also
+//						if( generateStatistic && UseAtool.checkFileType(usedFile) == Constants.DATAFILE_TRACE )
+//						{
+//							monitor.setTaskName(Constants.STATISTICS_GENERATING_PROG_TITLE);
+//
+//							ReadFile fileReader = new ReadFile();
+//							boolean error = fileReader.readFile(usedFile);
+//							if( error && statisticView != null) {
+//								AbstractList<ProcessInfo> processes = fileReader.getStatistic();
+//								statisticView.setData( project, processes);
+//								fileReader.finish();
+//							}
+//
+//						}
+//					}
+					if (!monitor.isCanceled()) {
+
+						monitor.setTaskName(Constants.GRAPH_GENERATING_PROG_TITLE);
+						try {
+							ReadFile fileReader = new ReadFile();
+							boolean success = fileReader.readFile(usedFile);
+							if (success) {
+								if (chart != null){
+									resetGraphView();
+								}
+								AbstractList<ProcessInfo> processes = fileReader.getStatistic();
+								IMemoryActivityModel model = new AnalyzeFactory().createModel(processes.size() == 0);
+								chart.setInput(project, model);
+								model.addProcesses(processes);
+								fileReader.finish();
+							}	
+						}catch( OutOfMemoryError oome ) {
+							Activator.getDefault().logInfo(IStatus.ERROR, IStatus.ERROR, "Can not allocate enough memory for the memory usage graph model.");
+							analyzeJob = null;
+						}catch (Exception e ) {
+							Activator.getDefault().log(IStatus.ERROR, "Error while generating graph model", e);
+							analyzeJob = null;
+						}
+					}
+					analyzeJob = null;
+					return new Status(IStatus.OK, Constants.ANALYZE_CONSOLE_ID,
+							IStatus.OK,
+							Constants.PROGRESSDIALOG_ANALYZE_COMPLETE, null);
+				}
+			};
+
+			analyzeJob.setUser(true);
+			analyzeJob.setPriority(Job.LONG);
+			analyzeJob.schedule();
+
+		} else { // if existing job is running display info to user
+			showMessage(Constants.INFO_ALLREADY_RUNNING);
+		}
+	}
+
+
+	/**
+	 * Change report detail level.
+	 */
+	public final void changeDetailLevel() {
+
+		// sync with UI thread
+		PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				// get preference store
+				IPreferenceStore store = Activator.getPreferences();
+
+				// get active report level
+				String reportLevel = store.getString(Constants.REPORT_LEVEL);
+
+				boolean updateMemLeakAlso = false;
+
+				// set new report level
+				if (Constants.REPORT_EVERY.equals(reportLevel)) {
+					store.setValue(Constants.REPORT_LEVEL,
+							Constants.REPORT_KNOWN);
+					updateMemLeakAlso = true;
+				} else if (Constants.REPORT_KNOWN.equals(reportLevel)) {
+					store.setValue(Constants.REPORT_LEVEL,
+							Constants.REPORT_TOPMOST);
+				} else if (Constants.REPORT_TOPMOST.equals(reportLevel)) {
+					store.setValue(Constants.REPORT_LEVEL,
+							Constants.REPORT_EVERY);
+					updateMemLeakAlso = true;
+				}
+
+				if (updateMemLeakAlso && runView != null) {
+					activeTreeItem = null;
+
+					// set view content
+					runView.setInput(getResults(false));
+
+					// refresh view
+					runView.refresh();
+
+					// if last selected item not found current item list
+					if (activeTreeItem == null) {
+						runView.setAutoExpandLevel(2);
+					} else {
+						// set selection to correct item
+						runView.setSelection(new StructuredSelection(
+								activeTreeItem), true);
+					}
+
+				}
+
+				if (callstackView != null) {
+					// update view callstack view content
+					callstackView.setInput(getCallStack(activeTreeItem));
+
+					// expand all the trees on call stack view
+					callstackView.expandAll();
+
+				}
+
+				// change tooltip
+				changeReportActionTooltip();
+
+			}
+		});
+
+	}
+
+	/**
+	 * Change logging mode.
+	 *
+	 * @param loggingMode
+	 *            Used logging mode
+	 */
+	public final void changeLogTarget(final String loggingMode) {
+
+		if (logTargetMenu == null) {
+			return;
+		}
+
+		// get preference store
+		IPreferenceStore store = Activator.getPreferences();
+		String usedLoggingMode = "";
+
+		// if no loggingmode given get it from the AnalyzeTool preferences
+		if (loggingMode == null) {
+			usedLoggingMode = store.getString(Constants.LOGGING_MODE);
+		}
+		// logging mode is given => so start to use it
+		else {
+			store.setValue(Constants.LOGGING_MODE, loggingMode);
+			usedLoggingMode = loggingMode;
+		}
+
+		// current logging mode is external change it to external
+		if (Constants.LOGGING_EXT.equals(usedLoggingMode)) {
+			logTargetMenu.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_COMPUTER));
+			logTargetMenu
+					.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_EXT);
+			if (loggingMode == null){
+				externalLogTargetAction.setChecked(true);
+				s60LogTargetAction.setChecked(false);
+				externalFastLogTargetAction.setChecked(false);
+				askLogTargetAction.setChecked(false);
+			}
+		}
+		// current logging mode is s60 change it to s60
+		else if (Constants.LOGGING_S60.equals(usedLoggingMode)) {
+
+			logTargetMenu.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_CELLURAR));
+			logTargetMenu
+					.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_S60);
+			if (loggingMode == null){
+				externalLogTargetAction.setChecked(false);
+				s60LogTargetAction.setChecked(true);
+				externalFastLogTargetAction.setChecked(false);
+				askLogTargetAction.setChecked(false);
+			}
+		}
+
+		else if( Constants.LOGGING_EXT_FAST.equals(usedLoggingMode)) {
+			logTargetMenu.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_COMPUTER_FAST));
+			logTargetMenu.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_FAST);
+			if( loggingMode == null) {
+				externalLogTargetAction.setChecked(false);
+				s60LogTargetAction.setChecked(false);
+				externalFastLogTargetAction.setChecked(true);
+				askLogTargetAction.setChecked(false);
+			}
+		}
+		// current logging mode is "ask_always"
+		else {
+			logTargetMenu.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_ASK));
+			logTargetMenu
+					.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_ASK);
+			if (loggingMode == null){
+				externalLogTargetAction.setChecked(false);
+				s60LogTargetAction.setChecked(false);
+				externalFastLogTargetAction.setChecked(false);
+				askLogTargetAction.setChecked(true);
+			}
+		}
+
+		// if the fast data gathering mode is enabled by the preference page => enable also toolbar option
+		// else disable fast data gathering mode
+		externalFastLogTargetAction.setEnabled(store.getBoolean(Constants.LOGGING_FAST_ENABLED));
+	}
+
+	/**
+	 * Changes "Change report detail level" action tooltip.
+	 */
+	public final void changeReportActionTooltip() {
+		if (changeDetails == null) {
+			return;
+		}
+
+		// get preference store
+		IPreferenceStore store = Activator.getPreferences();
+
+		// get active report level
+		String reportLevel = store.getString(Constants.REPORT_LEVEL);
+
+		// set new report level
+		if (Constants.REPORT_EVERY.equals(reportLevel)) {
+			changeDetails.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_DETAILS_ALL));
+			changeDetails
+					.setToolTipText(Constants.ACTION_CHANGE_REPORT_LEVEL_ALL);
+		} else if (Constants.REPORT_KNOWN.equals(reportLevel)) {
+			changeDetails.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_DETAILS_KNOWN));
+			changeDetails
+					.setToolTipText(Constants.ACTION_CHANGE_REPORT_LEVEL_KNOWN);
+		} else if (Constants.REPORT_TOPMOST.equals(reportLevel)) {
+			changeDetails.setImageDescriptor(Activator
+					.getImageDescriptor(Constants.BUTTON_DETAILS_TOPMOST));
+			changeDetails
+					.setToolTipText(Constants.ACTION_CHANGE_REPORT_LEVEL_TOPMOST);
+		}
+
+	}
+
+	/**
+	 * Change view title.
+	 *
+	 * @param newTitle
+	 *            New title text
+	 */
+	private void changeViewTitle(final String newTitle) {
+
+		// if newTitle contains text
+		if (newTitle != null) {
+			super.setContentDescription(newTitle);
+		}
+	}
+
+	/**
+	 * Check project validity that is project is selected.
+	 *
+	 * @return True if project is open and accessible otherwise False
+	 */
+	public final boolean checkProjectValidity() {
+		// project is not selected show info to user
+		if (project == null || !project.isOpen()) {
+			Util.showMessage(Constants.NO_PROJ_SELECT);
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Cleans atool.exe made changes.
+	 */
+	public final void clean() {
+		if (!checkProjectValidity()) {
+			return;
+		}
+
+		// check is atool.exe available
+		if (!Util.isAtoolAvailable()) {
+			showErrorMessage(Constants.INFO_ATOOL_NOT_AVAILABLE);
+			return;
+		}
+
+		// ask for user
+		boolean ret = Util.openConfirmationDialog(Constants.CONFIRM_DELETE_ALL);
+
+		// if user confirms
+		if (ret) {
+			// clear AnalyzeTool made changes
+			Util util = new Util();
+			util.clearAtoolChanges(project);
+
+			cleanAnalyzeData(null);
+			updateChangeDetailState(project);
+		}
+
+		if( statisticView != null ) {
+			statisticView.clean(null);
+		}
+		
+		if (chart != null){
+			resetGraphView();
+		}
+
+	}
+
+	/**
+	 * Cleans all the saved data.
+	 */
+	private void cleanAnalyzeData(final IProject projectRef) {
+		// clean all data if project not specified
+		if (projectRef == null) {
+			// clean all the project related info and data
+			projectResults.clear();
+			projectModules.clear();
+		}
+		else {
+			// clear only one project results
+			if (projectResults.contains(projectRef)) {
+				projectResults.clearProjectData(projectRef);
+			}
+
+			if( projectModules.contains(projectRef)) {
+				projectModules.remove(projectRef);
+			}
+		}
+
+
+
+		cppFileNames.clear();
+
+		// update variables
+		activeTreeItem = null;
+		usedDataFileName = "";
+
+
+		// set default view contents
+		if (runView != null) {
+			runView.getControl().getDisplay().syncExec(new Runnable() {
+				public void run() {
+					runView.setInput(getStartupContent());
+					if (informationLabel != null) {
+						updateInformationLabel("");
+					}
+
+					changeViewTitle(viewTitle);
+					if( statisticView != null ) {
+						statisticView.clean(projectRef);
+					}
+				}
+			});
+		}
+
+		clearCallstackViewContent();
+		if( clearProjectResults != null && clearProjectResults != null ) {
+			clearProjectResults.setEnabled(false);
+		}else if( clearProjectResults != null ) {
+			updateChangeDetailState(projectRef);
+		}
+
+	}
+
+	/**
+	 * Clears callstack view contents.
+	 */
+	private void clearCallstackViewContent() {
+		if (runView == null) {
+			return;
+		}
+
+		// if view exists
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+
+				if (callstackView != null) {
+					callstackView.setInput(null);
+				}
+			}
+		});
+
+	}
+
+	/**
+	 * Contributes action bar.
+	 */
+	private void contributeToActionBars() {
+		if (getViewSite() == null) {
+			return;
+		}
+		IActionBars bars = getViewSite().getActionBars();
+		fillLocalPullDown(bars.getMenuManager());
+		fillLocalToolBar(bars.getToolBarManager());
+	}
+
+
+	/**
+	* This is a callback that will allow us
+	* to create the viewer and initialize it.
+	*/
+	@Override
+	public void createPartControl( Composite parent ){
+
+		//create new Tab
+		CTabFolder mainFolder = new CTabFolder( parent, SWT.TOP );
+
+		//create main view and add it tab
+		createMainView( mainFolder );
+
+		//create new statistic view
+		//createMemoryView( mainFolder );
+		//create graph
+		createGraphView(mainFolder);
+
+		//set initial selection
+		mainFolder.setSelection( mainTab );
+	}
+
+	/**
+	 * Creates graph view and add it to graph tab
+	 * @param parent CTabFolder parent of the view
+	 */
+	private void createGraphView(CTabFolder mainFolder) {
+		final CTabItem chartTabItem = new CTabItem(mainFolder, SWT.NONE);
+		chartTabItem.setText("Graph"); 
+		chartTabItem.setToolTipText("AnalyzeTool graph per process"); 
+		
+		chart = new ChartContainer(mainFolder, SWT.NONE);
+		chartTabItem.setControl(chart);
+		IMemoryActivityModel model = AnalyzeFactory.getEmptyModel();
+		chart.setInput(project, model);
+		model.addProcesses(model.getProcesses());//charts should get notified via listeners on the model
+	}
+	
+	/**
+	 * Clears the graph by setting an empty model and causing paint events
+	 */
+	private void resetGraphView(){
+		if (chart != null){
+			chart.setInput(project, AnalyzeFactory.getEmptyModel());
+			//chart.update();
+		}
+	}
+
+	/**
+	 * Creates new statistic view and add it to memory tab
+	 * @param parent Statistic view parent( CTabFolder )
+	 */
+	public void createMemoryView( CTabFolder parent )
+	{
+		statisticView = new StatisticView();
+		memoryTab = statisticView.createView( parent );
+	}
+
+	/**
+	 * Creates memory results view
+	 * @param parent View parent ( CTabFolder )
+	 */
+	public void createMainView(CTabFolder parent) {
+
+		// Create SashForm this form includes all the current view components
+		SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL);
+
+		mainTab = new CTabItem( parent, SWT.NONE );
+		mainTab.setControl( sashForm );
+		mainTab.setText(Constants.MAIN_TAB_TITLE);
+
+		// create new treeviewer to shown memory analysis runs and leaks
+		runView = new TreeViewer(sashForm, SWT.VIRTUAL);
+
+		// create SashForm to display call stack addresses and more detailed
+		// information
+		// of selected run or leak
+		SashForm callstackForm = new SashForm(sashForm, SWT.VERTICAL);
+
+		// set content and label providers
+		runView.setContentProvider(new ViewContentProvider());
+		runView.setLabelProvider(new ViewLabelProvider());
+		// runView.addFilter( new ATFilter() );
+		// get init content
+		runView.setInput(getStartupContent());
+
+		// add listener to provide selection change events
+		runView.addTreeListener(this);
+
+		runView.setAutoExpandLevel(2);
+
+		// create new information label
+		// this label contains more detailed information of selected item
+		informationLabel = new Label(callstackForm, SWT.BORDER | SWT.CENTER);
+
+		// create grid data => this provides layout changes
+		GridData data = new GridData();
+
+		// add grid data to label, this enables label ui modifications e.g. line
+		// feed
+		informationLabel.setLayoutData(data);
+
+		// set init text
+		informationLabel.setText(Constants.INFO_NO_DATA);
+
+		// create new call stack view
+		// this components contains information of one memory leak call stack
+		// addresses
+		callstackView = new TreeViewer(callstackForm, SWT.MULTI | SWT.H_SCROLL
+				| SWT.V_SCROLL);
+
+		// modify UI components layouts
+		// reserve more space for left side of UI
+		sashForm.setWeights(new int[] { 5, 3 });
+		callstackForm.setWeights(new int[] { 2, 8 });
+
+		// add content and label providers
+		callstackView.setContentProvider(new ViewContentProvider());
+		callstackView.setLabelProvider(new ViewLabelProvider());
+
+		// make actions and construct click listeners
+		makeActions();
+		hookContextMenu();
+		hookDoubleClickAction();
+		hookClicks();
+		contributeToActionBars();
+
+		// set view title
+		viewTitle = String.format(Constants.ANALYZE_TOOL_TITLE_WITH_VERSION, Util.getAToolFeatureVersionNumber());
+		this.setContentDescription(viewTitle);
+
+		// add selection listener
+		if (getSite() != null) {
+			getSite().getPage().addSelectionListener(this);
+			runView.getControl().addKeyListener(this);
+		}
+
+		// set actionlistener
+		Activator.setActionListener(this);
+
+		// set help shortcuts
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(
+				callstackView.getControl(),
+				AnalyzeToolHelpContextIDs.ANALYZE_MAIN);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(runView.getControl(),
+				AnalyzeToolHelpContextIDs.ANALYZE_MAIN);
+
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(new ATResourceListener());
+		
+		//get used command line engine version
+		String version = Util.getAtoolVersionNumber(Util.getAtoolInstallFolder());
+		
+		//compare current version to min version
+		int comp = Util.compareVersionNumber(Constants.CS_SUPPORT_MIN_VERSION, version);
+		
+		IPreferenceStore store = Activator.getPreferences();
+		//if current version is same or higher than required version => set flag to true
+		if( comp == Constants.VERSION_NUMBERS_EQUALS || comp == Constants.VERSION_NUMBERS_SECOND ) {
+			store.setValue(Constants.LOGGING_FAST_ENABLED, true);
+		}
+		else {
+			store.setValue(Constants.LOGGING_FAST_ENABLED, false);
+		}
+		
+		// get default value for logging mode
+		preferenceChanged();
+	}
+
+	/**
+	 * When AnalyzeTool view is activated and Tracing utility plug-in is not
+	 * available disable AnalyzeTool trace actions.
+	 *
+	 * @see com.nokia.s60tools.analyzetool.ui.IActionListener#disableTraceActions(boolean)
+	 *
+	 * @param disable
+	 *            Boolean state of trace action
+	 */
+	public void disableTraceActions(final boolean disable) {
+
+		if (traceAction != null && disable) {
+			// enable trace action
+			traceAction.setToolTipText(Constants.ACTION_START_TRACE);
+			traceAction.setEnabled(disable);
+		} else if (traceAction != null && !disable) {
+			// disable trace action
+			traceAction.setToolTipText(Constants.TRACE_NOT_FOUND);
+			traceAction.setEnabled(disable);
+		}
+
+		traceActive = false;
+	}
+
+	/**
+	 * Fills context menu.
+	 *
+	 * @param manager
+	 *            Menu manager
+	 */
+	private void fillContextMenu(IMenuManager manager) {
+
+		manager.add(buildWithAtool);
+		manager.add(new Separator());
+		manager.add(traceAction);
+		manager.add(startSubtest);
+		manager.add(stopSubtest);
+		manager.add(new Separator());
+		manager.add(changeDetails);
+		manager.add(refreshResults);
+		manager.add(clearProjectResults);
+		manager.add(new Separator());
+		manager.add(cleanAtoolChanges);
+		manager.add(copyAction);
+		// Other plug-ins can contribute there actions here
+		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+	}
+
+	/**
+	 * Fills local pull down menu.
+	 *
+	 * @param manager
+	 *            Menu manager
+	 */
+	private void fillLocalPullDown(IMenuManager manager) {
+		manager.add(buildWithAtool);
+		manager.add(new Separator());
+		manager.add(traceAction);
+		manager.add(startSubtest);
+		manager.add(stopSubtest);
+		manager.add(new Separator());
+		manager.add(changeDetails);
+		manager.add(refreshResults);
+		manager.add(new Separator());
+		manager.add(cleanAtoolChanges);
+		manager.add(new Separator());
+		manager.add(openPrefs);
+	}
+
+	/**
+	 * Fills local toolbar.
+	 *
+	 * @param manager
+	 *            Menu manager
+	 */
+	private void fillLocalToolBar(IToolBarManager manager) {
+
+		logTargetMenu = new DropDownMenu(Constants.ACTION_SAVE, this, false,
+				false);
+		makeLogTargetActions();
+		logTargetMenu.addAction(s60LogTargetAction);
+		logTargetMenu.addAction(externalLogTargetAction);
+		logTargetMenu.addAction(externalFastLogTargetAction);
+		logTargetMenu.addAction(askLogTargetAction);
+		manager.add(logTargetMenu);
+
+		manager.add(buildWithAtool);
+		manager.add(new Separator());
+		manager.add(traceAction);
+		manager.add(startSubtest);
+		manager.add(stopSubtest);
+		manager.add(new Separator());
+		manager.add(changeDetails);
+		manager.add(new Separator());
+		fileOpenMenu = new DropDownMenu(Constants.ACTION_OPEN, this, false,
+				true);
+		makeFileOpenActions();
+		manager.add(fileOpenMenu);
+
+		// get drop down menu for save action
+		saveFileMenu = new DropDownMenu(Constants.ACTION_SAVE, this, true,
+				false);
+		saveFileMenu.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_SAVE));
+
+		saveFileMenu.addAction(saveReportAction);
+		saveFileMenu.addAction(saveDataFileAction);
+		manager.add(saveFileMenu);
+		manager.add(new Separator());
+		manager.add(cleanAtoolChanges);
+		manager.add(new Separator());
+		manager.add(openPrefs);
+	}
+
+	/**
+	 * Gets call stack information of current leak.
+	 *
+	 * @param treeObject
+	 *            Tree object
+	 * @return Object
+	 */
+	Object getCallStack(final TreeObject treeObject) {
+		IPreferenceStore store = Activator.getPreferences();
+		// if project is not selected or treeobject is not created
+		// => leave
+		if (project == null || treeObject == null) {
+			return null;
+		}
+
+		// set active tree item
+		activeTreeItem = treeObject;
+
+		AnalysisItem item = null;
+		if (treeObject.isSubTest()) {
+			item = projectResults.getSubtestItem(project,
+					treeObject.getRunID(), treeObject.getMemLeakID(),
+					treeObject.getSubtestID());
+		}
+		// get AnalysisItem
+		else {
+			item = projectResults.getSpecific(project, treeObject.getRunID(),
+					treeObject.getMemLeakID());
+		}
+
+		if (item == null) {
+			return null;
+		}
+
+		if (store == null) {
+			return null;
+		}
+		AbstractList<MMPInfo> modules = projectModules.get(project);
+		TreeHelper helper = new TreeHelper(null, store);
+
+		TreeParent parent = helper.getCallstack(item, modules);
+
+		return parent;
+	}
+
+
+	/**
+	 * Gets callstack item name.
+	 *
+	 * @param callstackItem
+	 *            One callstack item
+	 * @return Callstack name if found otherwise null
+	 */
+	public final String getCallstackItemName(final CallstackItem callstackItem) {
+		// if call stack item not set => return
+		if (callstackItem == null) {
+			return null;
+		}
+
+		String cppFileName = "";
+		String fileName = callstackItem.getFileName().toLowerCase(Locale.US);
+
+		if (fileName.indexOf(".cpp") == -1) {
+			return null;
+		}
+
+		// check that project contains cpp file which is parsed from call stack
+		// list
+		Iterator<String> iterCppFiles = cppFileNames.iterator();
+		while( iterCppFiles.hasNext() ) {
+			String cppFileLocation = iterCppFiles.next();
+
+			//parse file name from the source path
+			int slash = Util.getLastSlashIndex(cppFileLocation);
+			if( slash != -1 ) {
+				String cppFile = cppFileLocation.substring(slash+1, cppFileLocation.length());
+				if( cppFile.equalsIgnoreCase(fileName)) {
+					cppFileName = cppFileLocation;
+					break;
+				}
+			}
+		}
+		return cppFileName;
+	}
+
+	/**
+	 * Gets file info for current project.
+	 *
+	 * @param projectRef
+	 *            Project reference
+	 */
+	private void getFileInfos(final IProject projectRef) {
+		ResourceVisitor visitor = new ResourceVisitor(this);
+
+		// go thru all open projects
+		// this enables to display one memory address corresponding source code
+		// line
+		// for outside of active project
+		try {
+			if (projectRef == null) {
+				IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace()
+						.getRoot();
+				IProject[] projects = myWorkspaceRoot.getProjects();
+				for (int i = 0; i < projects.length; i++) {
+					IProject tempProject = projects[i];
+					if (tempProject.isOpen()) {
+						tempProject.accept(visitor);
+					}
+				}
+
+			} else { // project is selected
+				// if project is open => accept resource visitor
+				if (projectRef.isOpen()) {
+					projectRef.accept(visitor);
+				}
+			}
+		} catch (CoreException e) {
+			e.printStackTrace();
+
+		}
+	}
+
+	/**
+	 * Gets project results.
+	 *
+	 * @param projectRef
+	 *            Project reference
+	 */
+	public void getProjectResults(final IProject projectRef) {
+		// if project reference is null => leave
+		if (projectRef == null) {
+			return;
+		}
+		// if project is selected and it is open
+		else if (projectRef.isOpen()) {
+			// if this is the first time to get project results
+			if (lastProjectRef == null) {
+				lastProjectRef = projectRef;
+				updateBuildState(lastProjectRef);
+				updateChangeDetailState(lastProjectRef);
+			}
+			// project selection changed
+			// need to get selected project results and mmp file info
+			else if (!lastProjectRef.equals(projectRef)) {
+				activeTreeItem = null;
+				lastProjectRef = projectRef;
+
+				runView.setInput(getResults(false));
+				callstackView.setInput(getCallStack(null));
+
+				updateInformationLabel("");
+				updateBuildState(lastProjectRef);
+				updateChangeDetailState(lastProjectRef);
+			}
+		}
+
+		//update clear project results action state
+		if( projectResults.contains(projectRef) ) {
+			clearProjectResults.setEnabled(true);
+		}
+		else {
+			clearProjectResults.setEnabled(false);
+		}
+	}
+
+	/**
+	 * Gets memory leak analysis results.
+	 *
+	 * @param showErrorInfo
+	 *            Display error info or not
+	 * @return Object memory leak analysis results
+	 */
+	private Object getResults(final boolean showErrorInfo) {
+
+		try {
+			// create new tree paretn
+			TreeParent testRuns = new TreeParent(Constants.TEST_RUNS_TREE_TITLE);
+			invisibleRoot = null;
+			invisibleRoot = new TreeParent(Constants.TREE_TITLE);
+			invisibleRoot.addChild(testRuns);
+
+			// if current project does not contain results => just update
+			// default view values
+			if (!projectResults.contains(project)) {
+				changeViewTitle(viewTitle);
+				updateInformationLabel(Constants.INFO_NO_DATA);
+				return getStartupContent();
+			}
+
+			if( !projectModules.containsKey(project) )
+			{
+				AbstractList<MMPInfo> modules = Util.loadProjectTargetsInfo(project);
+				projectModules.put(project, modules);
+			}
+
+			// get run results
+			AbstractList<RunResults> runs = projectResults.getResults(project);
+			AbstractList<MMPInfo> modules = projectModules.get(project);
+
+			// if no results available => show default view content
+			if (runs == null || runs.isEmpty()) {
+				changeViewTitle(viewTitle);
+				updateInformationLabel(Constants.INFO_NO_DATA);
+
+				// because no results created => delete project empty results
+				projectResults.clearProjectData(project);
+
+				fileOpenHistory.removeFileName(projectResults
+						.getDataFileName(project));
+
+				// display info to user
+				if (showErrorInfo) {
+					showErrorMessage(Constants.INFO_FILE_INVALID);
+				}
+
+				return getStartupContent();
+			}
+
+			IPreferenceStore store = Activator.getPreferences();
+
+			// create TreeHelper object
+			// TreeHelper class creates tree model to this view.
+			TreeHelper helper = new TreeHelper(lastSelectedObject,
+					store);
+
+			// clear active item
+			activeTreeItem = null;
+
+			// update used data file name
+			usedDataFileName = projectResults.getDataFileName(project);
+
+			// change view title
+			changeViewTitle(viewTitle
+					+ " results from file: " + usedDataFileName);
+
+			// thru runs
+			Iterator<RunResults> runIterator = runs.iterator();
+			while (runIterator.hasNext()) {
+				// get one run info
+				RunResults oneRunResults = runIterator.next();
+
+				// creates one run information at the time
+				TreeParent oneRunTree = helper.createRunResults(oneRunResults, modules);
+
+				// get active item
+				// active must ask from the TreeHelper class
+				// because it can be filtered out when creating new tree model
+				activeTreeItem = helper.getActiveItem();
+				testRuns.addChild(oneRunTree);
+
+			}
+
+		} catch (java.lang.NullPointerException npe) {
+			npe.printStackTrace();
+			return null;
+		}
+
+		// expand to runs level
+		runView.setAutoExpandLevel(2);
+
+		return invisibleRoot;
+	}
+
+	/**
+	 * Sets startup contents for view.
+	 *
+	 * @return Object which can be displayd
+	 */
+	public TreeParent getStartupContent() {
+		// create default treeviewer content
+		invisibleRoot = new TreeParent(Constants.ANALYZE_TOOL_TITLE);
+		TreeParent child = new TreeParent(Constants.INFO_NO_DATA_FILE_AVAILABLE);
+		invisibleRoot.addChild(child);
+
+		return invisibleRoot;
+	}
+
+	/**
+	 * Adds selection changed listener to view.
+	 */
+	private void hookClicks() {
+		runView.addSelectionChangedListener(this);
+	}
+
+	/**
+	 * Hooks context menu.
+	 */
+	private void hookContextMenu() {
+		MenuManager menuMgr = new MenuManager("#PopupMenu");
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			@SuppressWarnings("synthetic-access")
+			public void menuAboutToShow(IMenuManager manager) {
+				MainView.this.fillContextMenu(manager);
+			}
+		});
+		Menu menu = menuMgr.createContextMenu(runView.getControl());
+		runView.getControl().setMenu(menu);
+		if (getSite() != null) {
+			getSite().registerContextMenu(menuMgr, runView);
+		}
+
+	}
+
+	/**
+	 * Hook double click actions.
+	 */
+	private void hookDoubleClickAction() {
+		callstackView.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+
+				doubleClickAction.run();
+			}
+		});
+	}
+
+	/**
+	 * Check that if subtest by given name allready exists.
+	 *
+	 * @param subTestName
+	 *            Subtest name
+	 * @param target
+	 *            Testing target
+	 * @return True if allready exists otherwise False
+	 */
+	public final boolean isSubtestExists(final String subTestName,
+			final String target) {
+		Iterator<ActiveSubtests> subTestIter = startedSubtest.iterator();
+		while (subTestIter.hasNext()) {
+			ActiveSubtests oneSubtest = subTestIter.next();
+			if (oneSubtest.getName().equals(subTestName)
+					&& oneSubtest.getTargetName().equals(target)) {
+				return true;
+			}
+
+		}
+		return false;
+	}
+
+
+
+	/**
+	 * Go thru the project files and stores mmp files.
+	 *
+	 * @param resource
+	 *            One resource file of project
+	 */
+	public final void loadFileInfo(IResource resource) {
+		// get all the cpp file info which are imported to workspace
+		// this enable pinpointing the code line for outside active project cpp
+		// file than
+		// the memory analysis is made
+		// get cpp file info
+		String cppFileName = Util.getCPPFileNameAndPath(resource);
+
+		// if cpp file found, save it
+		if (cppFileName != null && !cppFileNames.contains(cppFileName)) {
+			this.cppFileNames.add(cppFileName);
+		}
+	}
+
+	/**
+	 * Construct all the actions.
+	 */
+	private void makeActions() {
+
+		// listens click actions
+		clickAction = new Action() {
+			@Override
+			public void run() {
+				// get selection
+				ISelection selection = runView.getSelection();
+
+				// get selection object
+				Object obj = ((IStructuredSelection) selection)
+						.getFirstElement();
+
+				// if object exists
+				if (obj == null) {
+					copyAction.setEnabled(false);
+					return;
+				}
+
+				// get call stack addresses to view
+				if (obj instanceof TreeObject) {
+					lastSelectedObject = obj;
+
+					//get callstack items
+					Object resultObject = getCallStack((TreeObject) obj);
+
+					// if results not found
+					if( resultObject == null ) {
+						copyAction.setEnabled(false);
+					}
+					else {
+						callstackView.setInput(resultObject);
+						copyAction.setEnabled(true);
+					}
+
+				}
+
+				// expand all the trees on call stack view
+				callstackView.expandAll();
+
+				setTextToInformationLabel();
+			}
+		};
+
+		// listens double click actions
+		doubleClickAction = new Action() {
+			@Override
+			public void run() {
+				// get selection
+				ISelection selection = callstackView.getSelection();
+				Object obj = ((IStructuredSelection) selection)
+						.getFirstElement();
+
+				// open file in editor
+				if (obj instanceof TreeObject) {
+					openEditor((TreeObject) obj);
+				}
+			}
+		};
+
+		// data capture
+		traceAction = new Action() {
+			@Override
+			public void run() {
+
+				// if trace is active => stop the trace
+				if (traceActive) {
+					stop(true);
+				}
+				// if trace is not active => start the trace
+				else {
+					start();
+				}
+			}
+		};
+		traceAction.setText(Constants.ACTION_START_TRACE);
+		traceAction.setToolTipText(Constants.ACTION_START_TRACE);
+		traceAction.setImageDescriptor(Activator
+				.getImageDescriptor((Constants.BUTTON_RUN)));
+
+		// if trace actions are disabled
+		if (!enableTrace) {
+			traceAction.setEnabled(false);
+			traceAction.setToolTipText(Constants.TRACE_NOT_FOUND);
+		}
+
+		// build with atool
+		buildWithAtool = new Action() {
+			@Override
+			public void run() {
+				activateAnalysisBuild();
+			}
+		};
+		buildWithAtool.setText(Constants.ACTION_AT_BUILD_ACTIVE);
+		buildWithAtool.setToolTipText(Constants.ACTION_AT_BUILD_ACTIVE);
+		buildWithAtool.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_BUILD));
+
+		// clean atool changes
+		cleanAtoolChanges = new Action() {
+			@Override
+			public void run() {
+				clean();
+			}
+		};
+		cleanAtoolChanges.setText(Constants.ACTION_CLEAR_CHANGES);
+		cleanAtoolChanges
+				.setToolTipText(Constants.ACTION_CLEAR_CHANGES_TOOLTIP);
+		cleanAtoolChanges.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_CLEAN));
+
+		// change detail level
+		changeDetails = new Action() {
+			@Override
+			public void run() {
+				changeDetailLevel();
+			}
+		};
+		changeDetails.setText(Constants.ACTION_CHANGE_REPORT_LEVEL);
+
+		// save report( xml ) file
+		saveReportAction = new Action() {
+			@Override
+			public void run() {
+				saveReportFile(Constants.SAVE_REPORT_FILE_XML);
+			}
+		};
+		saveReportAction.setText(Constants.ACTION_SAVE_REPORT);
+		saveReportAction.setToolTipText(Constants.ACTION_SAVE_REPORT);
+
+		// save data file
+		saveDataFileAction = new Action() {
+			@Override
+			public void run() {
+				saveReportFile(Constants.SAVE_REPORT_FILE_DATA);
+
+			}
+		};
+		saveDataFileAction.setText(Constants.ACTION_SAVE_DATA);
+		saveDataFileAction.setToolTipText(Constants.ACTION_SAVE_DATA);
+
+		// start subtest
+		startSubtest = new Action() {
+			@Override
+			public void run() {
+				startSubTest();
+			}
+		};
+		startSubtest.setText(Constants.ACTION_START_SUBTEST);
+		startSubtest.setToolTipText(Constants.ACTION_START_SUBTEST);
+		startSubtest.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_START_SUBTEST));
+
+		// stop subtest
+		stopSubtest = new Action() {
+			@Override
+			public void run() {
+				stopSubTest();
+			}
+		};
+		stopSubtest.setText(Constants.ACTION_STOP_SUBTEST);
+		stopSubtest.setToolTipText(Constants.ACTION_STOP_SUBTEST);
+		stopSubtest.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_STOP_SUBTEST));
+		stopSubtest.setDescription(Constants.ACTION_STOP_SUBTEST);
+
+		// set start and stop subtest not visible at the beginning
+		startSubtest.setEnabled(false);
+		stopSubtest.setEnabled(false);
+
+		analyzeResults = new Action() {
+			@Override
+			public void run() {
+				analyzeDataFile(Constants.ANALYZE_ASK_FOR_USER, null, true);
+			}
+		};
+
+		analyzeResults.setText(Constants.ACTION_OPEN);
+		analyzeResults.setToolTipText(Constants.ACTION_OPEN);
+		analyzeResults.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_OPEN));
+
+		clearProjectResults = new Action() {
+			@Override
+			public void run() {
+				cleanAnalyzeData(project);
+				if(statisticView != null ) {
+					statisticView.clean(project);
+				}
+				updateChangeDetailState(project);
+			}
+		};
+		clearProjectResults.setText(Constants.ACTION_CLEAR_RESULTS);
+		clearProjectResults.setToolTipText(Constants.ACTION_CLEAR_RESULTS);
+
+		refreshResults = new Action() {
+			@Override
+			public void run() {
+				if( project != null && project.isOpen() && projectResults != null ) {
+					String dataFile = projectResults.getDataFileName(project);
+					if( dataFile != null || !("").equals(dataFile) ) {
+						analyzeDataFile(Constants.ANALYZE_USE_DATA_FILE, dataFile, true);
+					}
+					else {
+						//some internal error occurred => disable this action
+						refreshResults.setEnabled(false);
+					}
+
+				}
+			}
+		};
+		refreshResults.setText(Constants.ACTION_RE_ANALYZE);
+		refreshResults.setToolTipText(Constants.ACTION_RE_ANALYZE_TOOLTIP);
+		refreshResults.setEnabled(false);
+
+		//copy active item contents to clipboard
+		copyAction = new Action(){
+			@Override
+			public void run() {
+				//copy active item contents to clipboard
+
+				//Create new clipboard object
+				Clipboard cp = new Clipboard(runView.getControl().getDisplay());
+
+				//Create new TextTransfer object
+				//TextTransfer converts plain text represented as a java String to a platform specific representation of the data and vice versa
+				TextTransfer tt = TextTransfer.getInstance();
+
+				//new StringBuffer which contains the copied text
+				StringBuffer sb = new StringBuffer(64);
+
+				// chech that project contains results
+				if( projectResults == null || !projectResults.contains(project) || activeTreeItem == null ) {
+					return;
+				}
+				//get active item info (also callstack info)
+				AnalysisItem item = null;
+
+				// if selected item is subtest
+				if( activeTreeItem.isSubTest() ) {
+					item = projectResults.getSubtestItem(project,
+							activeTreeItem.getRunID(), activeTreeItem.getMemLeakID(),
+							activeTreeItem.getSubtestID());
+				}
+				else {
+					item = projectResults.getSpecific(project, activeTreeItem.getRunID(), activeTreeItem.getMemLeakID());
+				}
+
+				// check that item found
+				if( item == null ) {
+					return;
+				}
+
+				sb.append(activeTreeItem.getName());
+				String separator = System.getProperty ( "line.separator" );
+				sb.append(separator);
+				char space = ' ';
+				AbstractList<CallstackItem> callstackItems = item.getCallstackItems();
+				Iterator<CallstackItem> iterCallstack = callstackItems.iterator();
+				while( iterCallstack.hasNext() ) {
+					CallstackItem oneItem = iterCallstack.next();
+					sb.append("      ");
+					sb.append(oneItem.getMemoryAddress());
+					sb.append(space);
+					sb.append(oneItem.getModuleName());
+					sb.append(space);
+					sb.append(oneItem.getFunctionName());
+					sb.append(space);
+					sb.append(oneItem.getFileName());
+					sb.append(space);
+					int lineNbr = oneItem.getLeakLineNumber();
+					if( lineNbr > 0 ) {
+						sb.append(lineNbr);
+					}
+					sb.append(separator);
+				}
+
+				//info is ready => now copy info to clipboard
+				cp.setContents(new Object[] { sb.toString() },
+			            new Transfer[] { tt });
+			}
+		};
+		copyAction.setText(Constants.ACTION_COPY);
+		copyAction.setEnabled(false);
+		
+		// open preferences action
+		openPrefs = new Action() {
+			@Override
+			public void run() {
+				PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+						Constants.ANALYZE_TOOL_PREFS_ID, null, null);
+				
+				if( dialog != null ) {
+					dialog.open();
+				}
+			}
+		};
+		openPrefs.setText(Constants.ACTION_OPEN_PREFS);
+		openPrefs.setToolTipText(Constants.ACTION_OPEN_PREFS_TOOLTIP);
+		openPrefs.setImageDescriptor(Activator.getImageDescriptor(Constants.BUTTON_OPEN_PREFS));
+		
+		changeReportActionTooltip();
+		updateChangeDetailState(project);
+		updateBuildState(project);
+	}
+
+	/**
+	 * Creates file open actions.
+	 */
+	private void makeFileOpenActions() {
+		fileOpenMenu.setText(Constants.ACTION_OPEN);
+		fileOpenMenu.setToolTipText(Constants.ACTION_OPEN);
+		fileOpenMenu.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_OPEN));
+	}
+
+	/**
+	 * Creates file open actions.
+	 */
+	private void makeLogTargetActions() {
+
+		s60LogTargetAction = new Action(Constants.LOGGING_S60, Action.AS_RADIO_BUTTON) {
+			@Override
+			public void run() {
+				changeLogTarget(Constants.LOGGING_S60);
+			}
+		};
+		s60LogTargetAction.setText(Constants.PREFS_S60);
+		s60LogTargetAction
+				.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_S60);
+		s60LogTargetAction.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_CELLURAR));
+
+		externalLogTargetAction = new Action(Constants.LOGGING_EXT, Action.AS_RADIO_BUTTON) {
+			@Override
+			public void run() {
+				changeLogTarget(Constants.LOGGING_EXT);
+			}
+		};
+		externalLogTargetAction.setText(Constants.PREFS_EXT);
+		externalLogTargetAction
+				.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_EXT);
+		externalLogTargetAction.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_COMPUTER));
+
+		externalFastLogTargetAction = new Action(Constants.LOGGING_EXT_FAST, Action.AS_RADIO_BUTTON) {
+			@Override
+			public void run() {
+				changeLogTarget(Constants.LOGGING_EXT_FAST);
+			}
+		};
+		externalFastLogTargetAction.setText(Constants.PREFS_EXT_FAST);
+		externalFastLogTargetAction.setToolTipText(Constants.PREFS_EXT_FAST_TOOLTIP);
+		externalFastLogTargetAction.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_COMPUTER_FAST));
+
+		askLogTargetAction = new Action(Constants.LOGGING_ASK_ALLWAYS, Action.AS_RADIO_BUTTON) {
+			@Override
+			public void run() {
+				changeLogTarget(Constants.LOGGING_ASK_ALLWAYS);
+			}
+		};
+
+
+		askLogTargetAction.setText(Constants.PREFS_ASK_ALWAYS);
+		askLogTargetAction
+				.setToolTipText(Constants.ACTION_CHANGE_LOGGING_MODE_TOOLTIP_ASK);
+		askLogTargetAction.setImageDescriptor(Activator
+				.getImageDescriptor(Constants.BUTTON_ASK));
+
+	}
+
+	/**
+	 * Opens current callstack item on default editor and pinpoints memory leak.
+	 * line
+	 *
+	 * @param treeObject
+	 *            Tree object
+	 */
+	public final void openEditor(final TreeObject treeObject) {
+		// get file info for all projects
+		getFileInfos(project);
+
+		try {
+
+			// if no project selected
+			if (project == null || !project.isOpen()) {
+				Util.showMessage(Constants.NO_PROJ_SELECT);
+				return;
+			}
+
+			// get selected call stack item
+			CallstackItem callstackItem = treeObject.getCallstackItem();
+			if (callstackItem == null) {
+				return;
+			}
+
+			String cppFileName = getCallstackItemName(callstackItem);
+
+			if (cppFileName == null || ("").equals(cppFileName)) {
+				cppFileName = callstackItem.getFileName();
+			}
+
+			// if leak number is invalid => leave
+			if (callstackItem.getLeakLineNumber() < 1) {
+				return;
+			}
+
+			String line = Integer.toString(callstackItem.getLeakLineNumber());
+
+			IFile file = null;
+			if (project.isOpen()) {
+				file = ResourcesPlugin.getWorkspace().getRoot().getFile(
+						new Path(project.getName() + "\\" + cppFileName));
+			}
+
+			// if file not found in active project
+			// go thru all open projects in current workbench
+			if (file == null || !file.exists()) {
+				IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace()
+						.getRoot();
+				IProject[] projects = myWorkspaceRoot.getProjects();
+				for (int i = 0; i < projects.length; i++) {
+					file = ResourcesPlugin.getWorkspace().getRoot()
+							.getFile(
+									new Path(projects[i].getName() + "\\"
+											+ cppFileName));
+
+					// file found => skip the rest of the projects
+					if (file != null && file.exists()) {
+						break;
+					}
+				}
+
+			}
+
+			// if file still not found
+			// display info to user and leave
+			if (file == null || !file.exists()) {
+				Util.showMessage(Constants.SOURCE_NOT_FOUND);
+				return;
+			}
+
+			IWorkbenchPage page = PlatformUI.getWorkbench()
+					.getActiveWorkbenchWindow().getActivePage();
+
+			HashMap<String, Object> map = new HashMap<String, Object>();
+			map.put(IMarker.LINE_NUMBER, Integer.parseInt(line));
+			map.put(IDE.EDITOR_ID_ATTR, Constants.SOURCE_FILE_EDITOR_ID);
+			IMarker marker = file.createMarker(IMarker.TEXT);
+			marker.setAttributes(map);
+			IDE.openEditor(page, marker);
+
+		} catch (NullPointerException npe) {
+			npe.printStackTrace();
+		} catch (CoreException ce) {
+			ce.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Updates log target action and report action tooltips.
+	 *
+	 * @see com.nokia.s60tools.analyzetool.ui.IActionListener#preferenceChanged()
+	 */
+	public void preferenceChanged() {
+		// get active logging mode
+		changeLogTarget(null);
+
+		changeReportActionTooltip();
+	}
+
+	/**
+	 * Refresh AnalyzeTool view.
+	 */
+	public final void refreshView() {
+		// update display content
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+
+				updateInformationLabel("");
+
+				// refresh view
+				runView.setInput(getResults(false));
+
+				// refresh callstack view
+				getCallStack(activeTreeItem);
+				if( project != null && project.isOpen() && projectResults.contains(project)) {
+					clearProjectResults.setEnabled(true);
+				}
+				else {
+					clearProjectResults.setEnabled(false);
+				}
+				updateChangeDetailState(project);
+
+			}
+		});
+	}
+
+	/**
+	 * Runs user selected AnalyzeTool action.
+	 *
+	 * @see com.nokia.s60tools.analyzetool.ui.IActionListener#runAction(IProject, com.nokia.s60tools.analyzetool.global.Constants.ACTIONS)
+	 *
+	 * @param projectRef
+	 *            Project reference
+	 *
+	 * @param action
+	 *            Which action to execute
+	 */
+	public void runAction(IProject projectRef, Constants.ACTIONS action) {
+		project = projectRef;
+
+		switch (action) {
+		case RUN_VIEW_MEM_LEAKS:
+			analyzeResults.run();
+			break;
+
+		case RUN_BUILD:
+			buildWithAtool.run();
+			break;
+
+		case RUN_CLEAN:
+			cleanAtoolChanges.run();
+			break;
+
+		default: // by design default statement is empty
+			break;
+		}
+	}
+
+	/**
+	 * Saves existing report or data file asks user where to save.
+	 *
+	 * @param type
+	 *            Which kind of type the file is. Possible types xml or data
+	 *            file
+	 *
+	 * @return True if saving successfully otherwise false
+	 */
+	public final boolean saveReportFile(final int type) {
+		// copy success?
+		boolean success = false;
+
+		// check if project is selected
+		if (project == null) {
+			showMessage(Constants.NO_PROJ_SELECT);
+			return success;
+		}
+
+		// folder location
+		String folder = null;
+
+		// file path and name to use
+		String usedFile = null;
+
+		// save xml file
+		if (type == Constants.SAVE_REPORT_FILE_XML) {
+			String targetPath = Util.getBldInfFolder(project, true)
+					+ Constants.FILENAME_CARBIDE;
+			java.io.File file = new java.io.File(targetPath);
+			if (file.exists()) {
+				String[] names = new String[2];
+				names[0] = "*.xml";
+				names[1] = "*.*";
+
+				Shell shell = null;
+
+				// get shell from teh active view
+				if (runView != null) {
+					shell = runView.getControl().getShell();
+				}
+
+				// if for some reason shell is null => leave
+				if (shell == null) {
+					return success;
+				}
+
+				// ask user where to save xml report file
+				folder = Util.fileSaveDialog(Constants.DIALOG_SAVE_REPORT,
+						names, shell);
+				usedFile = targetPath;
+			} else {
+				Util.showMessage(Constants.INFO_NO_RESULTS_FILE);
+				return success;
+			}
+
+		}
+		// save data file
+		else {
+			String dataFile = Util.isDataFileAvailable(project);
+			// check is there data file which can be used
+			if ((dataFile == null || dataFile.equals(""))
+					&& (usedDataFileName == null || usedDataFileName.equals(""))) {
+				Util.showMessage(Constants.INFO_NO_DATA_FILE);
+				return success;
+			}
+			// if no existing data file opened
+			else if (usedDataFileName == null || usedDataFileName.equals("")) {
+				usedFile = dataFile;
+
+			}
+			// user is already opened data file => save it
+			else {
+				usedFile = usedDataFileName;
+			}
+
+			String[] names = new String[2];
+			names[0] = "*.dat";
+			names[1] = "*.*";
+
+			Shell shell = null;
+
+			// get shell from teh active view
+			if (runView != null) {
+				shell = runView.getControl().getShell();
+			}
+
+			// if for some reason shell is null => leave
+			if (shell == null) {
+				return success;
+			}
+
+			// ask user where to save xml report file
+			folder = Util.fileSaveDialog(Constants.DIALOG_SAVE_TRACE, names,
+					shell);
+		}
+
+		// no folder selected
+		// user press "cancel" button;
+		if (folder == null) {
+			return success;
+		}
+
+		// copy file to folder
+		success = Util.copyFileToFolder(usedFile, folder);
+
+		// report to user
+		if (success) {
+			Util.showMessage(Constants.INFO_SAVE_SUCCESS + folder);
+		} else {
+			Util.showMessage(Constants.MAIN_CAN_NOT_COPY + usedFile);
+		}
+		return success;
+	}
+
+	/**
+	 * Notifies this action delegate that the selection in the workbench has
+	 * changed.
+	 *
+	 * @param part
+	 *            Workbench part
+	 *
+	 * @param selection
+	 *            User selection
+	 */
+	@SuppressWarnings("restriction")
+	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+		// project reference
+		IProject selectedProject = null;
+
+		// check where the selection comes
+		// supported views: CommonNavigator and SymbianProjectNavigator
+		if (!(part instanceof org.eclipse.ui.navigator.CommonNavigator) ) {
+			return;
+		}
+
+		// get selection
+		IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+
+		// get first element of selection
+		Object element = structuredSelection.getFirstElement();
+
+		// check selection
+		if (element instanceof IAdaptable) {
+			IAdaptable adaptable = (IAdaptable) element;
+
+			IResource resource = null;
+			if (adaptable instanceof IResource) {
+				resource = (IResource) adaptable;
+			} else if (adaptable instanceof org.eclipse.cdt.internal.ui.cview.IncludeRefContainer) {
+				selectedProject = ((org.eclipse.cdt.internal.ui.cview.IncludeRefContainer) adaptable)
+						.getCProject().getProject();
+			} else if (adaptable instanceof org.eclipse.cdt.core.model.ICProject) {
+				selectedProject = ((org.eclipse.cdt.core.model.ICProject) adaptable)
+						.getProject();
+			} else {
+				resource = (IResource) adaptable
+						.getAdapter(IResource.class);
+			}
+
+			// resource found => get resource project
+			if (resource != null) {
+				selectedProject = resource.getProject();
+			}
+
+		}
+		// first item is null => update build state
+		else if (element == null) {
+			updateBuildState(null);
+		}
+
+		// if project found and it is open => get project results
+		if (selectedProject != null && selectedProject.isOpen()) {
+			project = selectedProject;
+			getProjectResults(selectedProject);
+			updateBuildState(project);
+			if( statisticView != null ) {
+				statisticView.handleProjectChange(project);
+			}
+		}
+	}
+
+
+	/**
+	 * Executes clicAction when user selects item in the AnalyzeTool view.
+	 *
+	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+	 *
+	 * @param event
+	 *            Selection changed event
+	 */
+	public void selectionChanged(SelectionChangedEvent event) {
+		clickAction.run();
+	}
+
+	/**
+	 * Passing the focus request to the viewer's control.
+	 */
+	@Override
+	public void setFocus() {
+		runView.getControl().setFocus();
+
+	}
+
+	/**
+	 * Sets text to information label.
+	 */
+	public final void setTextToInformationLabel() {
+		if (activeTreeItem == null) {
+			return;
+		}
+
+		// run information
+		RunResults oneRunResults = projectResults.getRun(project,
+				activeTreeItem.getRunID());
+
+		// no results found => update label
+		if (oneRunResults == null) {
+			updateInformationLabel("");
+		} else {
+			StringBuffer buffer = new StringBuffer(32);
+			buffer.append("Run: ");
+			buffer.append(oneRunResults.getItemID());
+
+			buffer.append(" Memory leaks: ");
+			buffer.append(oneRunResults.getAnalysisItems().size());
+			buffer.append(" Handle leaks: ");
+			buffer.append(oneRunResults.getHandleLeaks().size());
+			if (("").equals(oneRunResults.getEndTime())) {
+				buffer.append("\nStart time: " + oneRunResults.getStartTime()
+						+ " \nEnd time: FAILED");
+			} else {
+				buffer.append("\nStart time: " + oneRunResults.getStartTime()
+						+ " \nEnd time: " + oneRunResults.getEndTime());
+			}
+
+			updateInformationLabel(buffer.toString());
+
+		}
+
+	}
+
+	/**
+	 * Shows error message.
+	 *
+	 * @param message
+	 *            Error message to show
+	 */
+	public final void showErrorMessage(final String message) {
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				Util.showErrorMessage(message);
+			}
+		});
+	}
+
+	/**
+	 * Shows message.
+	 *
+	 * @param message
+	 *            Message to show
+	 */
+	public final void showMessage(final String message) {
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				Util.showMessage(message);
+			}
+		});
+	}
+
+	/**
+	 * Starts traceviewer connection.
+	 */
+	private void start() {
+		// check is project selected and open
+		if (!checkProjectValidity()) {
+			return;
+		}
+
+		// get project file infos
+		getFileInfos(project);
+
+		String dataFile = Util.isDataFileAvailable(project);
+		// if data file already exists, ask for overwrite
+		if (dataFile != null && !dataFile.equalsIgnoreCase("")) {
+			int saveDataFiles = Util
+					.openConfirmationDialogWithCancel(Constants.CONFIRM_OVERWRITE_FILE);
+			if (saveDataFiles == Constants.SAVE_DATA_FILE) {
+				if (!saveReportFile(Constants.SAVE_REPORT_FILE_DATA)) {
+					return;
+				}
+			} else if (saveDataFiles == Constants.SAVE_DATA_FILE_CANCEL) {
+				// user press "Cancel" so return and do nothing
+				return;
+			}
+
+			// delete existing data file
+			Util.deleteDataFile(project);
+		}
+
+		ICarbideProjectInfo info = CarbideBuilderPlugin.getBuildManager().getProjectInfo(project);
+		ICarbideBuildConfiguration config = info.getDefaultConfiguration();
+
+		//start listening emulator output
+		if( config.getPlatformString().equals(Constants.BUILD_TARGET_WINSCW) ) {
+
+			listeningJob = new EpocReader(project, this);
+			listeningJob.start();
+
+			traceStarted();
+
+			return;
+		}
+
+		// else start trace capturing using Tracing utility connection
+
+		// main view class instance
+		// this instance if passed to the TraceWrapper class
+		final MainView selfInstance = this;
+		Job activateTrace = new Job(Constants.STARTING_TRACE) {
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				try {
+
+					// update progress monitor state
+					monitor.beginTask(Constants.STARTING_TRACE,
+							IProgressMonitor.UNKNOWN);
+
+					// load TraceWrapper class
+					Class<?> buildManagerClass = Class
+							.forName("com.nokia.s60tools.analyzetool.trace.TraceWrapper");
+
+					// get TraceWrapper class available methods
+					java.lang.reflect.Method[] methods = buildManagerClass
+							.getMethods();
+
+					// thru methods
+					for (int i = 0; i < methods.length; i++) {
+						// get one method
+						java.lang.reflect.Method oneMethod = methods[i];
+
+						// if method name is "connect"
+						if (oneMethod.getName().equalsIgnoreCase("connect")) {
+
+							// parameters for the connect method
+							Object[] objs = new Object[1];
+							objs[0] = selfInstance;
+
+							// call connect method
+							String returnValue = (String) oneMethod.invoke(
+									buildManagerClass.newInstance(), objs);
+
+							// if there was no errors while connection
+							if (("").equals(returnValue)) {
+
+								// invoke parser to open needed streams
+								parser.openStreams(Util.getBldInfFolder(
+										project, true));
+
+								traceStarted();
+							} else {
+								traceAction
+										.setImageDescriptor(Activator
+												.getImageDescriptor((Constants.BUTTON_RUN)));
+								traceActive = false;
+
+								showErrorMessage(returnValue);
+							}
+						}
+					}
+				} catch (ClassNotFoundException cnfe) {
+					cnfe.printStackTrace();
+
+				} catch (SecurityException se) {
+					se.printStackTrace();
+
+				} catch (IllegalAccessException iae) {
+					iae.printStackTrace();
+
+				} catch (IllegalArgumentException iare) {
+					iare.printStackTrace();
+
+				} catch (java.lang.reflect.InvocationTargetException ite) {
+					ite.printStackTrace();
+
+				} catch (InstantiationException iv) {
+					iv.printStackTrace();
+				}
+
+				return new Status(IStatus.OK, Constants.ANALYZE_CONSOLE_ID,
+						IStatus.OK, "Trace started", null);
+			}
+		};
+		activateTrace.setUser(true);
+		activateTrace.schedule();
+
+	}
+
+	/**
+	 * Starts subtests.
+	 */
+	public final void startSubTest() {
+		// get started processes
+		Hashtable<String, Integer> startedPros = null;
+
+		// if parser exists => means that the tracing is started and processes
+		// info is available
+		if (parser != null) {
+			startedPros = parser.getStartedProcesses();
+		}
+
+		// no processes = >show info and leave
+		if (startedPros == null || startedPros.isEmpty()) {
+			Util.showMessage(Constants.SUBTEST_NO_PROCESSES);
+			return;
+		}
+
+		// get started target info
+		AbstractList<String> targets = new ArrayList<String>();
+		for (java.util.Enumeration<String> e = startedPros.keys(); e
+				.hasMoreElements();) {
+			String processName = e.nextElement();
+			targets.add(processName);
+		}
+
+		// used target
+		String target = null;
+
+		// processes found, print info to user
+		if (targets.size() == 1) {
+			target = targets.get(0);
+		} else {
+			target = Util.openSelectionDialog(Constants.SUBTEST_SELECT_TARGET,
+					Constants.SUBTEST_RUNNING_PROCESSES_INFO, targets);
+
+		}
+		if (target == null || ("").equals(target) ) {
+			return;
+		}
+
+		// ask for subtest name
+		CustomInputDialog dialog = new CustomInputDialog(
+				Constants.ANALYZE_TOOL_TITLE, Constants.SUBTEST_INPUT_NAME, "");
+		dialog.open();
+		String subTestName = dialog.getUserInput();
+
+		if (subTestName == null || subTestName.length() == 0) {
+			return;
+		}
+
+		// get process id for selected target
+		int processID = startedPros.get(target);
+
+		// if subtest allready exists
+		if (isSubtestExists(subTestName, target)) {
+			Util.showMessage(Constants.SUBTEST_ALLREADY_RUNNING);
+			return;
+		}
+
+		// create new subtes object and add it to AbstractList
+		ActiveSubtests subtes = new ActiveSubtests(subTestName, target,
+				processID);
+		startedSubtest.add(subtes);
+
+		// start subtest
+		parser.parse(Constants.PREFIX + " " + processID + " TEST_START 0000 "
+				+ subTestName);
+		updateSubtestInfoText(Constants.SUBTEST_STARTED + target
+				+ Constants.ENRULE + subTestName);
+
+		stopSubtest.setEnabled(true);
+	}
+
+	/**
+	 * Stop external message tracing.
+	 */
+	public final void stop(boolean analyze) {
+
+		ICarbideProjectInfo info = CarbideBuilderPlugin.getBuildManager().getProjectInfo(project);
+		ICarbideBuildConfiguration config = info.getDefaultConfiguration();
+		if( config.getPlatformString().equalsIgnoreCase(Constants.BUILD_TARGET_WINSCW) ) {
+			listeningJob.stop();
+			traceStopped(analyze);
+			return;
+		}
+
+		//else stop Tracing utility connection
+		try {
+			Class<?> buildManagerClass = Class
+					.forName("com.nokia.s60tools.analyzetool.trace.TraceWrapper");
+
+			java.lang.reflect.Method[] methods = buildManagerClass.getMethods();
+			for (int i = 0; i < methods.length; i++) {
+				java.lang.reflect.Method oneMethod = methods[i];
+				if (oneMethod.getName().equalsIgnoreCase("disconnect")) {
+
+					Object[] objs = new Object[1];
+					objs[0] = this;
+					String returnValue = (String) oneMethod.invoke(
+							buildManagerClass.newInstance(), new Object[] {});
+					if (("").equals(returnValue)) {
+						traceStopped(analyze);
+					} else {
+						showErrorMessage("Error while disconnecting Tracing utility");
+						traceAction.setImageDescriptor(Activator
+								.getImageDescriptor((Constants.BUTTON_STOP)));
+						traceActive = true;
+					}
+				}
+			}
+		} catch (ClassNotFoundException cnfe) {
+			cnfe.printStackTrace();
+
+		} catch (SecurityException se) {
+			se.printStackTrace();
+
+		} catch (IllegalAccessException iae) {
+			iae.printStackTrace();
+
+		} catch (IllegalArgumentException iare) {
+			iare.printStackTrace();
+
+		} catch (java.lang.reflect.InvocationTargetException ite) {
+			ite.printStackTrace();
+
+		} catch (InstantiationException iv) {
+			iv.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * Updates button states and creates results for project.
+	 */
+	private void traceStopped(boolean analyze) {
+		// update icon and information text
+		traceAction.setImageDescriptor(Activator
+				.getImageDescriptor((Constants.BUTTON_RUN)));
+		traceAction.setText(Constants.ACTION_START_TRACE);
+		traceAction
+				.setToolTipText(Constants.ACTION_START_TRACE);
+		traceActive = false;
+
+		// close any active subtests
+		if (!startedSubtest.isEmpty()) {
+			for (int j = 0; j < startedSubtest.size(); j++) {
+				ActiveSubtests oneSubtest = startedSubtest
+						.get(j);
+				parser.parse(Constants.PREFIX + " "
+						+ oneSubtest.getProcessID()
+						+ " TEST_END" + " 0000 "
+						+ oneSubtest.getName());
+			}
+			startedSubtest.clear();
+		}
+
+		// tell parser to finish => write data to file
+		parser.finish();
+
+		// inform user
+		updateLabel(Constants.INFO_TRACE_STOP);
+
+		// set start and stop trace not visible
+		startSubtest.setEnabled(false);
+		stopSubtest.setEnabled(false);
+		fileOpenMenu.setEnabled(true);
+		saveFileMenu.setEnabled(true);
+		cleanAtoolChanges.setEnabled(true);
+
+		project = traceStartedProjectRef;
+
+		// parse and analyze saved data file
+		if( analyze ) {
+			analyzeDataFile(Constants.ANALYZE_USE_DATA_FILE, null,
+					true);	
+		}
+	}
+
+	/**
+	 * Stop one subtest If there multiple subtest running ask for user to which
+	 * one to stop.
+	 */
+	public final void stopSubTest() {
+		// no processes show info
+		if (startedSubtest.isEmpty()) {
+			Util.showMessage(Constants.SUBTEST_NO_SUBTESTS);
+		} else {
+			// only one subtest no need to ask for users
+			if (startedSubtest.size() == 1) {
+				ActiveSubtests oneSubtest = startedSubtest.get(0);
+				parser.parse(Constants.PREFIX + " " + oneSubtest.getProcessID()
+						+ " TEST_END" + " 0000 " + oneSubtest.getName());
+				updateSubtestInfoText(Constants.SUBTEST_ENDED
+						+ oneSubtest.getTargetName() + Constants.ENRULE
+						+ oneSubtest.getName());
+				startedSubtest.remove(0);
+				stopSubtest.setEnabled(false);
+			} else { // multiple subtest found ask for the user which to stop
+				// multiple subtest found ask for user which to be ended
+				AbstractList<String> tmpSubtest = new ArrayList<String>();
+
+				// get list of active subtests
+				for (int i = 0; i < startedSubtest.size(); i++) {
+					ActiveSubtests oneSubtest = startedSubtest.get(i);
+					String tmpStr = oneSubtest.getTargetName()
+							+ Constants.ENRULE + oneSubtest.getName();
+					tmpSubtest.add(tmpStr);
+				}
+
+				String selection = Util.openSelectionDialog(
+						Constants.SUBTEST_SELECT_SUBTEST_TO_STOP, null,
+						tmpSubtest);
+				// thru active subtests
+				for (int k = 0; k < startedSubtest.size(); k++) {
+					// get one subtest
+					ActiveSubtests oneSubtest = startedSubtest.get(k);
+
+					// split user selected subtest information to get subtest
+					// name
+					String[] splittedText = selection.split(" ");
+
+					// if user selected subtest name and current subtest equals
+					if (splittedText[2].equals(oneSubtest.getName())) {
+						// write subtest end tag to data file
+						parser.parse(Constants.PREFIX + " "
+								+ oneSubtest.getProcessID() + " TEST_END"
+								+ " 0000 " + oneSubtest.getName());
+						updateSubtestInfoText(Constants.SUBTEST_ENDED
+								+ oneSubtest.getTargetName() + Constants.ENRULE
+								+ oneSubtest.getName());
+						// remove current subtest from active subtest
+						// AbstractList
+						startedSubtest.remove(k);
+						break;
+					}
+				}
+
+				if (startedSubtest.isEmpty()) {
+					stopSubtest.setEnabled(false);
+				}
+			}
+		}
+	}
+
+	/**
+	 * When AnalyzeTool view tree model is collapsed.
+	 *
+	 * @see org.eclipse.jface.viewers.ITreeViewerListener#treeCollapsed(org.eclipse.jface.viewers.TreeExpansionEvent)
+	 *
+	 * @param event
+	 *            Tree expansion event
+	 */
+	public void treeCollapsed(TreeExpansionEvent event) {
+		// MethodDeclaration/Block[count(BlockStatement) = 0 and
+		// @containsComment = 'false']
+	}
+
+	/**
+	 * When AnalyzeTool view tree model is expanded.
+	 *
+	 * @see org.eclipse.jface.viewers.ITreeViewerListener#treeExpanded(org.eclipse.jface.viewers.TreeExpansionEvent)
+	 *
+	 * @param event
+	 *            Tree expansion event
+	 */
+	public void treeExpanded(TreeExpansionEvent event) {
+		// MethodDeclaration/Block[count(BlockStatement) = 0 and
+		// @containsComment = 'false']
+	}
+
+	/**
+	 * Updates allocation count in the information label.
+	 *
+	 * The information layout is hard to modify so we need to manage information
+	 * label text
+	 */
+	public final void updateAllocNumber() {
+
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+
+				// if lable is created
+				if (informationLabel != null) {
+					// get existing label text
+					String tmpText = informationLabel.getText();
+
+					// split existing text
+					String[] strArray = tmpText.split(lineFeed);
+
+					// if text contains more than 3 lines
+					if (strArray.length >= 2) {
+						// create new buffer
+						StringBuffer tmpBuffer = new StringBuffer(
+								strArray.length);
+
+						// set memory allocation size
+						strArray[1] = Constants.INFO_ALLOCATED_MEM
+								+ parser.getAllocationsSize();
+
+						// get updated text to buffer
+						for (int i = 0; i < strArray.length; i++) {
+							tmpBuffer.append(strArray[i]);
+							tmpBuffer.append(lineFeed);
+						}
+
+						// set new text to information label
+						informationLabel.setText(tmpBuffer.toString());
+					} else {
+						informationLabel.setText(tmpText + lineFeed
+								+ Constants.INFO_ALLOCATED_MEM
+								+ parser.getAllocationsSize());
+					}
+
+				}
+
+			}
+		});
+
+	}
+
+	/**
+	 * Update build action icon and tooltip text.
+	 *
+	 * @param projectRef
+	 *            Project reference
+	 */
+	public final void updateBuildState(final IProject projectRef) {
+		if (buildWithAtool == null) {
+			return;
+		}
+
+		BuilderUtil util = new BuilderUtil();
+
+		// if project is not selected
+		if (projectRef == null) {
+			buildWithAtool.setText(Constants.ACTION_AT_BUILD_DEACTIVE);
+			buildWithAtool.setToolTipText(Constants.ACTION_AT_BUILD_DEACTIVE);
+			buildWithAtool.setChecked(false);
+		}
+		// if AnalyzeTool build is enabled
+		else if (util.isNatureEnabled(projectRef)) {
+			buildWithAtool.setText(Constants.ACTION_AT_BUILD_ACTIVE);
+			buildWithAtool.setToolTipText(Constants.ACTION_AT_BUILD_ACTIVE);
+			buildWithAtool.setChecked(true);
+		} else {
+			buildWithAtool.setText(Constants.ACTION_AT_BUILD_DEACTIVE);
+			buildWithAtool.setToolTipText(Constants.ACTION_AT_BUILD_DEACTIVE);
+			buildWithAtool.setChecked(false);
+		}
+
+	}
+
+	/**
+	 * Indicates the target (emulator/device) by inspecting the given projects build configuration.
+	 * @param selectedProject the currently active project
+	 * @return "emulator" if the build configuration is WINSCW, "device" otherwise
+	 */
+	private static String getTraceTarget(final IProject selectedProject) {
+		String target = "";
+		if (selectedProject != null && selectedProject.isOpen()) {
+			ICarbideProjectInfo info = CarbideBuilderPlugin.getBuildManager().getProjectInfo(selectedProject);
+			if (info != null) {
+				ICarbideBuildConfiguration config = info.getDefaultConfiguration();
+				target = config.getPlatformString().equals(
+						Constants.BUILD_TARGET_WINSCW) ? Constants.INFO_TRACE_FROM_EMULATOR : Constants.INFO_TRACE_FROM_DEVICE;
+			}
+		}
+		return target;
+	}
+
+	/**
+	 * Update change detail action state.
+	 *
+	 * @param projectRef
+	 *            Current project
+	 */
+	public final void updateChangeDetailState(final IProject projectRef) {
+		if (changeDetails == null) {
+			return;
+		}
+
+		if (projectRef == null) {
+			changeDetails.setEnabled(false);
+			refreshResults.setEnabled(false);
+			return;
+		} else if (projectResults.contains(projectRef)) {
+			changeDetails.setEnabled(true);
+		} else {
+			changeDetails.setEnabled(false);
+		}
+
+		String dataFile = projectResults.getDataFileName(projectRef);
+		if( dataFile != null ) {
+			int fileType = UseAtool.checkFileType(dataFile);
+			if( fileType == Constants.DATAFILE_TRACE || fileType == Constants.DATAFILE_LOG ) {
+				refreshResults.setEnabled(true);
+			}
+			else {
+				refreshResults.setEnabled(false);
+			}
+		}
+		else {
+			refreshResults.setEnabled(false);
+		}
+	}
+
+	/**
+	 * Sets information to the information label.
+	 *
+	 * @param infoText
+	 *            Info text
+	 */
+	private void updateInformationLabel(final String infoText) {
+		// trace is active => do not update information label
+		if (traceActive) {
+			return;
+		}
+
+		// sync with the UI thread
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				// if informationlabel exists set text
+				if (informationLabel != null) {
+					informationLabel.setText(infoText);
+				}
+			}
+		});
+	}
+
+	/**
+	 * Updates label by given string.
+	 *
+	 * @param line
+	 *            String to display
+	 */
+	public final void updateLabel(final String line) {
+
+		final String oneLine = line;
+
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				// if informationlabel exists set text
+				if (informationLabel != null) {
+					informationLabel.setText(oneLine);
+				}
+
+			}
+		});
+
+	}
+
+	/**
+	 * Updates Subtest info to the information label.
+	 *
+	 * The information layout is hard to modify so we need to manage information
+	 * label text
+	 *
+	 * @param text
+	 *            New label text
+	 */
+	private void updateSubtestInfoText(final String text) {
+		final String newText = text;
+
+		runView.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+
+				// if label exists
+				if (informationLabel != null) {
+					// get existing label text
+					String origText = informationLabel.getText();
+
+					// split existing text
+					String[] strArray = origText.split(lineFeed);
+
+					// create new buffer
+					StringBuffer tmpBuffer = new StringBuffer(strArray.length);
+					if (strArray.length >= 3) {
+						// update text
+						strArray[2] = newText;
+
+						// get updated text to buffer
+						for (int i = 0; i < strArray.length; i++) {
+							tmpBuffer.append(strArray[i]);
+							tmpBuffer.append(lineFeed);
+						}
+						// set new text to information label
+						informationLabel.setText(tmpBuffer.toString());
+					} else {
+						informationLabel.setText(origText + newText);
+					}
+
+				}
+
+			}
+		});
+	}
+
+	/**
+	 * Updates button states, clears existing project data and updating view.
+	 */
+	private void traceStarted() {
+		// clear view contents
+		cleanAnalyzeData(project);
+		clearCallstackViewContent();
+		traceStartedProjectRef = project;
+
+		// change icon and information text
+		traceAction
+				.setImageDescriptor(Activator
+						.getImageDescriptor((Constants.BUTTON_STOP)));
+		traceAction
+				.setText(Constants.ACTION_STOP_TRACE);
+		traceAction
+				.setToolTipText(Constants.ACTION_STOP_TRACE);
+		traceActive = true;
+
+		String fromTarget = getTraceTarget(traceStartedProjectRef);
+		updateLabel(fromTarget.length()==0 ? Constants.INFO_TRACE_START : String.format(Constants.INFO_TRACE_FROM_TARGET_START, fromTarget));
+		// add2UserActionHistory( "Trace started for
+		// project: "
+		// +project.getName() +" at "+ Util.getTime() );
+
+		// set start and stop subtest visible
+		startSubtest.setEnabled(true);
+		stopSubtest.setEnabled(false);
+		fileOpenMenu.setEnabled(false);
+		saveFileMenu.setEnabled(false);
+		cleanAtoolChanges.setEnabled(false);
+
+		updateAllocNumber();
+	}
+
+	/**
+	 * Overrided method to capture keyevents.
+	 *
+	 * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+	 */
+	public void keyPressed(KeyEvent e) {
+
+		// C key address(hex)
+		final int CTRL_C = 0x3;
+
+		// key event character
+		int charValue = e.character;
+
+		// c key pressed
+		boolean cPressed = (charValue == CTRL_C); // This should be enough
+
+		// ctrl key pressed
+		boolean ctrlPressed = (e.stateMask & SWT.CTRL) != 0;
+
+		//if ctrl and c key pressed => run copy action
+		if(ctrlPressed & cPressed){
+			// Triggering copy action
+			copyAction.run();
+		}
+
+	}
+
+	/**
+	 * (non-Javadoc)
+	 * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+	 */
+	public void keyReleased(KeyEvent e) {
+		// This method is overrided
+	}
+}