Index: .classpath
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/.classpath,v
retrieving revision 1.6
diff -u -r1.6 .classpath
--- .classpath	3 May 2005 13:31:17 -0000	1.6
+++ .classpath	2 Sep 2005 07:39:42 -0000
@@ -13,5 +13,6 @@
 	<classpathentry kind="src" path="/testing-util"/>
 	<classpathentry kind="src" path="/testing-client"/>
 	<classpathentry kind="src" path="/org.eclipse.jdt.core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: .project
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/.project,v
retrieving revision 1.2
diff -u -r1.2 .project
--- .project	13 Aug 2004 15:18:01 -0000	1.2
+++ .project	2 Sep 2005 07:39:42 -0000
@@ -4,6 +4,7 @@
 	<comment></comment>
 	<projects>
 		<project>asm</project>
+		<project>aspectj5rt</project>
 		<project>bridge</project>
 		<project>org.eclipse.jdt.core</project>
 		<project>runtime</project>
Index: src/org/aspectj/ajdt/ajc/BuildArgParser.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java,v
retrieving revision 1.40
diff -u -r1.40 BuildArgParser.java
--- src/org/aspectj/ajdt/ajc/BuildArgParser.java	23 Aug 2005 08:47:32 -0000	1.40
+++ src/org/aspectj/ajdt/ajc/BuildArgParser.java	2 Sep 2005 07:39:43 -0000
@@ -171,6 +171,7 @@
 			}
 			
 			buildConfig.setFiles(fileList);
+			buildConfig.setUserFileNameMap(parser.getUserFileNameMap());
 			if (destinationPath != null) { // XXX ?? unparsed but set?
 				buildConfig.setOutputDir(new File(destinationPath));
 			}
Index: src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java,v
retrieving revision 1.28
diff -u -r1.28 AjBuildConfig.java
--- src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java	23 Aug 2005 08:47:14 -0000	1.28
+++ src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java	2 Sep 2005 07:39:43 -0000
@@ -44,6 +44,7 @@
 	private File outputJar;
 	private List/*File*/ sourceRoots = new ArrayList();
 	private List/*File*/ files = new ArrayList();
+	private Map/*File -> File*/ userFileNameMap = new HashMap();
 	private List /*File*/ binaryFiles = new ArrayList();  // .class files in indirs...
 	private List/*File*/ inJars = new ArrayList();
 	private List/*File*/ inPath = new ArrayList();
@@ -117,6 +118,10 @@
 	public List/*File*/ getFiles() {
 		return files;
 	}
