diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts b/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts
index 422b99ae02b..c89f4945db9 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts
@@ -2978,6 +2978,7 @@ class test
 
 //=
 =>leading
+#ifndef TEST_H_ = //TEST
 =>trailing
 =>freestanding
 
@@ -2999,6 +3000,9 @@ class test
 
 //=
 =>leading
+#ifndef TEST_H_ = /*
+ * Licence information...
+ */
 =>trailing
 =>freestanding
 
@@ -3021,6 +3025,9 @@ class test
 
 //=
 =>leading
+#ifndef TEST_H_ = /*
+ * Licence information...
+ */
 class test
 {
 }; = //test
@@ -3054,7 +3061,11 @@ private:
 
 //=
 =>leading
+#ifndef HIDEMETHOD_H_ = /*
+ * HideMethod.h
+ */
 =>trailing
+#endif = /* HIDEMETHOD_H_ */
 =>freestanding
 
 //!CommentRecognition Bug 233438
@@ -3077,6 +3088,7 @@ private:
 //=
 =>leading
 =>trailing
+#endif = /* HIDEMETHOD_H_ */
 =>freestanding
 
 //@test.cpp
@@ -3122,6 +3134,7 @@ private:
 //=
 =>leading
 =>trailing
+#endif = /* HIDEMETHOD_H_ */
 =>freestanding
 
 //@test.cpp
