frameworkplugins/com.nokia.s60tools.util/src/com/nokia/s60tools/util/sourcecode/internal/MapSourceFinder.java
changeset 0 61163b28edca
equal deleted inserted replaced
-1:000000000000 0:61163b28edca
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 package com.nokia.s60tools.util.sourcecode.internal;
       
    19 
       
    20 import java.io.BufferedReader;
       
    21 import java.io.File;
       
    22 import java.io.FileFilter;
       
    23 import java.io.FileInputStream;
       
    24 import java.io.FileNotFoundException;
       
    25 import java.io.FilenameFilter;
       
    26 import java.io.IOException;
       
    27 import java.io.InputStreamReader;
       
    28 import java.util.ArrayList;
       
    29 import java.util.Collection;
       
    30 import java.util.HashSet;
       
    31 import java.util.Iterator;
       
    32 import java.util.Stack;
       
    33 import java.util.regex.Pattern;
       
    34 import com.nokia.s60tools.util.cmdline.CmdLineExeption;
       
    35 import com.nokia.s60tools.util.cmdline.UnsupportedOSException;
       
    36 import com.nokia.s60tools.util.console.IConsolePrintUtility;
       
    37 import com.nokia.s60tools.util.internal.Messages;
       
    38 import com.nokia.s60tools.util.resource.FileUtils;
       
    39 import com.nokia.s60tools.util.sourcecode.CannotFoundFileException;
       
    40 import com.nokia.s60tools.util.sourcecode.ISourceFinder;
       
    41 import com.nokia.s60tools.util.sourcecode.ISourcesFinder;
       
    42 import com.nokia.s60tools.util.sourcecode.SourceFileLocation;
       
    43 
       
    44 /**
       
    45  * Class for founding source file location from .map files.
       
    46  */
       
    47 public class MapSourceFinder implements ISourceFinder, ISourcesFinder {
       
    48 
       
    49 	//
       
    50 	// Private constants used in map file seeking and parsing
       
    51 	//
       
    52 	private static final String CLASS_SEPARATOR = "::";//$NON-NLS-1$
       
    53 	private static final String SEMI_COLON = ";";//$NON-NLS-1$
       
    54 	private static final String COMMENT_START = "/*";//$NON-NLS-1$
       
    55 	private static final String COMMENT_END = "*/";//$NON-NLS-1$
       
    56 	private static final String CODE_COMMENT_PREFIX = "//";//$NON-NLS-1$
       
    57 	private static final String DLL_SUFFIX= ".dll";//$NON-NLS-1$
       
    58 	private static final String BACKSLASH = "\\"; //$NON-NLS-1$
       
    59 	private static final String S60_PATH_PREFIX = BACKSLASH + "s60" + BACKSLASH; //$NON-NLS-1$
       
    60 	private static final String SRC_PATH_PREFIX = BACKSLASH + "src" + BACKSLASH; //$NON-NLS-1$
       
    61 	private static final String S60_PATH_PREFIX_DOUBLE_SLASHS = BACKSLASH + BACKSLASH + "s60" + BACKSLASH + BACKSLASH; //$NON-NLS-1$
       
    62 	private static final String SRC_PATH_PREFIX_DOUBLE_SLASHS = BACKSLASH + BACKSLASH + "src" + BACKSLASH + BACKSLASH; //$NON-NLS-1$
       
    63 	private static final String C_SUFFIX = ".c"; //$NON-NLS-1$
       
    64 	private static final String CPP_SUFFIX = ".cpp"; //$NON-NLS-1$
       
    65 	private static final String METHOD_CLOSING_CHAR = ")"; //$NON-NLS-1$
       
    66 	private static final String METHOD_OPENING_CHAR = "("; //$NON-NLS-1$
       
    67 	private static final String METHOD_DEFINITION_CLOSING_CHAR = "}";
       
    68 	private static final String MAP_FILE_SUFFIX = ".map"; //$NON-NLS-1$
       
    69 	private static final String NULL_ADDRESS = "0x00000000"; //$NON-NLS-1$
       
    70 	private static final String ABSOLUTE  = "ABSOLUTE"; //$NON-NLS-1$
       
    71 	private static final String EPOC32_BUILD  = "EPOC32\\BUILD"; //$NON-NLS-1$
       
    72 	private static final String EPOC32_BUILD_DOUBLE_SLASHES  = "EPOC32\\\\BUILD"; //$NON-NLS-1$
       
    73 	private static final String EXPORT ="EXPORT_C"; //$NON-NLS-1$
       
    74 	private static final String IMPORT = "IMPORT_C"; //$NON-NLS-1$
       
    75 
       
    76 	
       
    77 	/**
       
    78 	 * Print utility used to report error, warnings, and info messages.
       
    79 	 */
       
    80 	private IConsolePrintUtility printUtility = null;
       
    81 
       
    82 	/**
       
    83 	 * Constructor.
       
    84 	 * @param printUtility Print utility used to report error, warnings, and info messages.
       
    85 	 */
       
    86 	public MapSourceFinder(IConsolePrintUtility printUtility){
       
    87 		this.printUtility = printUtility;		
       
    88 	}
       
    89 	
       
    90 	/* (non-Javadoc)
       
    91 	 * @see com.nokia.s60tools.util.sourcecode.ISourceFinder#findSourceFile(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
       
    92 	 */
       
    93 	public SourceFileLocation findSourceFile(String ordinal, String methodName, String compoentName,
       
    94 			String variant, String build, String epocRootPath) throws CannotFoundFileException {
       
    95 		SourceFileLocation sourceLocation = null;
       
    96 		try {
       
    97 			String address = getAddress(ordinal, compoentName, variant, build,
       
    98 					epocRootPath);
       
    99 			String mapFilePath = getMapFilePath(compoentName, variant, build, epocRootPath);
       
   100 			File mapFile = getMapFile(mapFilePath);
       
   101 
       
   102 			String lineWhereAddressIs = getAddressLineFromFile(address, mapFile, methodName);
       
   103 
       
   104 			if(methodName == null){
       
   105 				methodName = getMethodNameFromMapFileLine(lineWhereAddressIs);				
       
   106 			}
       
   107 			
       
   108 			String objectFileName = getObjectFileName(lineWhereAddressIs, address);
       
   109 			sourceLocation = getSourceFileLocation(objectFileName, mapFile, methodName, epocRootPath, isDll(compoentName));			
       
   110 			
       
   111 			sourceLocation.setDllName(compoentName);
       
   112 			sourceLocation.setMethodName(methodName);
       
   113 			sourceLocation.setObjectName(objectFileName);
       
   114 			sourceLocation.setOrdinal(ordinal);
       
   115 			sourceLocation.setMethodAddress(address);
       
   116 			
       
   117 		} catch (Exception e) {			
       
   118 			e.printStackTrace(); 
       
   119 			// Mapping all possible exceptions into single exception type. 
       
   120 			throw new CannotFoundFileException(e.getMessage(), e);
       
   121 		}		
       
   122 		return sourceLocation;
       
   123 	}
       
   124 	
       
   125 	
       
   126 	/* (non-Javadoc)
       
   127 	 * @see com.nokia.s60tools.util.sourcecode.ISourceFinder#findSourceFile(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.Collection)
       
   128 	 */
       
   129 	public SourceFileLocation findSourceFile(String ordinal, String methodName, String componentName, String epocRootPath, Collection<String> pathsToSeekMapFile) throws CannotFoundFileException {
       
   130 		SourceFileLocation sourceLocation = null;
       
   131 		try {
       
   132 	
       
   133 			String mapFileName = componentName + MAP_FILE_SUFFIX;
       
   134 			
       
   135 			File mapFile = getMapFile(pathsToSeekMapFile, componentName, mapFileName);
       
   136 			
       
   137 			if(mapFile == null){
       
   138 				String msg = "'" + mapFileName  //$NON-NLS-1$
       
   139 					+"' " //$NON-NLS-1$
       
   140 					+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part1")   //$NON-NLS-1$
       
   141 					+methodName 
       
   142 					+"' "  //$NON-NLS-1$
       
   143 					+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part2");  //$NON-NLS-1$
       
   144 				String consoleMsg = msg + " "  //$NON-NLS-1$
       
   145 					+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part3");  //$NON-NLS-1$
       
   146 
       
   147 				String pathSeparator= ", "; //$NON-NLS-1$
       
   148 				for (Iterator<String> iterator = pathsToSeekMapFile.iterator(); iterator
       
   149 						.hasNext();) {
       
   150 					String path = (String) iterator.next();
       
   151 					consoleMsg += path + pathSeparator;
       
   152 				}
       
   153 				consoleMsg = consoleMsg.substring(0, consoleMsg.length() - pathSeparator.length());
       
   154 				printUtility.println(consoleMsg, IConsolePrintUtility.MSG_ERROR);
       
   155 				throw new CannotFoundFileException(msg);
       
   156 			}
       
   157 			File parentDir = mapFile.getParentFile();
       
   158 			
       
   159 			String componentPath = parentDir.getAbsolutePath() + File.separatorChar + componentName;
       
   160 			
       
   161 			String address = getAddress(ordinal, componentPath, epocRootPath);
       
   162 			String lineWhereAddressIs = getAddressLineFromFile(address, mapFile, methodName);
       
   163 
       
   164 			if(methodName == null){
       
   165 				methodName = getMethodNameFromMapFileLine(lineWhereAddressIs);				
       
   166 			}
       
   167 			
       
   168 			String objectFileName = getObjectFileName(lineWhereAddressIs, address);
       
   169 			sourceLocation = getSourceFileLocation(objectFileName, mapFile, methodName, epocRootPath, isDll(componentName));			
       
   170 			
       
   171 			sourceLocation.setDllName(componentName);
       
   172 			sourceLocation.setMethodName(methodName);
       
   173 			sourceLocation.setObjectName(objectFileName);
       
   174 			sourceLocation.setOrdinal(ordinal);
       
   175 			sourceLocation.setMethodAddress(address);
       
   176 			
       
   177 		} catch (Exception e) {			
       
   178 			e.printStackTrace(); 
       
   179 			// Mapping all possible exceptions into single exception type. 
       
   180 			throw new CannotFoundFileException(e.getMessage(), e);
       
   181 		}		
       
   182 		return sourceLocation;
       
   183 	}
       
   184 	
       
   185 	/**
       
   186 	 * Check if component is DLL or not.
       
   187 	 * @param componentName Component name.
       
   188 	 * @return <code>true</code> if component is DLL, otherwise <code>false</code>.
       
   189 	 */
       
   190 	private boolean isDll(String componentName) {		
       
   191 		return componentName.trim().endsWith(DLL_SUFFIX) ? true : false;
       
   192 	}
       
   193 	/**
       
   194 	 * Gets map file object based on path name if file exists.
       
   195 	 * @param mapFilePath Path to map file.
       
   196 	 * @return File object for map file, if file exists, otherwise throwing exception.
       
   197 	 * @throws FileNotFoundException
       
   198 	 */
       
   199 	private File getMapFile(String mapFilePath) throws CannotFoundFileException {
       
   200 		File mapFile = new File(mapFilePath);
       
   201 		if(!mapFile.exists()){
       
   202 			throw new CannotFoundFileException(
       
   203 					Messages.getString("MapSourceFinder.MapDoesntExist_ErrMsg_Part1") //$NON-NLS-1$
       
   204 					+mapFilePath
       
   205 					+Messages.getString("MapSourceFinder.MapDoesntExist_ErrMsg_Part2")); //$NON-NLS-1$
       
   206 		}
       
   207 		return mapFile;
       
   208 	}
       
   209 
       
   210 
       
   211 	/* (non-Javadoc)
       
   212 	 * @see com.nokia.s60tools.util.sourcecode.ISourceFinder#findSourceFile(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
       
   213 	 */
       
   214 	public SourceFileLocation findSourceFile(String ordinal, String componentName,
       
   215 			String variant, String build, String epocRootPath)  throws CannotFoundFileException{
       
   216 
       
   217 			return findSourceFile(ordinal, null, componentName, variant, build, epocRootPath);
       
   218 			
       
   219 	}
       
   220 	
       
   221 	/**
       
   222 	 * Tries to find a variant map file for given component. E.g. if component is called MyComponent.exe,
       
   223 	 * it might not have a map file called MyComponent.exe.map. It might contain a variant map file e.g.
       
   224 	 * MyComponent.11001011.exe.map. This method tries to find this variant map file MyComponent.11001011.exe.map.
       
   225 	 * @param epocRootPath EPOCROOT path
       
   226 	 * @param variant Build variant
       
   227 	 * @param build Build type (udeb/urel)
       
   228 	 * @param component Component name.
       
   229 	 * @return variant map file, or <code>null</code> if not found.
       
   230 	 */
       
   231 	private File getVariantMapFile(String epocRootPath, String variant, String build, String component) {
       
   232 		File variantMapFile = null;
       
   233 		
       
   234 		String mapPath = 
       
   235 			epocRootPath + File.separatorChar 
       
   236 			+SourceFileLocation.EPOC32_FOLDER_NAME + File.separatorChar
       
   237 			+SourceFileLocation.RELEASE_FOLDER_NAME + File.separatorChar
       
   238 			+variant + File.separatorChar
       
   239 			+build + File.separatorChar;
       
   240 		mapPath = makeWindowsPath(mapPath);
       
   241 		
       
   242 		File path = new File(mapPath);
       
   243 		if (path.isDirectory() && path.exists()) {
       
   244 			
       
   245 			final class VariantFilter implements FilenameFilter {
       
   246 				String component;
       
   247 				public VariantFilter(String componentName) {
       
   248 					component = componentName;
       
   249 				}
       
   250 		        public boolean accept(File dir, String name) {
       
   251 		            if (name.toLowerCase().endsWith(".map")) {
       
   252 		            	int index = component.lastIndexOf(".");
       
   253 		            	if (name.toLowerCase().startsWith(component.substring(0, index+1).toLowerCase()))
       
   254 		            		return true;
       
   255 		            }
       
   256 	            	return false;
       
   257 		        }
       
   258 			}
       
   259 		    String[] files = path.list(new VariantFilter(component));
       
   260 		    if (files != null && files.length == 1)
       
   261 		    	variantMapFile = new File(mapPath + files[0]);
       
   262 		}
       
   263 		
       
   264 		return variantMapFile;
       
   265 	}
       
   266 	
       
   267 	/* (non-Javadoc)
       
   268 	 * @see com.nokia.s60tools.util.sourcecode.ISourceFinder#findSourceFileByMethodName(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
       
   269 	 */
       
   270 	public SourceFileLocation findSourceFileByMethodName(String methodName,
       
   271 			String componentName, String variant, String build, String epocRootPath) throws CannotFoundFileException{
       
   272 		
       
   273 		String mapFilePath = getMapFilePath(componentName, variant, build, epocRootPath);
       
   274 		
       
   275 		File mapFile = null;
       
   276 		try {
       
   277 			mapFile = getMapFile(mapFilePath);
       
   278 
       
   279 		// we could not find map file, try to find variant map file
       
   280 		} catch (CannotFoundFileException e) {
       
   281 			mapFile = getVariantMapFile(epocRootPath, variant, build, componentName);
       
   282 			if (mapFile == null)
       
   283 				throw e;
       
   284 		}
       
   285 		
       
   286 		return findSourceFile(methodName, componentName, epocRootPath, mapFile);		
       
   287 	
       
   288 	}
       
   289 	
       
   290 	/* (non-Javadoc)
       
   291 	 * @see com.nokia.s60tools.util.sourcecode.ISourceFinder#findSourceFileByMethodName(java.lang.String, java.lang.String, java.lang.String, java.util.Collection)
       
   292 	 */
       
   293 	public SourceFileLocation findSourceFileByMethodName(String methodName,
       
   294 			String componentName, String epocRootPath, Collection<String> pathsToSeekMapFile) throws CannotFoundFileException{
       
   295 
       
   296 		String mapFileName = componentName + MAP_FILE_SUFFIX;
       
   297 		File mapFile = getMapFile(pathsToSeekMapFile, componentName, mapFileName);
       
   298 		
       
   299 		//If we did not found map file, we cannot proceed to src file seek
       
   300 		if(mapFile == null){
       
   301 			String msg = "'" + mapFileName  //$NON-NLS-1$
       
   302 				+"' " //$NON-NLS-1$
       
   303 				+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part1")   //$NON-NLS-1$
       
   304 				+methodName 
       
   305 				+"' "  //$NON-NLS-1$
       
   306 				+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part2");  //$NON-NLS-1$
       
   307 			String consoleMsg = msg + " "  //$NON-NLS-1$
       
   308 				+Messages.getString("MapSourceFinder.MapFileNotFoundForMethod_ErrMsg_Part3");  //$NON-NLS-1$
       
   309 
       
   310 			String pathSeparator= ", "; //$NON-NLS-1$
       
   311 			for (Iterator<String> iterator = pathsToSeekMapFile.iterator(); iterator
       
   312 					.hasNext();) {
       
   313 				String path = (String) iterator.next();
       
   314 				consoleMsg += path + pathSeparator;
       
   315 			}
       
   316 			consoleMsg = consoleMsg.substring(0, consoleMsg.length() - pathSeparator.length());
       
   317 			printUtility.println(consoleMsg, IConsolePrintUtility.MSG_ERROR);
       
   318 			throw new CannotFoundFileException(msg);
       
   319 		}
       
   320 		
       
   321 		return findSourceFile(methodName, componentName, epocRootPath, mapFile);		
       
   322 		
       
   323 	}
       
   324 	
       
   325 	
       
   326 	/**
       
   327 	 * Gets a map file by component name and list of folder where to seek it
       
   328 	 * @param pathsToSeekMapFile Path list to seek map files from.
       
   329 	 * @param componentName Component name.
       
   330 	 * @return file File object pointing to map file and <code>null</code> if not found.
       
   331 	 */
       
   332 	private File getMapFile(Collection<String> pathsToSeekMapFile,
       
   333 			String componentName, String mapFileName) throws CannotFoundFileException {
       
   334 		
       
   335 		MapFilenameFilter mapFilenameFilter = new MapFilenameFilter(mapFileName);
       
   336 		DirFileFilter dirFilter = new DirFileFilter();
       
   337 		
       
   338 		for (Iterator<String> iterator = pathsToSeekMapFile.iterator(); iterator
       
   339 				.hasNext();) {
       
   340 			String path = (String) iterator.next();
       
   341 			File dir = new File(path);
       
   342 			if(!dir.exists() || !dir.isDirectory()){
       
   343 				continue;
       
   344 			}
       
   345 			File mapFile = getFileFromDir(dir, mapFileName, mapFilenameFilter, dirFilter);
       
   346 			if(mapFile != null){
       
   347 				return mapFile;
       
   348 			}
       
   349 			
       
   350 		}
       
   351 		
       
   352 		return null;
       
   353 	}
       
   354 	
       
   355 	/**
       
   356 	 * Get map file from dir and dirs under given dir. Calls recursively it self.
       
   357 	 * @param dir Directory to search for.
       
   358 	 * @param mapFileName Map file name to search for.
       
   359 	 * @param mapFilenameFilter Map file name filter.
       
   360 	 * @param dirFilter Directory filter.
       
   361 	 * @return mapFile with given name, or null if cannot be found
       
   362 	 */
       
   363 	private File getFileFromDir(File dir, String mapFileName, MapFilenameFilter mapFilenameFilter, DirFileFilter dirFilter){
       
   364 
       
   365 		File [] files = dir.listFiles(mapFilenameFilter);
       
   366 		if(files != null && files.length > 0){
       
   367 			return files[0];
       
   368 		}
       
   369 
       
   370 		File [] dirs = dir.listFiles(dirFilter);
       
   371 		for (int i = 0; i < dirs.length; i++) {
       
   372 			File mapFile = getFileFromDir(dirs[i], mapFileName, mapFilenameFilter, dirFilter);
       
   373 			if(mapFile != null){
       
   374 				return mapFile;
       
   375 			}
       
   376 		}
       
   377 		return null;
       
   378 		
       
   379 	}
       
   380 	
       
   381 	/**
       
   382 	 * Filter accepts only directories, not files
       
   383 	 */
       
   384 	private class DirFileFilter implements FileFilter {
       
   385 
       
   386 		public boolean accept(File file) {
       
   387 			return file.isDirectory();
       
   388 		}		
       
   389 	}
       
   390 	
       
   391 	/**
       
   392 	 * Filter accepts only files named by given file (case in sensitive)
       
   393 	 */
       
   394 	private class MapFilenameFilter implements FilenameFilter{
       
   395 		
       
   396 		private String mapFileName = null;
       
   397 
       
   398 		private MapFilenameFilter(){
       
   399 		}
       
   400 		public MapFilenameFilter(String mapFileName){
       
   401 			this();
       
   402 			this.mapFileName = mapFileName;			
       
   403 		}
       
   404 		
       
   405 		public boolean accept(File dir, String name) {
       
   406 			return name.equalsIgnoreCase(mapFileName) ? true : false;
       
   407 		}	
       
   408 	}
       
   409 	
       
   410 	/**
       
   411 	 * Finds source file based on the method name.
       
   412 	 * @param methodName Method name.
       
   413 	 * @param componentName Component name.
       
   414 	 * @param epocRootPath EPOCROOT path.
       
   415 	 * @param mapFile File object pointing to MMP file.
       
   416 	 * @return source file location, or <code>null</code> if not found.
       
   417 	 * @throws CannotFoundFileException
       
   418 	 */
       
   419 	private SourceFileLocation findSourceFile(String methodName,
       
   420 			String componentName, String epocRootPath, File mapFile)
       
   421 			throws CannotFoundFileException {
       
   422 		try {			
       
   423 			// Example method name line
       
   424 			//20	CRepository::Create(unsigned long, TDesC16 const&)
       
   425 
       
   426 			String lineWhereAddressIs = getAddressLineFromFile(mapFile, methodName);
       
   427 			String address = getAddresFromLine(lineWhereAddressIs, methodName);
       
   428 			
       
   429 			String objectFileName = getObjectFileName(lineWhereAddressIs, address);
       
   430 			String shortMethodNameWithoutParams = getMethodNameWithoutParams(methodName);
       
   431 			SourceFileLocation sourceLocation = getSourceFileLocation(objectFileName, mapFile, shortMethodNameWithoutParams, epocRootPath, isDll(componentName));			
       
   432 			
       
   433 			sourceLocation.setDllName(componentName);
       
   434 			sourceLocation.setMethodAddress(address);
       
   435 			sourceLocation.setMethodName(methodName);
       
   436 			sourceLocation.setObjectName(objectFileName);
       
   437 			sourceLocation.setMethodAddress(address);
       
   438 			return sourceLocation;
       
   439 			
       
   440 		} catch (Exception e) {
       
   441 			e.printStackTrace();
       
   442 			// Mapping all possible exceptions into single exception type. 
       
   443 			throw new CannotFoundFileException(e.getMessage() , e);
       
   444 		}
       
   445 	}
       
   446 
       
   447 	/**
       
   448 	 * Get address from map file line based on method name
       
   449 	 * @param lineWhereAddressIs Line containing address.
       
   450 	 * @param methodName Method name.
       
   451 	 * @return Method address.
       
   452 	 */
       
   453 	private String getAddresFromLine(String lineWhereAddressIs,
       
   454 			String methodName) {
       
   455 		//e.g. : CRepository::Create(unsigned long, const TDesC16&) 0x000080b9   Thumb Code     8  centralrepository.in(.text)
       
   456 		String addString = lineWhereAddressIs.substring(lineWhereAddressIs.indexOf(methodName) + methodName.length()).trim();
       
   457 		//e.g. : '0x000080b9   Thumb Code     8  centralrepository.in(.text)'		
       
   458 		addString = addString.substring(0, addString.indexOf(" ")).trim(); //$NON-NLS-1$
       
   459 		return addString;
       
   460 	}
       
   461 	
       
   462 	
       
   463 	/**
       
   464 	 * Get Address using petran command-line runner.
       
   465 	 * @param ordinal Method ordinal.
       
   466 	 * @param componentName Component name.
       
   467 	 * @param variant Build variant.
       
   468 	 * @param build Build type (urel/udeb).
       
   469 	 * @param epocRootPath EPOCROOT path.
       
   470 	 * @return Address for the given method ordinal.
       
   471 	 * @throws UnsupportedOSException
       
   472 	 * @throws InterruptedException
       
   473 	 * @throws CmdLineExeption
       
   474 	 */
       
   475 	private String getAddress(String ordinal, String componentName, String variant,
       
   476 			String build, String epocRootPath) throws UnsupportedOSException,
       
   477 			InterruptedException, CmdLineExeption {
       
   478 		
       
   479 		PetranDumpCMDLineRunner runner = new PetranDumpCMDLineRunner(printUtility);		
       
   480 		String address =  runner.getAddress(ordinal, componentName, variant, build, epocRootPath);
       
   481 		return address;
       
   482 	}
       
   483 	
       
   484 	/**
       
   485 	 * Get Address using petran command-line runner.
       
   486 	 * @param ordinal Method ordinal
       
   487 	 * @param componentPath path of the component
       
   488 	 * @param epocRootPath EPOCROOT path
       
   489 	 * @return Address for the given method ordinal.
       
   490 	 * @throws UnsupportedOSException
       
   491 	 * @throws InterruptedException
       
   492 	 * @throws CmdLineExeption
       
   493 	 */
       
   494 	private String getAddress(String ordinal, String componentPath, String epocRootPath) throws UnsupportedOSException,
       
   495 			InterruptedException, CmdLineExeption {
       
   496 		
       
   497 		PetranDumpCMDLineRunner runner = new PetranDumpCMDLineRunner(printUtility);		
       
   498 		String address =  runner.getAddress(ordinal, componentPath, epocRootPath);
       
   499 		return address;
       
   500 	}
       
   501 	
       
   502 	/**
       
   503 	 * Get sourceFile location
       
   504 	 * @param objectFileName Object file name.
       
   505 	 * @param mapFile File object pointing to map file.
       
   506 	 * @param methodName Method name.
       
   507 	 * @param epocRootPath EPOCROOT path.
       
   508 	 * @param isDll <code>true</code> if component is DLL, otherwise <code>false</code>.
       
   509 	 * @return path in Windows format, separators will be "\":s even when they were "/":s originally.
       
   510 	 * @throws IOException
       
   511 	 * @throws CannotFoundFileException 
       
   512 	 */
       
   513 	private SourceFileLocation getSourceFileLocation(String objectFileName, File mapFile, String methodName, String epocRootPath, boolean isDll) throws IOException, CannotFoundFileException {
       
   514 		FileInputStream in = null;
       
   515 		InputStreamReader isr = null;
       
   516 		BufferedReader br = null;
       
   517 		ArrayList<String> lines = new ArrayList<String>();
       
   518 		SourceFileLocation sourceLocation = null;
       
   519 
       
   520 		try {
       
   521 			in = new FileInputStream(mapFile);
       
   522 			isr = new InputStreamReader(in);
       
   523 			br = new BufferedReader(isr);
       
   524 
       
   525 			String line = null;
       
   526 			//seek "0x00000000" and "ABSOLUTE" and object file name from file line by line
       
   527 			while ((line = br.readLine()) != null) {
       
   528 				if(line.contains(objectFileName) && 
       
   529 						line.contains(NULL_ADDRESS) &&
       
   530 						line.contains(ABSOLUTE) ){
       
   531 
       
   532 					//if we found wanted text, checking that it does not contain 
       
   533 					//\EPOC32\BUILD or \\EPOC32\\BUILD, because then its not a source, but build file
       
   534 					//Returning path in windows format
       
   535 					String epocBuildLine = makeWindowsPath(line);
       
   536 					//Making sure that souce location does not point to BUILD folder
       
   537 					if(epocBuildLine.indexOf(EPOC32_BUILD) == SourceFileLocation.OFFSET_NOT_FOUND){						
       
   538 						epocBuildLine = epocBuildLine.substring(0, epocBuildLine.indexOf(NULL_ADDRESS)).trim();
       
   539 						lines.add(epocBuildLine);			
       
   540 					}
       
   541 					
       
   542 				}
       
   543 			}
       
   544 			
       
   545 			//If there was only one line
       
   546 			if(lines.size() == 1){
       
   547 				String filePath = buildAbsoluteFilePath(lines.get(0), epocRootPath);
       
   548 				if(sourceFileExist(filePath)){
       
   549 					sourceLocation = new SourceFileLocation();
       
   550 					sourceLocation.setSourceFileLocation(filePath);
       
   551 					String methodNameWithoutParams = getMethodNameWithoutParams(methodName);
       
   552 					int offset = getMethodNameLineOfsetFromSourceFile(methodNameWithoutParams, new File(filePath), isDll);
       
   553 					if(offset != SourceFileLocation.OFFSET_NOT_FOUND){
       
   554 						sourceLocation.setMethodOffset(offset);						
       
   555 					}
       
   556 				}else{
       
   557 					String msg = Messages.getString("MapSourceFinder.ObjectFileDoesntExist_ErrMsg_Part1") +objectFileName //$NON-NLS-1$ //$NON-NLS-2$ 
       
   558 							+Messages.getString("MapSourceFinder.ObjectFileDoesntExist_ErrMsg_Part2") + mapFile.getAbsolutePath() //$NON-NLS-1$ //$NON-NLS-2$ 
       
   559 							+Messages.getString("MapSourceFinder.ObjectFileDoesntExist_ErrMsg_Part3") + filePath//$NON-NLS-1$ //$NON-NLS-2$ 					
       
   560 							+Messages.getString("MapSourceFinder.ObjectFileDoesntExist_ErrMsg_Part4");//$NON-NLS-1$ 
       
   561 					printUtility.println(msg); 
       
   562 					throwCannotFoundFileException(mapFile, methodName, msg);
       
   563 				}
       
   564 			}
       
   565 			//If there was many occurrences, opening files and seek method name, to get only one result
       
   566 			else if(lines.size() > 0){
       
   567 				sourceLocation = foundSourceFileWhereMethodIsImplemented(lines, methodName, epocRootPath, isDll);
       
   568 				
       
   569 				if(sourceLocation == null){
       
   570 					String msg = Messages.getString("MapSourceFinder.SourceFileNotFoundForMethod_ErrMsg_Part1") //$NON-NLS-1$
       
   571 							+methodName  + Messages.getString("MapSourceFinder.SourceFileNotFoundForMethod_ErrMsg_Part2") +mapFile.getAbsolutePath() +"'."; //$NON-NLS-1$ //$NON-NLS-2$
       
   572 					printUtility.println(msg);
       
   573 
       
   574 					throwCannotFoundFileException(mapFile, methodName, msg);
       
   575 				}
       
   576 
       
   577 			}//No results found
       
   578 			else{
       
   579 				String msg = Messages.getString("MapSourceFinder.ObjectFileNotFound_ErrMsg_Part1") +objectFileName +Messages.getString("MapSourceFinder.ObjectFileNotFound_ErrMsg_Part2") + mapFile.getAbsolutePath() +"'."; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
   580 				printUtility.println(msg);
       
   581 				throwCannotFoundFileException(mapFile, methodName, msg);
       
   582 				
       
   583 			}
       
   584 						
       
   585 		} finally{
       
   586 			if(in != null){
       
   587 				in.close();
       
   588 			}
       
   589 			if(isr != null){
       
   590 				isr.close();
       
   591 			}
       
   592 			if(br != null){
       
   593 				br.close();
       
   594 			}
       
   595 		}
       
   596 
       
   597 		return sourceLocation;		
       
   598 	}
       
   599 
       
   600 	/**
       
   601 	 * Throw an exception with message about map file and method name, that a source file cannot be found from those details
       
   602 	 * @param mapFile File object pointing to map file.
       
   603 	 * @param methodName Method name.
       
   604 	 * @throws CannotFoundFileException
       
   605 	 */
       
   606 	private void throwCannotFoundFileException(File mapFile, String methodName, String msg) throws CannotFoundFileException{
       
   607 		throw new CannotFoundFileException(msg);
       
   608 	}
       
   609 
       
   610 	
       
   611 	/**
       
   612 	 * Converts path into Windows format by 
       
   613 	 * replacing extra "\\":s and replace "/" with "\".
       
   614 	 * @param path Path name string to convert.
       
   615 	 * @return path name string in windows format
       
   616 	 */
       
   617 	private String makeWindowsPath(String path) {
       
   618 		//fixing slashes so we can find epoc32 build folder in any cases.
       
   619 		//First replacing "\"'s with "/"'s so regular expression will work
       
   620 		String windowsPath = path.replace(BACKSLASH, "/" ); //$NON-NLS-1$ //$NON-NLS-2$
       
   621 		//removing multiple backslashes: " +" means more than one white spaces, e.g. "a    b c" -> "a b c"
       
   622 		windowsPath = windowsPath.replaceAll("/+", "/"); //$NON-NLS-1$ //$NON-NLS-2$
       
   623 		windowsPath = windowsPath.replace("/", BACKSLASH); //$NON-NLS-1$ //$NON-NLS-2$
       
   624 		return windowsPath;
       
   625 	}		
       
   626 	
       
   627 	/**
       
   628 	 * Checks if file exists.
       
   629 	 * @param filePath File path name.
       
   630 	 * @return <code>true</code> if exist, otherwise <code>false</code>.
       
   631 	 */
       
   632 	private boolean sourceFileExist(String filePath) {		
       
   633 		File file = new File(filePath);		
       
   634 		return file.exists();
       
   635 	}
       
   636 	/**
       
   637 	 * Builds absolute file path name from source file path and EPOCROOT path
       
   638 	 * @param srcPath File source path
       
   639 	 * @param epocRootPath EPOCROOT path
       
   640 	 * @return Absolute file path name.
       
   641 	 */
       
   642 	private String buildAbsoluteFilePath(String srcPath, String epocRootPath) {
       
   643 		String filePath;
       
   644 		
       
   645 		srcPath = FileUtils.removeDriveLetterPortionFromPathIfExists(srcPath);
       
   646 		
       
   647 		if(epocRootPath.endsWith(File.separator) && srcPath.startsWith(File.separator)){
       
   648 			filePath = epocRootPath + srcPath;
       
   649 		}
       
   650 		else if(epocRootPath.endsWith(File.separator) || srcPath.startsWith(File.separator) ){
       
   651 			filePath = epocRootPath + srcPath;
       
   652 		}		
       
   653 		else{
       
   654 			filePath = epocRootPath + File.separatorChar + srcPath;
       
   655 		}
       
   656 		
       
   657 		//Removing possible double slashes
       
   658 		filePath = makeWindowsPath(filePath);
       
   659 		
       
   660 		return filePath;
       
   661 	}
       
   662 	
       
   663 	/**
       
   664 	 * Check if source files contains method name, if contains, returning that file location. 
       
   665 	 * Skips parameters, only seeking method name or ClassName::MethodName if given.
       
   666 	 * @param lines containing paths to source files found in .map file
       
   667 	 * @param methodName Method name.
       
   668 	 * @param epocRootPath EPOCROOT path.
       
   669 	 * @param isDll <code>true</code> if component is DLL, otherwise <code>false</code>.
       
   670 	 * @return Source file path if method name without parameters is found from that file, or <code>null</code> if not found
       
   671 	 * @throws IOException 
       
   672 	 * @throws FileNotFoundException 
       
   673 	 * @throws CannotFoundFileException 
       
   674 	 */
       
   675 	private SourceFileLocation foundSourceFileWhereMethodIsImplemented(ArrayList<String> lines,
       
   676 			String methodName, String epocRootPath, boolean isDll) throws FileNotFoundException, IOException, CannotFoundFileException {			
       
   677 
       
   678 		File srcFile;
       
   679 		//Seeking lines where is source file paths one by one
       
   680 		for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
       
   681 			String path = (String) iterator.next();
       
   682 			srcFile = buildSourceFileObject(path, epocRootPath, methodName);
       
   683 			
       
   684 			if(srcFile.exists()){
       
   685 				String methodNameWithOutParams = getMethodNameWithoutParams(methodName);
       
   686 				
       
   687 				int methodLineOfset = getMethodNameLineOfsetFromSourceFile(methodNameWithOutParams, srcFile, isDll);
       
   688 				//If we found a file where is classname::methodname, stop searching and return that one.
       
   689 				if(methodLineOfset != SourceFileLocation.OFFSET_NOT_FOUND){
       
   690 					SourceFileLocation sourceLocation = new SourceFileLocation();
       
   691 					sourceLocation.setSourceFileLocation(srcFile.getAbsolutePath());
       
   692 					sourceLocation.setMethodOffset(methodLineOfset);
       
   693 					return sourceLocation;
       
   694 				}
       
   695 			}else{
       
   696 				//Caller will throw an exception if null returned
       
   697 				printUtility.println(Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part1") +srcFile.getAbsolutePath()  //$NON-NLS-1$
       
   698 						+ Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part2") +methodName +Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part3")); //$NON-NLS-1$ //$NON-NLS-2$
       
   699 			}
       
   700 		}
       
   701 		return null;
       
   702 	}
       
   703 	
       
   704 	/**
       
   705 	 * Builds alternate source path from the parameters in case the default behavior has failed.
       
   706 	 * @param path Source file path found from *.map-file.
       
   707 	 * @param epocRootPath EPOCROOT defined in SDK properties.
       
   708 	 * @param methodName Name of the method we were about to search.
       
   709 	 * @return Alternate file path, if found.
       
   710 	 */
       
   711 	private File buildSourceFileObject(String path, String epocRootPath, String methodName) {
       
   712 		
       
   713 		// Default behavior is to add 'source path' to EPOCROOT. (format used in platform built map-files)	
       
   714 		String srcFileUri = buildAbsoluteFilePath(path, epocRootPath);
       
   715 		File srcFile = new File(srcFileUri);
       
   716 		
       
   717 		// Checking if the default behavior resulted correct file name
       
   718 		if(!srcFile.exists()){
       
   719 			// Printing info to console about the operation
       
   720 			printUtility.println(Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part1") +srcFile.getAbsolutePath()  //$NON-NLS-1$
       
   721 					+ Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part2") +methodName +Messages.getString("MapSourceFinder.FileDoesntExist_ErrMsg_Part3")); //$NON-NLS-1$ //$NON-NLS-2$
       
   722 			// Checking if the source path already contained EPOCROOT, and stripping it.
       
   723 			srcFile = stripEpocRootFromPath(path, epocRootPath, srcFile);
       
   724 		}
       
   725 		
       
   726 		return srcFile;
       
   727 	}
       
   728 	/**
       
   729 	 * Checks if given path already contains EPOCROOT without logical drive letter.
       
   730 	 * If contains, then stripping it away and returning file object containing correct path.
       
   731 	 * @param path Original source path in map-file
       
   732 	 * @param epocRootPath Currently used EPOCROOT
       
   733 	 * @param srcFile Currently used source file absolute path (possibly containing already EPOCROOT).
       
   734 	 * @return File object containing correct path without duplicate EPOCROOT, or current file object
       
   735 	 *         as result if there was no overlapping.
       
   736 	 */
       
   737 	private File stripEpocRootFromPath(String path, String epocRootPath, File srcFile) {
       
   738 		// For components that user has build in Carbide has different kind of source path used.
       
   739 		// The source path in map-file may already include EPOCROOT e.g. in the following example:
       
   740 		//
       
   741 		// EPOCROOT=C:\foo\bar\MySDK\
       
   742 		// Source file path found from *.map-file=\foo\bar\MySDK\MyExamples\MyExample\ENGINE\src\enginedll.cpp
       
   743 		//
       
   744 		String epocRootWithoutDrive = epocRootPath.substring(2); // Skipping drive letter and colon: "C:" 
       
   745 
       
   746 		if(path.startsWith(epocRootWithoutDrive)){
       
   747 			// Stripping EPOCROOT
       
   748 			String altSrcFileUri = path.substring(epocRootWithoutDrive.length());
       
   749 			srcFile = new File(epocRootPath + altSrcFileUri);
       
   750 			// Printing info to console about the operation
       
   751 			printUtility.println(Messages.getString("MapSourceFinder.StrippingEpocrootFromPath_InfoMsg")); //$NON-NLS-1$
       
   752 		}
       
   753 		return srcFile;
       
   754 	}
       
   755 	
       
   756 	/**
       
   757 	 * Parses out params from method name
       
   758 	 * @param methodName Name of the method to parse.
       
   759 	 * @return Method name without parameters.
       
   760 	 */
       
   761 	private String getMethodNameWithoutParams(String methodName) {
       
   762 		
       
   763 		//ContentAccess::CData::NewL(RFile&, TDesC16 const&, ContentAccess::TIntent)
       
   764 		String methodNameWithClassButWithOutParams = methodName.split(Pattern.quote(METHOD_OPENING_CHAR))[0];
       
   765 		String methodNameWithOutParams;
       
   766 		
       
   767 		String classSeparator = CLASS_SEPARATOR;
       
   768 		if(methodNameWithClassButWithOutParams.indexOf(classSeparator) != -1){
       
   769 			String [] parts = methodNameWithClassButWithOutParams.split(Pattern.quote(classSeparator));
       
   770 			methodNameWithOutParams = parts[parts.length - 2] +classSeparator + parts[parts.length -1];
       
   771 		}else{
       
   772 			methodNameWithOutParams = methodNameWithClassButWithOutParams;
       
   773 		}
       
   774 		
       
   775 		//If that file contains line, where is methodname, e.g. MyClass:MyMethod then that file is what we want
       
   776 		//Only Class name and method name is searched, skipping parameters because of possible new lines and so on.
       
   777 		return methodNameWithOutParams;
       
   778 	}
       
   779 	
       
   780 	/**
       
   781 	 * Get object filename from line where method address was found
       
   782 	 * @param lineWhereAddressIs Line containing the address and object file name.
       
   783 	 * @param address Method address
       
   784 	 * @return object file name
       
   785 	 */
       
   786 	private String getObjectFileName(String lineWhereAddressIs, String address) {
       
   787 
       
   788 		//First line should be e.g.:
       
   789 		//CRepository::Create(unsigned long, const TDesC16&) 0x000080b9   Thumb Code     8  centralrepository.in(.text)
       
   790 		//or/
       
   791 		//User::LeaveIfError(int)                  0x00009078   ARM Code       0  euser{000a0000}-593.o(StubCode)
       
   792 		
       
   793 		//Cut string after address
       
   794 		String objFileName = lineWhereAddressIs.substring(lineWhereAddressIs.indexOf(address) +address.length()).trim();
       
   795 		//No there should be: "Thumb Code     8  centralrepository.in(.text)"
       
   796 		//or: "ARM Code       0  euser{000a0000}-593.o(StubCode)"
       
   797 		
       
   798 		//Cut string before "("
       
   799 		objFileName = objFileName.substring(0, objFileName.lastIndexOf(METHOD_OPENING_CHAR)).trim();
       
   800 		//No there should be: "Thumb Code     8  centralrepository.in"
       
   801 		//or: "ARM Code       0  euser{000a0000}-593.o"
       
   802 		
       
   803 		//Cut string from last " "
       
   804 		objFileName = objFileName.substring(objFileName.lastIndexOf(" ")).trim(); //$NON-NLS-1$
       
   805 
       
   806 		//No there should be: "centralrepository.in"
       
   807 		//or: "euser{000a0000}-593.o"
       
   808 
       
   809 		return objFileName;
       
   810 	}
       
   811 
       
   812 	/**
       
   813 	 * Get method name from line where method address was found.
       
   814 	 * @param lineWhereAddressIs Line containing the address and object file name.
       
   815 	 * @return method name
       
   816 	 */
       
   817 	private String getMethodNameFromMapFileLine(String lineWhereAddressIs) {
       
   818 		//CRepository::Create(unsigned long, const TDesC16&) 0x000080b9   Thumb Code     8  centralrepository.in(.text)
       
   819 		String method = lineWhereAddressIs.substring(0, lineWhereAddressIs.indexOf(METHOD_CLOSING_CHAR));
       
   820 		return method != null ? method.trim() : null;
       
   821 	}		
       
   822 	
       
   823 	/**
       
   824 	 * Get those lines from file, where is the wanted string.
       
   825 	 * @param wantedString wanted string, or <code>null</code> if all lines is wanted
       
   826 	 * @param file File object to search for the string.
       
   827 	 * @param addAllLinesIfWantedStringExist If set to <code>true</code> and wantedString 
       
   828 	 *                                       occurs at least once, all lines from file will be returned, 
       
   829 	 *                                       otherwise an empty list will be returned, 
       
   830 	 *                                       If set to <code>false</code>, only those lines where 
       
   831 	 *                                       wanted string exist will be returned. 
       
   832 	 * @return Lines based wanted strings and boolean parameter setting.
       
   833 	 * @throws IOException
       
   834 	 */
       
   835 	private ArrayList<String> getLinesFromFile(String wantedString, File file, boolean addAllLinesIfWantedStringExist) throws IOException{
       
   836 		ArrayList<String> lines = new ArrayList<String>();
       
   837 		FileInputStream in = null;
       
   838 		InputStreamReader isr = null;
       
   839 		BufferedReader br = null;
       
   840 		boolean fileContainsWantedString = false;
       
   841 				
       
   842 		try {
       
   843 			in = new FileInputStream(file);
       
   844 			isr = new InputStreamReader(in);
       
   845 			br = new BufferedReader(isr);
       
   846 
       
   847 			String line = null;
       
   848 			
       
   849 			//seek wanted text from file line by line
       
   850 			while ((line = br.readLine()) != null) {
       
   851 				//if we found wanted text, stopping search
       
   852 				if(addAllLinesIfWantedStringExist){
       
   853 					lines.add(line);
       
   854 					//Marking that we found a required line from that file when all lines is gathered
       
   855 					if(line.contains(wantedString)){
       
   856 						fileContainsWantedString = true;
       
   857 					}
       
   858 				}
       
   859 				else if(!addAllLinesIfWantedStringExist && line.contains(wantedString)){
       
   860 					lines.add(line);
       
   861 				}//Else line is not wanted and will not be added to lines
       
   862 			}		
       
   863 		}finally{
       
   864 				if(in != null){
       
   865 					in.close();
       
   866 				}
       
   867 				if(isr != null){
       
   868 					isr.close();
       
   869 				}
       
   870 				if(br != null){
       
   871 					br.close();
       
   872 				}
       
   873 		}		
       
   874 		
       
   875 		//If we want all lines from file and that file does not contain wanted String
       
   876 		//we collect already all lines but there was no wanted line, so returning new empty list
       
   877 		if(addAllLinesIfWantedStringExist && !fileContainsWantedString){
       
   878 			return new ArrayList<String>();
       
   879 		}else{		
       
   880 			return lines;
       
   881 		}
       
   882 	}
       
   883 	
       
   884 	
       
   885 	/**
       
   886 	 * Seek address line where is method address and braces ().
       
   887 	 * @param address Method address.
       
   888 	 * @param mapFile File object pointing to map file.
       
   889 	 * @param methodName Method name.
       
   890 	 * @return Address line.
       
   891 	 * @throws FileNotFoundException
       
   892 	 * @throws IOException
       
   893 	 * @throws CannotFoundFileException 
       
   894 	 */
       
   895 	private String getAddressLineFromFile(String address, File mapFile, String methodName)
       
   896 			throws FileNotFoundException, IOException, CannotFoundFileException {
       
   897 		
       
   898 		ArrayList<String> lines = getLinesFromFile(address, mapFile, false);
       
   899 		String wantedLine = null;
       
   900 			
       
   901 			//If there was only one occurrence
       
   902 			if(lines.size() == 1){
       
   903 				wantedLine = lines.get(0);
       
   904 				
       
   905 			}
       
   906 			//If there was many occurences, selecting wanted one  
       
   907 			else if(lines.size() > 1){
       
   908 				
       
   909 				//Seeking all foundings and select wanted line
       
   910 				for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
       
   911 					String aLine = (String) iterator.next();
       
   912 					
       
   913 					//If there is many lines, we want that one where method name is, 
       
   914 					//and in method name lines, there will be braces "()" before address e.g. in XnResource.dll.map
       
   915 					//StubCode                                 0x000084b8   Section        8  apmime{000a0000}-57.o(StubCode)
       
   916 					//TDataType::InternalizeL(RReadStream&)    0x000084b8   ARM Code       0  apmime{000a0000}-57.o(StubCode)
       
   917 					
       
   918 					//cut string before address
       
   919 					aLine = aLine.substring(aLine.indexOf(address));
       
   920 					if(aLine.contains(METHOD_CLOSING_CHAR) && aLine.contains(METHOD_OPENING_CHAR)){
       
   921 						
       
   922 							wantedLine = aLine;
       
   923 							break;							
       
   924 					}
       
   925 									
       
   926 				}
       
   927 				
       
   928 			}//else wantedLine will be null and exception will thrown
       
   929 			
       
   930 		if(wantedLine == null){
       
   931 			throw new CannotFoundFileException(
       
   932 					Messages.getString("MapSourceFinder.CannotFoundAddress_ErrMsg_Part1") +methodName +Messages.getString("MapSourceFinder.CannotFoundAddress_ErrMsg_Part2") +mapFile.getName() +"'."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
   933 		}
       
   934 		
       
   935 		return wantedLine;
       
   936 	}
       
   937 	
       
   938 	
       
   939 	/**
       
   940 	 * Seek address line where is method name and braces ().
       
   941 	 * @param mapFile File object pointing to map file.
       
   942 	 * @param methodName Method name.
       
   943 	 * @return Address line.
       
   944 	 * @throws FileNotFoundException
       
   945 	 * @throws IOException
       
   946 	 * @throws CannotFoundFileException 
       
   947 	 */
       
   948 	private String getAddressLineFromFile(File mapFile, String methodName)
       
   949 			throws FileNotFoundException, IOException, CannotFoundFileException {
       
   950 
       
   951 		//Line is e.g:
       
   952 		//CTerminalControlSession::GetDeviceLockParameterL(TBuf8<(int)21>&, int) 0x000090e1   Thumb Code   188  TerminalControl.in(.text)
       
   953 		//When method is: CTerminalControlSession::GetDeviceLockParameterL(TBuf8<(int)21>&, int)
       
   954 		
       
   955 		ArrayList<String> lines = getLinesFromFile(methodName, mapFile, false);
       
   956 		String wantedLine = null;
       
   957 			
       
   958 			//If there was only one occurrence
       
   959 			if(lines.size() == 1){
       
   960 				wantedLine = lines.get(0);
       
   961 				
       
   962 			}
       
   963 			//If there was many occurrences, selecting wanted one  
       
   964 			else if(lines.size() > 1){
       
   965 				
       
   966 				//Seeking all findings and select wanted line
       
   967 				for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
       
   968 					String aLine = (String) iterator.next();
       
   969 					//What to do if many lines found? Currently just printing a debug message. 
       
   970 					//Really it should not be happening, but if does, logic must be improved if error situation occurs. 
       
   971 					 printUtility.println(
       
   972 							 Messages.getString("MapSourceFinder.ManyAddressLines_Msg_Part_1")  //$NON-NLS-1$
       
   973 							 +methodName  
       
   974 							 +Messages.getString("MapSourceFinder.ManyAddressLines_Msg_Part_2")	//$NON-NLS-1$							
       
   975 							+mapFile.getName()
       
   976 							+Messages.getString("MapSourceFinder.ManyAddressLines_Msg_Part_3")//$NON-NLS-1$
       
   977 							+aLine
       
   978 							+"'.");	//$NON-NLS-1$					
       
   979 					
       
   980 				}
       
   981 				//Even if there is many lines, just selecting the first one
       
   982 				wantedLine = lines.get(0);
       
   983 				
       
   984 			}//else wantedLine will be null and exception will thrown
       
   985 			
       
   986 		if(wantedLine == null){
       
   987 			throw new CannotFoundFileException(
       
   988 					Messages.getString("MapSourceFinder.CannotFoundAddress_ErrMsg_Part1") +methodName +Messages.getString("MapSourceFinder.CannotFoundAddress_ErrMsg_Part2") +mapFile.getName() +"'."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
   989 		}
       
   990 		
       
   991 		return wantedLine;
       
   992 	}	
       
   993 	
       
   994 	
       
   995 	/**
       
   996 	 * Seek offset from method implementation from source file.
       
   997 	 * @param methodName Method name
       
   998 	 * @param file File to gen method name line offset.
       
   999 	 * @param isDll  When set to <code>true</code> tells that implementation must 
       
  1000 	 *               have prefix IMPORT_C or EXPORT_C and if set to <code>false</code> 
       
  1001 	 *               we suppose that it is exe file in question and those are not required.
       
  1002 	 * @return Offset or -1 if not found
       
  1003 	 * @throws FileNotFoundException
       
  1004 	 * @throws IOException
       
  1005 	 */
       
  1006 	private int getMethodNameLineOfsetFromSourceFile(String methodName, File file, boolean isDll)
       
  1007 			throws FileNotFoundException, IOException {
       
  1008 		//getting all lines of that file if it contains methodName at least some where
       
  1009 		ArrayList<String> lines = getLinesFromFile(methodName, file, true);
       
  1010 		String wantedLine = null;
       
  1011 		int offset = SourceFileLocation.OFFSET_NOT_FOUND;//-1 will return if offset cannot be found from file
       
  1012 			// If there was at least one occurrence of methodName
       
  1013 			if (lines.size() > 0) {
       
  1014 
       
  1015 				//For finding offset of method implementation, we need to collect file contents
       
  1016 				StringBuffer fileBuffer = new StringBuffer();
       
  1017 				StringBuffer tmpBuffer = null;
       
  1018 				boolean isInsideCommentSegment = false;	
       
  1019 				boolean searchForMethodDefinition = false;
       
  1020 				String methodStartingLine = null;
       
  1021 				
       
  1022 				// Seeking all findings and select wanted line
       
  1023 				for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
       
  1024 					String aLine = (String) iterator.next();//Not to be modified
       
  1025 					fileBuffer.append(aLine);//for founding out offset collecting file to buffer
       
  1026 					fileBuffer.append("\r\n"); //$NON-NLS-1$
       
  1027 					String lineWithoutComments = aLine;
       
  1028 									
       
  1029 					//If we are inside of comment segment, and this line does not contain comment segment closing
       
  1030 					//we can just skip the line because its a comment line. 
       
  1031 					if(isInsideCommentSegment && lineWithoutComments.indexOf(COMMENT_END) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1032 						continue;
       
  1033 					}
       
  1034 					//if we are inside of comment segment and this line contains comment closing segment
       
  1035 					//checking out if there is something after that comment segment line
       
  1036 					else if(isInsideCommentSegment && lineWithoutComments.indexOf(COMMENT_END) != SourceFileLocation.OFFSET_NOT_FOUND){
       
  1037 						
       
  1038 						lineWithoutComments = getLineWithOutComments(lineWithoutComments, isInsideCommentSegment);
       
  1039 						
       
  1040 						//mark that comment segment is closed if so
       
  1041 						isInsideCommentSegment = isLineClosingCommentSegment(lineWithoutComments);
       
  1042 					}										
       
  1043 					
       
  1044 					//if that line contains opening sequence to comment segment
       
  1045 					else if(lineWithoutComments.indexOf(COMMENT_START) != SourceFileLocation.OFFSET_NOT_FOUND ){
       
  1046 
       
  1047 						//case 1 / ** <comments>
       
  1048 						//case 2 ..Text / ** <comments> * /  Text..
       
  1049 						//case 3 / ** <comments> * / Text..
       
  1050 						
       
  1051 						isInsideCommentSegment = isLineOpeningCommentSegment(lineWithoutComments);
       
  1052 						lineWithoutComments = getLineWithOutComments(lineWithoutComments, isInsideCommentSegment);
       
  1053 					}
       
  1054 					//Else in this line there is no comment segment, and status nor line needs no modifications
       
  1055 
       
  1056 					//if this line does not contain methodName, just continue
       
  1057 					if(!searchForMethodDefinition && (isInsideCommentSegment || !lineWithoutComments.contains(methodName)) /*|| isCommentLine*/){
       
  1058 						continue;
       
  1059 					}
       
  1060 					boolean isCommentLine = isCommentLine(lineWithoutComments, methodName);
       
  1061 					//if this line does not contain methodName, just continue
       
  1062 					if(!searchForMethodDefinition && (isInsideCommentSegment || !lineWithoutComments.contains(methodName) || isCommentLine)){
       
  1063 						continue;
       
  1064 					}
       
  1065 					
       
  1066 					//Cut the line, because there can be e.g. MyClass::MyMethod() //;;; When ";" would cause line to drop out
       
  1067 					if(lineWithoutComments.indexOf(CODE_COMMENT_PREFIX) != SourceFileLocation.OFFSET_NOT_FOUND){
       
  1068 						lineWithoutComments = lineWithoutComments.split(Pattern.quote(CODE_COMMENT_PREFIX))[0];
       
  1069 					}
       
  1070 					
       
  1071 					/**
       
  1072 					 * If this (searchForMethodDefinition) is true, the method assumes that
       
  1073 					 * it has encountered a line with the method name but not sure whether
       
  1074 					 * its a definition point or invocation point. So, it scans for the text
       
  1075 					 * after the method name until it encounters certain delimiters, to conclude
       
  1076 					 * whether its point of definition or point of invocation.
       
  1077 					 */
       
  1078 					if(searchForMethodDefinition)
       
  1079 					{
       
  1080 						String neededText = fetchContentBeforeDefinition(lineWithoutComments);
       
  1081 						tmpBuffer.append(neededText);
       
  1082 						
       
  1083 						if(hasDelimiter(tmpBuffer.toString()))
       
  1084 						{
       
  1085 							tmpBuffer = tmpBuffer.deleteCharAt(tmpBuffer.length()-1);
       
  1086 							String contentToBeParsed = tmpBuffer.toString();
       
  1087 							boolean isMethodDefined = parseForMethodDefinition(contentToBeParsed);
       
  1088 						
       
  1089 							if(isMethodDefined)
       
  1090 							{
       
  1091 								searchForMethodDefinition = false;
       
  1092 								wantedLine = methodStartingLine;
       
  1093 								tmpBuffer = null;
       
  1094 								break;
       
  1095 							}
       
  1096 							else{
       
  1097 								searchForMethodDefinition = false;
       
  1098 								tmpBuffer = null;
       
  1099 								continue;
       
  1100 							}
       
  1101 						}
       
  1102 					}
       
  1103 					//
       
  1104 					//Now we know that this line where we are, is not inside of "/**/" -comments,
       
  1105 					//This line is not a comment line with "//":s
       
  1106 					//And this line is containing method name
       
  1107 					//					
       
  1108 
       
  1109 					//If component is DLL it exports functions, and EXPORT_C (or IMPORT_C just in case) must occur in line
       
  1110 					//This is not a perfect way to do it, but it works, because EXPORT_C definition is
       
  1111 					//most likely written to same line as method definition.
       
  1112 					if (isDll && 
       
  1113 							( lineWithoutComments.toUpperCase().indexOf(EXPORT) != SourceFileLocation.OFFSET_NOT_FOUND
       
  1114 							|| lineWithoutComments.toUpperCase().indexOf(IMPORT) != SourceFileLocation.OFFSET_NOT_FOUND)
       
  1115 							&& lineWithoutComments.indexOf(SEMI_COLON) == SourceFileLocation.OFFSET_NOT_FOUND) {
       
  1116 						wantedLine = aLine;						
       
  1117 						break;
       
  1118 					}
       
  1119 					//If the line contains function name but does not contain EXPORT_C or IMPORT_C, we will 
       
  1120 					//scan the text after method name to check if method definition has started.
       
  1121 					else if(isDll && lineWithoutComments.contains(methodName)) {
       
  1122 						tmpBuffer = new StringBuffer();
       
  1123 						tmpBuffer.append(lineWithoutComments.substring(lineWithoutComments.indexOf(methodName) + methodName.length()));
       
  1124 					
       
  1125 						methodStartingLine = aLine;
       
  1126 						searchForMethodDefinition = true;
       
  1127 					}
       
  1128 					//If method name is not [ClassName]::[MethodName] but e.g. __my_macro, excluding EXPORT_C check
       
  1129 					//But then there must be "("
       
  1130 					else if(methodName.indexOf(CLASS_SEPARATOR) == SourceFileLocation.OFFSET_NOT_FOUND
       
  1131 							&& lineWithoutComments.indexOf(SEMI_COLON) == SourceFileLocation.OFFSET_NOT_FOUND
       
  1132 							&& lineWithoutComments.indexOf(METHOD_OPENING_CHAR) != SourceFileLocation.OFFSET_NOT_FOUND){ 
       
  1133 						wantedLine = aLine;
       
  1134 						break;
       
  1135 					}
       
  1136 					
       
  1137 					//If its not dll but exe, it does not export functions, then it might be implementation 
       
  1138 					else if(!isDll && lineWithoutComments.indexOf(SEMI_COLON) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1139 						wantedLine = aLine;
       
  1140 						break;
       
  1141 					}
       
  1142 					//Else we are not interested on this line and keep seeking					
       
  1143 					else{
       
  1144 						 printUtility.println(
       
  1145 								 Messages.getString("MapSourceFinder.OffsetSeek_Msg_Part_1")  //$NON-NLS-1$
       
  1146 								 +methodName  
       
  1147 								 +Messages.getString("MapSourceFinder.OffsetSeek_Msg_Part_2")	//$NON-NLS-1$							
       
  1148 								+file.getAbsolutePath()
       
  1149 								+Messages.getString("MapSourceFinder.OffsetSeek_Msg_Part_3")//$NON-NLS-1$
       
  1150 								+lineWithoutComments
       
  1151 								+Messages.getString("MapSourceFinder.OffsetSeek_Msg_Part_4"));	//$NON-NLS-1$					
       
  1152 					}
       
  1153 
       
  1154 				}//for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
       
  1155 				if(wantedLine != null){
       
  1156 					offset = fileBuffer.lastIndexOf(wantedLine); //getOfsetForLine(lines, wantedLine);
       
  1157 				}
       
  1158 				
       
  1159 			}//if (lines.size() > 0) {
       
  1160 
       
  1161 			//Now wantedLine should be line we want, we can found out offset for that line			
       
  1162 
       
  1163 		return offset;
       
  1164 	}		
       
  1165 
       
  1166 	/**
       
  1167 	 * Get content of this line with out comments.
       
  1168 	 *  e.g. 'MyClass::Foo(TInt bar /*My comments * /)'
       
  1169 	 *  returns 'MyClass::Foo(TInt bar )'
       
  1170 	 *  NOTE: does not handle '//' comments at all
       
  1171 	 * @param line Line to remove comments from
       
  1172 	 * @param isInsideCommentSegment  set to <code>true</code>, if we are already are inside of comment segment 
       
  1173 	 * @return a line without comments
       
  1174 	 */
       
  1175 	private String getLineWithOutComments(String line, boolean isInsideCommentSegment) {
       
  1176 		
       
  1177 		// /** aa */ BB /** cc */ DD  --> Should return " BB  DD"
       
  1178 		// aa */ BB /** cc */ DD  --> Should return " BB  DD" if isInsideComment and "aa  BB  DD" if no
       
  1179 		// AA */ should return "" if inside comments, and "AA */" if not
       
  1180 		
       
  1181 		//if we are inside comments, and comment segment is not closing, 
       
  1182 		//there is no other than comments, so return empty string
       
  1183 		if(isInsideCommentSegment && line.indexOf(COMMENT_END) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1184 			return ""; //$NON-NLS-1$
       
  1185 		}
       
  1186 		//if we are not inside comments and not even start a comment just return the line
       
  1187 		else if(!isInsideCommentSegment && line.indexOf(COMMENT_START) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1188 			return line;
       
  1189 		}		
       
  1190 		//else we parse out everything else but comments
       
  1191 
       
  1192 		StringBuffer b = new StringBuffer();		
       
  1193 		String [] parts = line.split(Pattern.quote(COMMENT_START));
       
  1194 				
       
  1195 		//Splitted string goes like this:
       
  1196 		// "/** aa */ BB /** cc */ DD" -->
       
  1197 		// " aa */ BB "
       
  1198 		// " cc */ DD"
       
  1199 		for (int i = 0; i < parts.length; i++) {
       
  1200 			//Skip empty parts
       
  1201 			if(parts[i].equals("")){ //$NON-NLS-1$
       
  1202 				continue;
       
  1203 			}
       
  1204 			//If we are not inside comments, and line was not started with comments, the first part belongs to text
       
  1205 			else if(i==0 && !isInsideCommentSegment && parts[i].indexOf(COMMENT_END) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1206 				b.append(parts[i]);
       
  1207 			}
       
  1208 			//if comment is opened, but not closed, this part belongs to comment and will be skipped			
       
  1209 			else if(parts[i].indexOf(COMMENT_END) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1210 				continue;
       
  1211 			}else{
       
  1212 				b.append(parts[i].substring( parts[i].indexOf(COMMENT_END)+COMMENT_END.length() ) );
       
  1213 			}
       
  1214 		}			
       
  1215 	
       
  1216 		return b.toString();
       
  1217 	}
       
  1218 	/**
       
  1219 	 * Check if this line opens a comment segment, and is not closing it
       
  1220 	 * @param line Line to be checked.
       
  1221 	 * @return <code>true</code> if start a comment block without closing it, otherwise <code>false</code>.
       
  1222 	 */
       
  1223 	private boolean isLineOpeningCommentSegment(String line) {
       
  1224 		
       
  1225 		int commentStartIndex = line.lastIndexOf(COMMENT_START);
       
  1226 		int commentEndIndex = line.lastIndexOf(COMMENT_END);			
       
  1227 		
       
  1228 		if(commentStartIndex > commentEndIndex){
       
  1229 			return true;
       
  1230 		}
       
  1231 		
       
  1232 		return false;
       
  1233 	}
       
  1234 	
       
  1235 	/**
       
  1236 	 * Check if this line closes a comment segment
       
  1237 	 * @param line Line to be checked.
       
  1238 	 * @return <code>true</code> if line closes comment segment, otherwise <code>false</code>.
       
  1239 	 */
       
  1240 	private boolean isLineClosingCommentSegment(String line) {
       
  1241 		
       
  1242 		int commentStartIndex = line.lastIndexOf(COMMENT_START);
       
  1243 		int commentEndIndex = line.lastIndexOf(COMMENT_END);			
       
  1244 		
       
  1245 		if(commentEndIndex > commentStartIndex){
       
  1246 			return true;
       
  1247 		}
       
  1248 		
       
  1249 		return false;
       
  1250 	}	
       
  1251 	
       
  1252 	
       
  1253 	/**
       
  1254 	 * Check if this line is comment line starting with //
       
  1255 	 * @param line Line to be checked.
       
  1256 	 * @return <code>true</code> if line starts with //, otherwise <code>false</code>.
       
  1257 	 */
       
  1258 	private boolean isCommentLine(String line, String methodName) {
       
  1259 		if(line.trim().startsWith(CODE_COMMENT_PREFIX)){
       
  1260 			return true;
       
  1261 		}
       
  1262 		else if(line.indexOf(CODE_COMMENT_PREFIX) != SourceFileLocation.OFFSET_NOT_FOUND){
       
  1263 			
       
  1264 			int commentIndex = line.indexOf(CODE_COMMENT_PREFIX);
       
  1265 			int methodNameIndex = line.indexOf(methodName);
       
  1266 			if(commentIndex > methodNameIndex){
       
  1267 				return false;
       
  1268 			}else{
       
  1269 				return true;
       
  1270 			}
       
  1271 		}else{
       
  1272 			return false;
       
  1273 		}
       
  1274 	}
       
  1275 	
       
  1276 	/**
       
  1277 	 * Gets *.map file path.
       
  1278 	 * @param componentName Component name.
       
  1279 	 * @param variant Build variant.
       
  1280 	 * @param build Build type (urel/udeb).
       
  1281 	 * @param epocRootPath EPOCROOT path.
       
  1282 	 * @return path to .dll file +MAP_FILE_SUFFIX
       
  1283 	 */
       
  1284 	private String getMapFilePath(String componentName, String variant, String build,
       
  1285 			String epocRootPath) {
       
  1286 		String mapPath = 
       
  1287 			epocRootPath + File.separatorChar 
       
  1288 			+SourceFileLocation.EPOC32_FOLDER_NAME + File.separatorChar
       
  1289 			+SourceFileLocation.RELEASE_FOLDER_NAME + File.separatorChar
       
  1290 			+variant + File.separatorChar
       
  1291 			+build + File.separatorChar
       
  1292 			+componentName
       
  1293 			+MAP_FILE_SUFFIX;
       
  1294 		mapPath = makeWindowsPath(mapPath);
       
  1295 		return mapPath;
       
  1296 		}
       
  1297 	
       
  1298 	/* (non-Javadoc)
       
  1299 	 * @see com.nokia.s60tools.util.sourcecode.ISourcesFinder#findSourceFiles(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
       
  1300 	 */
       
  1301 	public String[] findSourceFiles(String componentName,
       
  1302 			String variant, String build, String epocRootPath
       
  1303 			) throws CannotFoundFileException {
       
  1304 		
       
  1305 		try {
       
  1306 			//Projects map file
       
  1307 			String mapFilePath = getMapFilePath(componentName, variant, build, epocRootPath);
       
  1308 			File mapFile = getMapFile(mapFilePath);
       
  1309 		
       
  1310 			String objectFileName = componentName.split(Pattern.quote("."))[0]; //$NON-NLS-1$
       
  1311 
       
  1312 			//Get all source file paths from map file
       
  1313 			String sourcePaths [] = getAllSourceFilePaths(mapFile, epocRootPath, objectFileName);
       
  1314 
       
  1315 			return sourcePaths;
       
  1316 			
       
  1317 		}  catch (FileNotFoundException e) {
       
  1318 			e.printStackTrace();
       
  1319 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1320 		} catch (IOException e) {
       
  1321 			e.printStackTrace();
       
  1322 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1323 		} catch (Exception e) {
       
  1324 			e.printStackTrace();
       
  1325 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1326 		}			
       
  1327 		
       
  1328 	}	
       
  1329 
       
  1330 	/* (non-Javadoc)
       
  1331 	 * @see com.nokia.s60tools.util.sourcecode.ISourcesFinder#findSourceFiles(java.lang.String, java.lang.String, java.util.Collection)
       
  1332 	 */
       
  1333 	public String[] findSourceFiles(String componentName,
       
  1334 			 String epocRootPath, Collection<String> pathsToSeekMapFile
       
  1335 			) throws CannotFoundFileException {
       
  1336 		
       
  1337 		try {
       
  1338 			//Projects map file
       
  1339 			String mapFileName = componentName + MAP_FILE_SUFFIX;
       
  1340 			
       
  1341 			File mapFile = getMapFile(pathsToSeekMapFile, componentName, mapFileName);
       
  1342 		
       
  1343 			//If we did not found map file, we cannot proceed to src file seek
       
  1344 			if(mapFile == null){
       
  1345 				String msg = "'" + mapFileName  //$NON-NLS-1$
       
  1346 					+"' " //$NON-NLS-1$
       
  1347 					+Messages.getString("MapSourceFinder.MapFileNotFoundForSource_ErrMsg_Part1") //$NON-NLS-1$
       
  1348 					+componentName; 
       
  1349 				String consoleMsg = msg + " "  //$NON-NLS-1$
       
  1350 					+Messages.getString("MapSourceFinder.MapFileNotFoundForSource_ErrMsg_Part2"); //$NON-NLS-1$
       
  1351 
       
  1352 				String pathSeparator= ", "; //$NON-NLS-1$
       
  1353 				for (Iterator<String> iterator = pathsToSeekMapFile.iterator(); iterator
       
  1354 						.hasNext();) {
       
  1355 					String path = (String) iterator.next();
       
  1356 					consoleMsg += path + pathSeparator;
       
  1357 				}
       
  1358 				consoleMsg = consoleMsg.substring(0, consoleMsg.length() - pathSeparator.length());
       
  1359 				printUtility.println(consoleMsg, IConsolePrintUtility.MSG_ERROR);
       
  1360 				throw new CannotFoundFileException(msg);
       
  1361 			}
       
  1362 			String objectFileName = componentName.split(Pattern.quote("."))[0]; //$NON-NLS-1$
       
  1363 
       
  1364 			//Get all source file paths from map file
       
  1365 			String sourcePaths [] = getAllSourceFilePaths(mapFile, epocRootPath, objectFileName);
       
  1366 
       
  1367 			return sourcePaths;
       
  1368 			
       
  1369 		}  catch (FileNotFoundException e) {
       
  1370 			e.printStackTrace();
       
  1371 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1372 		} catch (IOException e) {
       
  1373 			e.printStackTrace();
       
  1374 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1375 		} catch (Exception e) {
       
  1376 			e.printStackTrace();
       
  1377 			throw new CannotFoundFileException(e.getMessage() , e);
       
  1378 		}			
       
  1379 		
       
  1380 	}
       
  1381 	/**
       
  1382 	 * Get all source file lines from given file.
       
  1383 	 * @param file File object to be checked for.
       
  1384 	 * @param epocRootPath EPOCROOT path.
       
  1385 	 * @param objectFileName Object file name used to filter results.
       
  1386 	 * @return all source file lines from given file.
       
  1387 	 * @throws IOException
       
  1388 	 */
       
  1389 	private String[] getAllSourceFilePaths(File file, String epocRootPath, String objectFileName) throws IOException {
       
  1390 
       
  1391 	FileInputStream in = null;
       
  1392 	InputStreamReader isr = null;
       
  1393 	BufferedReader br = null;
       
  1394 	//HashSet does not allow duplicates
       
  1395 	HashSet<String> sourceFilePaths = new HashSet<String>();
       
  1396 
       
  1397 	try {
       
  1398 		in = new FileInputStream(file);
       
  1399 		isr = new InputStreamReader(in);
       
  1400 		br = new BufferedReader(isr);
       
  1401 
       
  1402 		String line = null;
       
  1403 
       
  1404 		// seek wanted text from file line by line
       
  1405 		while ((line = br.readLine()) != null) {
       
  1406 			// if we found wanted text, stopping search
       
  1407 			String srcLine = isSourceFilePathLine(line, epocRootPath, objectFileName); 
       
  1408 			if (srcLine != null) {
       
  1409 				sourceFilePaths.add(srcLine);
       
  1410 			}
       
  1411 		}
       
  1412  
       
  1413 	} finally {
       
  1414 		if (in != null) {
       
  1415 			in.close();
       
  1416 		}
       
  1417 		if (isr != null) {
       
  1418 			isr.close();
       
  1419 		}
       
  1420 		if (br != null) {
       
  1421 			br.close();
       
  1422 		}
       
  1423 	}
       
  1424 
       
  1425 		return (String []) sourceFilePaths.toArray(new String [0]);
       
  1426 	}
       
  1427 	
       
  1428 	/**
       
  1429 	 * Check if line from file is a source file line or not.
       
  1430 	 * @param line Line to be checked.
       
  1431 	 * @param epocRootPath EPOCROOT path.
       
  1432 	 * @param objectFileName Object file name used to filter results.
       
  1433 	 * @return Path to src file or <code>null</code> if it was not src line.
       
  1434 	 */
       
  1435 	private String isSourceFilePathLine(String line, String epocRootPath, String objectFileName) {
       
  1436 		
       
  1437 //		 * Source file lines are e.g. lines:
       
  1438 //	 *  \s60\mw\web\WebEngine\OssWebengine\WebCore\kwq\kwqvariant.cpp 0x00000000   Number         0  KWQVariant.o ABSOLUTE
       
  1439 //	 *  \src\cedar\generic\base\e32\EUSER\EPOC\ up_dll_file.cpp 0x00000000   Number         0  up_dll_file.o ABSOLUTE
       
  1440 //	 *  \\src\\cedar\\generic\\BASE\\E32\\compsupp\\RVCT2_2\\ucppinit_aeabi.cpp 0x00000000   Number         0  ucppinit_aeabi.o ABSOLUTE
       
  1441 
       
  1442 //	 * but not lines:
       
  1443 //	 *  \EPOC32\BUILD\src\COMMON\GENERIC\comms-infras\esock\group\ESOCK\ARMV5\VtblExports.s 0x00000000   Number         0  VtblExports.o ABSOLUTE
       
  1444 //	 *  \EPOC32\BUILD\src\cedar\generic\base\e32\EDLL\ARMV5\ urel\ uc_dll_.cpp 0x00000000   Number         0  uc_dll_.o ABSOLUTE
       
  1445 //	 *  \\EPOC32\\BUILD\\src\\cedar\\generic\\base\\e32\\EDLL\\ARMV5\\urel\\uc_dll_.cpp 0x00000000   Number         0  uc_dll_.o ABSOLUTE
       
  1446 
       
  1447 		//   Also source codes can be from users own source projects, e.g.
       
  1448 //		\Projects\Trombi\Carbide\creator\src\creatormailboxelement.cpp 0x00000000   Number         0  creator.in ABSOLUTE
       
  1449 		
       
  1450 		if(line == null || line.trim().length() < 1){
       
  1451 			return null;
       
  1452 		}
       
  1453 		
       
  1454 		if( (line.contains(CPP_SUFFIX) || line.contains(C_SUFFIX) )&& 
       
  1455 				line.contains(NULL_ADDRESS) &&
       
  1456 				line.contains(ABSOLUTE) &&
       
  1457 				line.toLowerCase().contains(objectFileName.toLowerCase())){
       
  1458 			
       
  1459 			//if we found wanted text, checking that it does not contain 
       
  1460 			//\EPOC32\BUILD or \\EPOC32\\BUILD, because then its not a source, but build file
       
  1461 			//fixing slashes so we can find epoc32 build folder in any cases.
       
  1462 			String srcPath = line.replace("/", BACKSLASH).trim(); //$NON-NLS-1$ //$NON-NLS-2$
       
  1463 			//removing multiple spaces: " +" means more than one white spaces, e.g. "a    b c" -> "a b c"
       
  1464 
       
  1465 			//Making sure that souce location does not point to BUILD folder
       
  1466 			if(srcPath.indexOf(EPOC32_BUILD) == SourceFileLocation.OFFSET_NOT_FOUND 
       
  1467 					&& srcPath.indexOf(EPOC32_BUILD_DOUBLE_SLASHES) == SourceFileLocation.OFFSET_NOT_FOUND){
       
  1468 				
       
  1469 				if(!srcPath.startsWith(BACKSLASH)){
       
  1470 					srcPath = BACKSLASH + srcPath;
       
  1471 				}
       
  1472 				
       
  1473 				//if path starts with src\... or s60\... its a symbian or S60 src path
       
  1474 				if(srcPath.startsWith( SRC_PATH_PREFIX) || srcPath.startsWith( S60_PATH_PREFIX) 
       
  1475 						|| srcPath.startsWith( SRC_PATH_PREFIX_DOUBLE_SLASHS) || srcPath.startsWith( S60_PATH_PREFIX_DOUBLE_SLASHS)
       
  1476 						)
       
  1477 				{
       
  1478 					
       
  1479 					String srcPathOrig = srcPath.substring(0, srcPath.indexOf(NULL_ADDRESS)).trim();
       
  1480 					srcPath = epocRootPath + srcPathOrig;
       
  1481 					srcPath = makeWindowsPath(srcPath);
       
  1482 					// Making sure that path does not have duplicate EPOCROOT.
       
  1483 					File file = stripEpocRootFromPath(srcPathOrig, epocRootPath, new File(srcPath));
       
  1484 					return file.getAbsolutePath();
       
  1485 				}
       
  1486 				//otherwise it can be users own source codes from own projects, and path can be anything
       
  1487 				//then cheking that found source file path is actually real path to existing file
       
  1488 				else{
       
  1489 					String srcPathOrig = srcPath.substring(0, srcPath.indexOf(NULL_ADDRESS)).trim();
       
  1490 					srcPath = epocRootPath + srcPathOrig;
       
  1491 					srcPath = makeWindowsPath(srcPath);
       
  1492 					// Making sure that path does not have duplicate EPOCROOT.
       
  1493 					File file = stripEpocRootFromPath(srcPathOrig, epocRootPath, new File(srcPath));
       
  1494 					if(file.exists()){
       
  1495 						return file.getAbsolutePath();		
       
  1496 					}
       
  1497 				}
       
  1498 			}
       
  1499 			
       
  1500 		}
       
  1501 				
       
  1502 		return null;
       
  1503 	}
       
  1504 	
       
  1505 	/**
       
  1506 	 * The method parses the given content for certain characters in a specific order
       
  1507 	 * to determine whether method definition has started or not.
       
  1508 	 * @param lineContent content to be parsed.
       
  1509 	 * @return true if the method definition is started else false.
       
  1510 	 */
       
  1511 	private boolean parseForMethodDefinition(String lineContent)
       
  1512 	{
       
  1513 		Stack<Character> chars_stack = new Stack<Character>();
       
  1514 		char [] line_chars = lineContent.toCharArray();
       
  1515 		
       
  1516 		final char METHOD_OPENING_CHAR = '(';
       
  1517 		final char METHOD_CLOSING_CHAR = ')';
       
  1518 		final char METHOD_DEFINITION_OPENING_CHAR = '{';
       
  1519 		
       
  1520 		for(char c: line_chars)
       
  1521 		{
       
  1522 			switch(c){
       
  1523 				case METHOD_OPENING_CHAR:
       
  1524 				case METHOD_CLOSING_CHAR:
       
  1525 				case METHOD_DEFINITION_OPENING_CHAR:
       
  1526 					chars_stack.push(c);
       
  1527 					break;
       
  1528 			}
       
  1529 		}
       
  1530 		
       
  1531 		while(!chars_stack.isEmpty())
       
  1532 		{
       
  1533 			Character lastChar = chars_stack.pop();
       
  1534 			
       
  1535 			if(lastChar == METHOD_DEFINITION_OPENING_CHAR)
       
  1536 			{
       
  1537 				char prevChar_1 = chars_stack.pop();
       
  1538 				char prevChar_2 = chars_stack.pop();
       
  1539 				
       
  1540 				if((prevChar_1 == METHOD_CLOSING_CHAR) && (prevChar_2 == METHOD_OPENING_CHAR))
       
  1541 					return true;
       
  1542 			}
       
  1543 		}
       
  1544 		return false;
       
  1545 		
       
  1546 	}
       
  1547 	
       
  1548 	/**
       
  1549 	 * The method checks for some predefined delimiter characters and 
       
  1550 	 * returns the content before those characters.
       
  1551 	 * @param input 
       
  1552 	 * @return
       
  1553 	 */
       
  1554 	private String fetchContentBeforeDefinition(String input)
       
  1555 	{
       
  1556 		if(input.contains(SEMI_COLON))
       
  1557 		{
       
  1558 			if(input.contains(METHOD_DEFINITION_CLOSING_CHAR)
       
  1559 					&& input.indexOf(METHOD_DEFINITION_CLOSING_CHAR) < input.indexOf(SEMI_COLON))
       
  1560 				return input.substring(0, input.indexOf(METHOD_DEFINITION_CLOSING_CHAR) +1);
       
  1561 			else	
       
  1562 				return input.substring(0, input.indexOf(SEMI_COLON) +1);
       
  1563 		}
       
  1564 		else if(input.contains(METHOD_DEFINITION_CLOSING_CHAR)){
       
  1565 			return input.substring(0, input.indexOf(METHOD_DEFINITION_CLOSING_CHAR) +1);
       
  1566 		}
       
  1567 		else{
       
  1568 			return input.toString();
       
  1569 		}
       
  1570 	}
       
  1571 	
       
  1572 	private boolean hasDelimiter(String line)
       
  1573 	{
       
  1574 		if(line.contains(METHOD_DEFINITION_CLOSING_CHAR) ||
       
  1575 				line.contains(SEMI_COLON))
       
  1576 			return true;
       
  1577 		else
       
  1578 			return false;
       
  1579 	}
       
  1580 	
       
  1581 }