private String getSourceFilePosition(String className, String methodName, String sourceCode, String preprocessedSourcePath, File[] sourceDirs)
private String getSourceFilePosition(String className, String methodName, String sourceCode, String preprocessedSourcePath, File[] sourceDirs, Map environmentProperties)
	private String getSourceFilePosition(String className, String methodName, String sourceCode, String preprocessedSourcePath, File[] sourceDirs) 	{		// first find the position in the preprocessed source code		// secondly find the original source-file in the provided source-files.				// find position of call 		String javaFileName = TextUtil.replace( className, '.', File.separatorChar )  + ".java";		preprocessedSourcePath = preprocessedSourcePath + File.separatorChar + javaFileName;		this.linesFromMethodStart -= 2;		if (this.linesFromMethodStart < 1) {			this.linesFromMethodStart = 1;		}		//System.out.println("searching for source-code [" + sourceCode + "] in method [" + methodName + "].");		CodeSequence codeSequence = new CodeSequence( sourceCode );		try {			String[] lines = FileUtil.readTextFile( preprocessedSourcePath );			int sourceFilePos = -1;			String preprocessedSourceCodeLine = null;			for (int i = 0; i < lines.length; i++) {				String line = lines[i];				if (line.indexOf(methodName) != -1) {					Matcher matcher = METHOD_PATTERN.matcher(line);					char firstChar = line.trim().charAt(0);					if ( (firstChar == '*')							|| (firstChar == '/')							|| (!matcher.find()) 							|| (matcher.group().startsWith("return")) ) {						continue;					}					//System.out.println("found method in line [" + i + "]: " + line );					int start = i + this.linesFromMethodStart;					int toAdd = 10;					if (this.linesFromMethodStart > 20) {						toAdd = this.linesFromMethodStart/2;					}					int end = start + toAdd;					if (end > lines.length) {						end = lines.length;					}					//System.out.println("lines from method start: " + this.linesFromMethodStart  + " checking range from " + start + " to " + end + " in " + preprocessedSourcePath);					for (int j = start; j < end; j++) {						line = lines[j];						if ( codeSequence.matches( line ) ) {							sourceFilePos = j;							preprocessedSourceCodeLine = line.trim();							break;						}											}					if (sourceFilePos != -1) {						break;					} else {						// try again from the method-start until [start]:						for (int j = i+1; j < start; j++) {							line = lines[j];							if ( codeSequence.matches( line ) ) {								sourceFilePos = j;								preprocessedSourceCodeLine = line.trim();								break;							}												}						if (sourceFilePos != -1) {							break;						//} else {												//	System.out.println("unable to call from lines " + (i+1) + " to " + end ) ;						}					}				}			}			if ( sourceFilePos == -1 ) {				//System.out.println("did not find source position");				return null;			}			// okay, we found the position of the faulty call:			// search for the original source file:			for (int i = 0; i < sourceDirs.length; i++) {				File dir = sourceDirs[i];				File originalFile = new File( dir.getAbsolutePath() + File.separatorChar + javaFileName );				if (originalFile.exists()) {					return  "   = " + originalFile.getAbsolutePath() + ":" + (sourceFilePos + 1) + ": \n\t\t" + preprocessedSourceCodeLine;				}			}			// did not find original file:			// now return the reference to the preprocessed source class file:			int separatorPos = javaFileName.lastIndexOf( File.separatorChar );			if (separatorPos != -1) {				javaFileName = javaFileName.substring( separatorPos + 1 );			}			return "   = " + javaFileName + ":" + (sourceFilePos + 1) + ":\n\t\t" + preprocessedSourceCodeLine;		} catch (FileNotFoundException e) {			System.out.println("Unable to resolve stacktrace: did not find source file [" + preprocessedSourcePath + "].");			return null;		} catch (IOException e) {			System.out.println("Unable to resolve stacktrace: unable to read source file [" + preprocessedSourcePath + "]: " + e );			return null;		}	}