@@ -3145,4 +3158,44 @@ int HideMethod::methode2(){
 =>trailing
 i++; = //comment
 =>freestanding
+//!CommentRecognition preprocessor directives comment recognition
+//#org.eclipse.cdt.core.parser.tests.rewrite.comenthandler.CommentHandlingTest
+//@main.cpp
+//c1
+int i;//c2
+//inc1
 
+//inc2
+
+#include "foo.h" /*inc3*/ /*inc4*/
+//main
+int main() {
+	return 0;
+	//block1
+}
+//ifdef1
+#ifdef X //ifdef2
+//=
+=>leading
+int i; = //c1
+#include "foo.h" = //inc1 , //inc2
+int main() {
+	return 0;
+	//block1
+} = //main
+#ifdef X = //ifdef1
+=>trailing
+int i; = //c2
+#include "foo.h" = /*inc3*/ , /*inc4*/
+#ifdef X = //ifdef2
+=>freestanding
+{
+	return 0;
+	//block1
+} = //block1
+//@foo.h
+void foo();
+//=
+=>leading
+=>trailing
+=>freestanding
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenter.java
index a7d748a3333..402fb71444f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenter.java
@@ -12,9 +12,9 @@
 package org.eclipse.cdt.internal.core.dom.rewrite.commenthandler;
 
 import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.Iterator;
 import java.util.List;
-import java.util.TreeMap;
 
 import org.eclipse.cdt.core.dom.ast.ASTVisitor;
 import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
@@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTComment;
 import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
 import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
 import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
 import org.eclipse.cdt.core.dom.ast.IASTInitializer;
@@ -33,15 +34,10 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
 import org.eclipse.cdt.core.dom.ast.IASTStatement;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.dom.ast.IASTTypeId;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
 import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
 
 /**
  * This is the starting point of the entire comment handling  process. The creation of the 
@@ -56,33 +52,40 @@ import org.eclipse.core.runtime.Path;
  */
 public class ASTCommenter {
 	
-	private static final class PPRangeChecker extends ASTVisitor {
-		int ppOffset;
-		int commentOffset;
-		boolean isPrePPComment = true;
+	private static final class PreprocessorRangeChecker extends ASTVisitor {
+		int statementOffset;
+		IASTFileLocation commentNodeLocation;
+		boolean isPreStatementComment = true;
 		
-		private PPRangeChecker(boolean visitNodes, int nextPPOfset, int commentNodeOffset) {
-			super(visitNodes);
-			ppOffset = nextPPOfset;
-			commentOffset = commentNodeOffset;
+		private PreprocessorRangeChecker(int statementOffset, IASTFileLocation commentNodeLocation) {
+			super(true);
+			this.statementOffset = statementOffset;
+			this.commentNodeLocation = commentNodeLocation;
 		}
 
 		private int checkOffsets(IASTNode node) {
 			int offset = ((ASTNode)node).getOffset();
-			int status = ASTVisitor.PROCESS_CONTINUE;
+			int status = PROCESS_CONTINUE;
 			
-			if (offset > commentOffset && offset < ppOffset) {
-				isPrePPComment = false;
-				status = ASTVisitor.PROCESS_ABORT;
-			} else if ((offset + ((ASTNode)node).getLength() < commentOffset)) {
-				status = ASTVisitor.PROCESS_SKIP;
-			} else if (offset > ppOffset) {
-				status = ASTVisitor.PROCESS_ABORT;
+			if (isCommentOnSameLine(node) 
+					|| offset > commentNodeLocation.getNodeOffset()
+					&& offset < statementOffset) {
+				isPreStatementComment = false;
+				status = PROCESS_ABORT;
+			} else if ((offset + ((ASTNode) node).getLength() < commentNodeLocation.getNodeOffset())) {
+				status = PROCESS_SKIP;
+			} else if (offset > statementOffset) {
+				status = PROCESS_ABORT;
 			}
 			
 			return status;
 		}
 
+		private boolean isCommentOnSameLine(IASTNode node) {
+			return commentNodeLocation.getStartingLineNumber() == node.getFileLocation()
+					.getEndingLineNumber();
+		}
+
 		@Override
 		public int visit(ICPPASTBaseSpecifier baseSpecifier) {
 			return checkOffsets(baseSpecifier);
@@ -168,141 +171,115 @@ public class ASTCommenter {
 	 * Creates a NodeCommentMap for the given TranslationUnit. This is the only way
 	 * to get a NodeCommentMap which contains all the comments mapped against nodes.
 	 * 
-	 * @param transUnit TranslationUnit
+	 * @param tu TranslationUnit
 	 * @return NodeCommentMap
 	 */
-	public static NodeCommentMap getCommentedNodeMap(IASTTranslationUnit transUnit){
-		if (transUnit == null) {
-			return new NodeCommentMap();
+	public static NodeCommentMap getCommentedNodeMap(IASTTranslationUnit tu){
+		NodeCommentMap commentMap = new NodeCommentMap();
+		if (tu == null) {
+			return commentMap;
 		}
-		List<IASTComment> comments = removeNotNeededComments(transUnit);		
-		if (comments == null || comments.isEmpty()) {
-			return new NodeCommentMap();
+		IASTComment[] commentsArray = tu.getComments();
+		if (commentsArray == null) {
+			return commentMap;
 		}
-		return addCommentsToCommentMap(transUnit, comments);
+		// Note that constructing a real ArrayList is required here, since in filterNonTuComments, the
+		// remove-method will be invoked on the list's iterator. Calling it on the type Arrays$ArrayList (the
+		// resulting type of Arrays.asList() ) would throw a UnsupportedOperationException.
+		ArrayList<IASTComment> comments = new ArrayList<IASTComment>(Arrays.asList(commentsArray));
+		filterNonTuComments(comments);
+		return addCommentsToCommentMap(tu, comments);
 	}
 
-	private static List<IASTComment> removeNotNeededComments(IASTTranslationUnit transUnit) {
-		List<IASTComment> comments = getCommentsInWorkspace(transUnit);
-		if (comments == null || comments.isEmpty()) {
-			return null;
+	/**
+	 * Note that passing an ArrayList (instead of just List or Collection) is required here, since this
+	 * guarantees that the call to the remove-method on the list's iterator will not result in an
+	 * UnsupportedOperationException which might be the case for other Collection/List types.
+	 */
+	private static void filterNonTuComments(ArrayList<IASTComment> comments) {
+		Iterator<IASTComment> iterator = comments.iterator();
+		while (iterator.hasNext()) {
+			if (!iterator.next().isPartOfTranslationUnitFile()) {
+				iterator.remove();
+			}
 		}
-		return removeAllPreprocessorComments(transUnit, comments);
 	}
 
-	private static List<IASTComment> getCommentsInWorkspace(IASTTranslationUnit tu) {
-		IASTComment[] comments = tu.getComments();
-		ArrayList<IASTComment> commentsInWorkspace = new ArrayList<IASTComment>();
-
-		if (comments == null || comments.length == 0) {
-			return null;
-		}
-
-		for (IASTComment comment : comments) {
-			if (isInWorkspace(comment)) {
-				commentsInWorkspace.add(comment);
-			}
-		}
-		return commentsInWorkspace;
-	}
-
-	private static List<IASTComment> removeAllPreprocessorComments(IASTTranslationUnit tu,
-			List<IASTComment> comments) {
-		IASTPreprocessorStatement[] preprocessorStatements = tu.getAllPreprocessorStatements();
-		TreeMap<Integer, String> treeOfPreProcessorLines = new TreeMap<Integer,String>();
-		TreeMap<String, ArrayList<Integer>> ppOffsetForFiles = new TreeMap<String, ArrayList<Integer>>();
-
-		for (IASTPreprocessorStatement statement : preprocessorStatements) {
-			if (isInWorkspace(statement)) {
-				String fileName = statement.getFileLocation().getFileName();
-				treeOfPreProcessorLines.put(statement.getFileLocation().getStartingLineNumber(), fileName);
-				ArrayList<Integer> offsetList = ppOffsetForFiles.get(fileName);
-				if (offsetList == null) {
-					offsetList = new ArrayList<Integer>();
-					ppOffsetForFiles.put(fileName, offsetList);
-				}
-				offsetList.add(((ASTNode)statement).getOffset());
-			}
-		}
-
-		ArrayList<IASTComment> commentsInCode = new ArrayList<IASTComment>();
-		for (IASTComment comment : comments) {
-			IASTFileLocation commentFileLocation = comment.getFileLocation();
-			int comStartLineNumber = commentFileLocation.getStartingLineNumber();
-			String fileName = commentFileLocation.getFileName();
-			if (treeOfPreProcessorLines.containsKey(comStartLineNumber)
-					&& treeOfPreProcessorLines.get(comStartLineNumber).equals(fileName)) {
-				continue;
-			}
-			if (commentIsAtTheBeginningBeforePreprocessorStatements(comment,
-					ppOffsetForFiles.get(fileName), tu)) {
-				continue;
-			}
-			commentsInCode.add(comment);
-		}
-		return commentsInCode;
-	}
-
-	private static boolean commentIsAtTheBeginningBeforePreprocessorStatements(IASTComment comment, 
-			ArrayList<Integer> listOfPreProcessorOffset, IASTTranslationUnit tu) {
-		if (listOfPreProcessorOffset == null) {
-			return false;
-		}
-		
-		if (comment.getTranslationUnit() == null || comment.getTranslationUnit().getDeclarations().length < 1) {
+	private static boolean isCommentDirectlyBeforePreprocessorStatement(IASTComment comment,
+			IASTPreprocessorStatement statement, IASTTranslationUnit tu) {
+		if (tu == null || tu.getDeclarations().length == 0) {
 			return true;
 		}
-		IASTDeclaration decl = comment.getTranslationUnit().getDeclarations()[0];
-		String commentFileName = comment.getFileLocation().getFileName();
-		boolean sameFile = decl.getFileLocation().getFileName().equals(commentFileName);
-		int commentNodeOffset = ((ASTNode)comment).getOffset();
-		if (sameFile) {
-			if (decl.getFileLocation().getNodeOffset() < commentNodeOffset) {
-				return false;
-			}
+		IASTFileLocation commentLocation = comment.getFileLocation();
+		int preprcessorOffset = statement.getFileLocation().getNodeOffset();
+		if (preprcessorOffset > commentLocation.getNodeOffset()) {
+			PreprocessorRangeChecker vister = new PreprocessorRangeChecker(preprcessorOffset, commentLocation);
+			tu.accept(vister);
+			return vister.isPreStatementComment;
 		}
-		Collections.sort(listOfPreProcessorOffset);
-		int nextPPOfset = -1;
-		for (Integer integer : listOfPreProcessorOffset) {
-			if (integer > commentNodeOffset) {
-				nextPPOfset = integer;
-				PPRangeChecker visti = new PPRangeChecker(true, nextPPOfset, commentNodeOffset);
-				tu.accept(visti);
-				if (visti.isPrePPComment) {
-					return true;
-				}
-			}
-		}
-			
 		return false;
 	}
 
-	private static boolean isInWorkspace(IASTNode node) {
-		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
-		IPath nodePath = new Path(node.getContainingFilename());
-		for (IProject project : projects) {
-			if (project.getLocation().isPrefixOf(nodePath)) return true;
-		}
-		return false;
+	public static boolean isInWorkspace(IASTNode node) {
+		return node.isPartOfTranslationUnitFile();
 	}
 	
-	private static NodeCommentMap addCommentsToCommentMap(IASTTranslationUnit rootNode,
-			List<IASTComment> comments){
+	private static NodeCommentMap addCommentsToCommentMap(IASTTranslationUnit tu,
+			ArrayList<IASTComment> comments){
 		NodeCommentMap commentMap = new NodeCommentMap();
 		CommentHandler commHandler = new CommentHandler(comments);
 
-		IASTDeclaration[] declarations = rootNode.getDeclarations();
-		for (int i = 0; i < declarations.length; i++) {
-			if (isInWorkspace(declarations[i])) {
-				ASTCommenterVisitor commenter = new ASTCommenterVisitor(commHandler, commentMap);
-				declarations[i].accept(commenter);
-				
-				// Add the remaining comments to the last declaration to prevent comment loss.
-				if (i == declarations.length - 1) {
-					commenter.addRemainingComments(declarations[i]);
-				}
+		assignPreprocessorComments(commentMap, comments, tu);
+		ASTCommenterVisitor commenter = new ASTCommenterVisitor(commHandler, commentMap);
+		tu.accept(commenter);
+		return commentMap;
+	}
+	
+	/**
+	 * Note that passing an ArrayList (instead of just List or Collection) is required here, since this
+	 * guarantees that the call to the remove-method on the list's iterator will not result in an
+	 * UnsupportedOperationException which might be the case for other Collection/List types.
+	 */
+	private static void assignPreprocessorComments(NodeCommentMap commentMap,
+			ArrayList<IASTComment> comments, IASTTranslationUnit tu) {
+		IASTPreprocessorStatement[] preprocessorStatementsArray = tu.getAllPreprocessorStatements();
+		if (preprocessorStatementsArray == null) {
+			return;
+		}
+		List<IASTPreprocessorStatement> preprocessorStatements = Arrays.asList(preprocessorStatementsArray);
+
+		if (preprocessorStatements.isEmpty() || comments.isEmpty()) {
+			return;
+		}
+
+		Iterator<IASTPreprocessorStatement> statementsIter = preprocessorStatements.iterator();
+		Iterator<IASTComment> commentIter = comments.iterator();
+		IASTPreprocessorStatement curStatement = getNextNodeInTu(statementsIter);
+		IASTComment curComment = getNextNodeInTu(commentIter);
+		while (curStatement != null && curComment != null) {
+			int statementLineNr = curStatement.getFileLocation().getStartingLineNumber();
+			int commentLineNr = curComment.getFileLocation().getStartingLineNumber();
+			if (commentLineNr == statementLineNr) {
+				commentMap.addTrailingCommentToNode(curStatement, curComment);
+				commentIter.remove();
+				curComment = getNextNodeInTu(commentIter);
+			} else if (commentLineNr > statementLineNr) {
+				curStatement = getNextNodeInTu(statementsIter);
+			} else if (isCommentDirectlyBeforePreprocessorStatement(curComment, curStatement, tu)) {
+				commentMap.addLeadingCommentToNode(curStatement, curComment);
+				commentIter.remove();
+				curComment = getNextNodeInTu(commentIter);
+			} else {
+				curComment = getNextNodeInTu(commentIter);
 			}
 		}
-		return commentMap;
-	}	
+	}
+
+	private static <T extends IASTNode> T getNextNodeInTu(Iterator<T> iter) {
+		if (!iter.hasNext()) {
+			return null;
+		}
+		T next = iter.next();
+		return next.isPartOfTranslationUnitFile() ? next : getNextNodeInTu(iter);
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenterVisitor.java
index 9fbd6bbf19f..a8a97e9dbb8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenterVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/ASTCommenterVisitor.java
@@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
 import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
 import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
 import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IASTInitializer;
 import org.eclipse.cdt.core.dom.ast.IASTName;
@@ -25,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
 import org.eclipse.cdt.core.dom.ast.IASTStatement;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.dom.ast.IASTTypeId;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
 import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@@ -43,6 +43,7 @@ public class ASTCommenterVisitor extends ASTVisitor {
 	protected NodeCommentMap commentMap;
 		
 	private NodeCommenter nodeCommenter;
+	private IASTDeclaration lastDecl;
 	
 	{
 		shouldVisitBaseSpecifiers = true;
@@ -57,6 +58,7 @@ public class ASTCommenterVisitor extends ASTVisitor {
 		shouldVisitStatements = true;
 		shouldVisitTemplateParameters = true;
 		shouldVisitTypeIds = true;
+		shouldVisitTranslationUnit = true;
 	}
 	
 	public ASTCommenterVisitor(CommentHandler commHandler, NodeCommentMap commentMap) {
@@ -69,10 +71,6 @@ public class ASTCommenterVisitor extends ASTVisitor {
 		nodeCommenter = new NodeCommenter(this, commHandler, commentMap);
 	}
 	
-	public void addRemainingComments(IASTDeclaration declaration) {
-		nodeCommenter.appendRemainingComments(declaration);
-	}
-	
 	@Override
 	public int visit(IASTName name) {
 		return nodeCommenter.appendComments((ASTNode) name);
@@ -100,7 +98,10 @@ public class ASTCommenterVisitor extends ASTVisitor {
 
 	@Override
 	public int visit(IASTDeclaration declaration) {
-		return nodeCommenter.appendComments((ASTNode) declaration);
+		if (ASTCommenter.isInWorkspace(declaration)) {
+			return nodeCommenter.appendComments((ASTNode) declaration);
+		}
+		return PROCESS_SKIP;
 	}
 
 	@Override
@@ -131,9 +132,13 @@ public class ASTCommenterVisitor extends ASTVisitor {
 	@Override
 	public int leave(IASTTranslationUnit tu) {
 		nodeCommenter.appendComments((ASTNode) tu);
+		if (lastDecl != null) {
+			nodeCommenter.appendRemainingComments(lastDecl);
+		}
 		return PROCESS_CONTINUE;
 	}
 
+
 	@Override
 	public int leave(IASTName name) {
 		nodeCommenter.appendComments((ASTNode) name);
@@ -142,6 +147,7 @@ public class ASTCommenterVisitor extends ASTVisitor {
 
 	@Override
 	public int leave(IASTDeclaration declaration) {
+		lastDecl = declaration;
 		nodeCommenter.appendComments((ASTNode) declaration);
 		return PROCESS_CONTINUE;
 	}
@@ -215,5 +221,5 @@ public class ASTCommenterVisitor extends ASTVisitor {
 	public int leave( IASTComment comment){
 		nodeCommenter.appendComments((ASTNode) comment);
 		return PROCESS_CONTINUE;
-	}	
+	}
 }