+	
+	public Map/* File -> File*/ getUserFileNameMap() {
+		return userFileNameMap;
+	}
 
 	/**
 	 * returned files includes all .class files found in
@@ -134,6 +139,10 @@
 	public void setFiles(List files) {
 		this.files = files;
 	}
+	
+	public void setUserFileNameMap(Map userFileNameMap) {
+		this.userFileNameMap = userFileNameMap;
+	}
 
 	public void setOutputDir(File outputDir) {
 		this.outputDir = outputDir;
Index: src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java,v
retrieving revision 1.73
diff -u -r1.73 AjBuildManager.java
--- src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java	23 Aug 2005 21:30:11 -0000	1.73
+++ src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java	2 Sep 2005 07:39:45 -0000
@@ -165,8 +165,11 @@
             if (!canIncremental && !batch) { // retry as batch?
                 return doBuild(buildConfig, baseHandler, true);
             }
+            IMessageHandler userTranslatingHandler = 
+            	new UserFileLocationTranslatingHandler(baseHandler,buildConfig.getUserFileNameMap());
             this.handler = 
-                CountingMessageHandler.makeCountingMessageHandler(baseHandler);
+                CountingMessageHandler.makeCountingMessageHandler(userTranslatingHandler);
+            ;
             // XXX duplicate, no? remove?
             String check = checkRtJar(buildConfig);
             if (check != null) {
Index: testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java,v
retrieving revision 1.16
diff -u -r1.16 AjBuildManagerTest.java
--- testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java	23 Jan 2004 19:07:52 -0000	1.16
+++ testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java	2 Sep 2005 07:39:46 -0000
@@ -89,6 +89,29 @@
 //			((StructureNode)StructureModelManager.INSTANCE.getStructureModel().getRoot().getChildren().get(0)).getChildren()
 //		);
 	}
+	
+	public void testUserFileTranslationInErrorMessages() throws IOException {
+		AjBuildManager manager = new AjBuildManager(messageWriter);
+		BuildArgParser parser = new BuildArgParser(messageWriter);
+		String javaClassPath = System.getProperty("java.class.path");
+        AjBuildConfig buildConfig = 
+			parser.genBuildConfig(new String[] { 
+				"-d", "out", 
+				"-classpath",
+				javaClassPath,
+				AjdtAjcTests.TESTDATA_PATH 
+                + "/src1/DeclareWarning.java",
+//				EajcModuleTests.TESTDATA_PATH + "/src1/Hello.java",
+				 });
+        String err = parser.getOtherMessages(true);		
+        assertTrue(err, null == err);
+        manager.setStructureModel(AsmManager.getDefault().getHierarchy());
+		MessageHandler handler = new MessageHandler();
+        manager.batchBuild(buildConfig, handler);
+        IMessage[] warnings = handler.getMessages(IMessage.WARNING, false);
+        assertEquals("1 warning",1,warnings.length);
+        assertTrue("source file mapped back to user location",warnings[0].getSourceLocation().getSourceFile().getPath().startsWith(".."));
+	}
 		
 	  
 	
Index: src/org/aspectj/ajdt/internal/core/builder/UserFileLocationTranslatingHandler.java
===================================================================
RCS file: src/org/aspectj/ajdt/internal/core/builder/UserFileLocationTranslatingHandler.java
diff -N src/org/aspectj/ajdt/internal/core/builder/UserFileLocationTranslatingHandler.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/aspectj/ajdt/internal/core/builder/UserFileLocationTranslatingHandler.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,97 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer			Initial implementation
+ * ******************************************************************/
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.bridge.IMessage.Kind;
+
+/**
+ * @author colyer
+ *
+ */
+public class UserFileLocationTranslatingHandler implements IMessageHandler {
+
+	private IMessageHandler delegate;
+	private Map userFileNameMap;
+	
+	public UserFileLocationTranslatingHandler(IMessageHandler delegateHandler, Map canonicalFileToUserFile) {
+		this.delegate = delegateHandler;
+		this.userFileNameMap = canonicalFileToUserFile;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
+	 */
+	public boolean handleMessage(IMessage message) throws AbortException {
+		IMessage messageToIssue = message;
+		ISourceLocation location = message.getSourceLocation();
+		if (location != null) {
+			File sourceFile = location.getSourceFile();
+			if (userFileNameMap.containsKey(sourceFile)) {
+				File userFile = (File) userFileNameMap.get(sourceFile);
+				if (!sourceFile.getPath().equals(userFile.getPath())) {
+					// path as known to user is different to the canonical path we have been
+					// working with. Could be due to eg. symbolic links in filesystem etc.
+					// this upsets clients such as AJDT
+					messageToIssue = replaceLocationsIn(message);
+				}
+			}
+		}
+		return delegate.handleMessage(messageToIssue);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+	 */
+	public boolean isIgnoring(Kind kind) {
+		return delegate.isIgnoring(kind);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind)
+	 */
+	public void dontIgnore(Kind kind) {
+		delegate.dontIgnore(kind);
+	}
+
+	private IMessage replaceLocationsIn(IMessage message) {
+		ISourceLocation newSourceLocation = replaceLocationIn(message.getSourceLocation());
+		List extraLocations = message.getExtraSourceLocations();
+		List newExtraLocations = new ArrayList();
+		for (Iterator iter = extraLocations.iterator(); iter.hasNext();) {
+			ISourceLocation loc = (ISourceLocation) iter.next();
+			newExtraLocations.add(replaceLocationIn(loc));
+		}
+		Message copyWithUpdatedLocation = new Message(message,newSourceLocation,newExtraLocations);
+		return copyWithUpdatedLocation;
+	}
+	
+	private ISourceLocation replaceLocationIn(ISourceLocation location) {
+		File newSourceFile = location.getSourceFile();
+		if (userFileNameMap.containsKey(newSourceFile)) {
+			newSourceFile = (File) userFileNameMap.get(newSourceFile);
+		}
+		SourceLocation newSourceLocation = new SourceLocation(location,newSourceFile);
+		return newSourceLocation;
+	}
+}
