diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java
index 72458b7ce0f..bb6d1dbf0e7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java
@@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.index;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
@@ -26,6 +25,7 @@ import org.eclipse.cdt.core.dom.ICodeReaderFactory;
 import org.eclipse.cdt.core.index.IIndex;
 import org.eclipse.cdt.core.index.IIndexFile;
 import org.eclipse.cdt.core.index.IIndexInclude;
+import org.eclipse.cdt.core.index.IIndexMacro;
 import org.eclipse.cdt.core.model.ITranslationUnit;
 import org.eclipse.cdt.core.parser.CodeReader;
 import org.eclipse.cdt.core.parser.ICodeReaderCache;
@@ -33,6 +33,7 @@ import org.eclipse.cdt.core.parser.IMacro;
 import org.eclipse.cdt.core.parser.IScanner;
 import org.eclipse.cdt.core.parser.ParserUtil;
 import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Path;
 
@@ -46,7 +47,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 	private final IIndex index;
 	private Map fileInfoCache = new HashMap(); // filename, fileInfo
 	private List usedMacros = new ArrayList();
-	private Collection fPathCollector;
 	
 	private static final char[] EMPTY_CHARS = new char[0];
 	
@@ -55,6 +55,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 		private FileInfo() {}
 		public IIndexFile fFile= null;
 		public IMacro[] fMacros= null;
+//		public FileInfo[] fFileInfos= null;
 		private boolean fRequested= false;
 		
 		public boolean isRequested() {
@@ -75,9 +76,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 	}
 
 	public CodeReader createCodeReaderForTranslationUnit(String path) {
-		if (fPathCollector != null) {
-			fPathCollector.add(path);
-		}
 		return ParserUtil.createReader(path, null);
 	}
 	
@@ -108,7 +106,13 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 						FileInfo fi = (FileInfo) iter.next();
 						if (fi.fMacros == null) {
 							assert fi.fFile != null;
-							fi.fMacros= fi.fFile.getMacros();
+							IIndexMacro[] macros= fi.fFile.getMacros();
+							IMacro[] converted= new IMacro[macros.length];
+							for (int i = 0; i < macros.length; i++) {
+								IIndexMacro macro = macros[i];
+								converted[i]= ((PDOMMacro)macro).getMacro();
+							}
+							fi.fMacros= converted;
 						}
 						for (int i = 0; i < fi.fMacros.length; ++i) {
 							scanner.addDefinition(fi.fMacros[i]);
@@ -126,9 +130,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 			// still try to parse the file.
 		}
 
-		if (fPathCollector != null) {
-			fPathCollector.add(canonicalPath);
-		}
 		return ParserUtil.createReader(canonicalPath, null);
 	}
 
@@ -187,8 +188,4 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
 	public FileInfo createFileInfo(ITranslationUnit tu) throws CoreException {
 		return createInfo(tu.getLocation().toOSString(), null);
 	}
-
-	public void setPathCollector(Collection paths) {
-		fPathCollector= paths;
-	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
index db7afcf2603..d1da4ad501b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
@@ -14,13 +14,11 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
@@ -137,6 +135,53 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
 		}
 	}
 	
+	protected void parseTUs(Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
+		// sources first
+		Iterator iter;
+		for (iter = sources.iterator(); iter.hasNext();) {
+			if (monitor.isCanceled()) 
+				return;
+			ITranslationUnit tu = (ITranslationUnit) iter.next();
+			String path = tu.getLocation().toOSString();
+			if (needToUpdate(path)) {
+				parseTU(tu, monitor);
+			}
+		}
+
+		// headers with context
+		for (iter = headers.iterator(); iter.hasNext();) {
+			if (monitor.isCanceled()) 
+				return;
+			ITranslationUnit tu = (ITranslationUnit) iter.next();
+			String path = tu.getLocation().toOSString();
+			if (!needToUpdate(path)) {
+				iter.remove();
+			}
+			else {
+				ITranslationUnit context= findContext(getIndex(), path);
+				if (context != null) {
+					parseTU(context, monitor);
+				}
+			}
+		}
+
+		// headers without context
+		if (getIndexAllFiles()) {
+			for (iter = headers.iterator(); iter.hasNext();) {
+				if (monitor.isCanceled()) 
+					return;
+				ITranslationUnit tu = (ITranslationUnit) iter.next();
+				String path = tu.getLocation().toOSString();
+				if (!needToUpdate(path)) {
+					iter.remove();
+				}
+				else {
+					parseTU(tu, monitor);
+				}
+			}
+		}
+	}
+
 	protected void parseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
 		IPath path= tu.getPath();
 		try {
@@ -246,40 +291,101 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
 		return fCompletedSources;
 	}
 	
-	/**
-	 * Extracts a map of names from the ast and returns an array defining the order in
-	 * which the symbols should be added to the index.
-	 * @since 4.0
-	 */
-	protected String[] extractSymbols(IASTTranslationUnit ast, Set legalPaths, final LinkedHashMap symbolMap) {
-		// includes
+	
+	protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
+		final Map symbolMap= new HashMap();
+
+		String[] orderedPaths= extractSymbols(ast, symbolMap);
+		for (int i=0; i<orderedPaths.length; i++) {
+			if (pm.isCanceled()) {
+				return;
+			}
+			String path= orderedPaths[i];
+			ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
+						
+			// resolve the names
+			ArrayList names= arrayLists[2];
+			for (int j=0; j<names.size(); j++) {
+				((IASTName[]) names.get(j))[0].resolveBinding();
+			}
+		}
+
+		boolean isFirstRequest= true;
+		boolean isFirstAddition= true;
+		IWritableIndex index= getIndex();
+		index.acquireWriteLock(getReadlockCount());
+		try {
+			for (int i=0; i<orderedPaths.length; i++) {
+				if (pm.isCanceled()) 
+					return;
+				
+				String path = orderedPaths[i];
+				if (path != null) {
+					if (fTrace) {
+						System.out.println("Indexer: adding " + path); //$NON-NLS-1$
+					}
+					IIndexFile file= addToIndex(index, path, symbolMap);
+					if (postAddToIndex(path, file)) {
+						if (isFirstRequest) 
+							isFirstRequest= false;
+						else 
+							fTotalSourcesEstimate--;
+					}
+					if (isFirstAddition) 
+						isFirstAddition= false;
+					else
+						fCompletedHeaders++;
+				}
+			}
+		} finally {
+			index.releaseWriteLock(getReadlockCount());
+		}
+		fCompletedSources++;
+	}
+
+	private String[] extractSymbols(IASTTranslationUnit ast, final Map symbolMap) throws CoreException {
+		LinkedHashSet orderedIncludes= new LinkedHashSet();
+		ArrayList stack= new ArrayList();
+
 		final String astFilePath = ast.getFilePath();
+		String currentPath= astFilePath;
+
 		IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
-		for (int i = includes.length-1; i >= 0; --i) {
+		for (int i= 0; i < includes.length; i++) {
 			IASTPreprocessorIncludeStatement include = includes[i];
 			IASTFileLocation sourceLoc = include.getFileLocation();
-			String path= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
-			if (legalPaths.contains(path)) {
-				prepareInMap(symbolMap, path);
-				addToMap(symbolMap, 0, path, include);
+			String newPath= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
+			while (!stack.isEmpty() && !currentPath.equals(newPath)) {
+				if (needToUpdate(currentPath)) {
+					prepareInMap(symbolMap, currentPath);
+					orderedIncludes.add(currentPath);
+				}
+				currentPath= (String) stack.remove(stack.size()-1);
 			}
-			path= include.getPath();
-			if (legalPaths.contains(path)) {
-				prepareInMap(symbolMap, path);
+			if (needToUpdate(newPath)) {
+				prepareInMap(symbolMap, newPath);
+				addToMap(symbolMap, 0, newPath, include);
+			}
+			stack.add(currentPath);
+			currentPath= include.getPath();
+		}
+		stack.add(currentPath);
+		while (!stack.isEmpty()) {
+			currentPath= (String) stack.remove(stack.size()-1);
+			if (needToUpdate(currentPath)) {
+				prepareInMap(symbolMap, currentPath);
+				orderedIncludes.add(currentPath);
 			}
 		}
-		if (legalPaths.contains(astFilePath)) {
-			prepareInMap(symbolMap, ast.getFilePath());
-		}
-	
+		
 		// macros
 		IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
-		for (int i = 0; i < macros.length; ++i) {
-			IASTPreprocessorMacroDefinition macro = macros[i];
+		for (int i2 = 0; i2 < macros.length; ++i2) {
+			IASTPreprocessorMacroDefinition macro = macros[i2];
 			IASTFileLocation sourceLoc = macro.getFileLocation();
 			if (sourceLoc != null) { // skip built-ins and command line macros
-				String path = sourceLoc.getFileName();
-				addToMap(symbolMap, 1, path, macro);
+				String path2 = sourceLoc.getFileName();
+				addToMap(symbolMap, 1, path2, macro);
 			}
 		}
 			
@@ -292,17 +398,16 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
 				}
 			}
 		});
-		
-		Collection temp= symbolMap.keySet();
-		int size= temp.size();
-		String[] result= new String[temp.size()];
-		for (Iterator iter = temp.iterator(); iter.hasNext();) {
-			result[--size]= (String) iter.next();
-		}
-		return result;
+		return (String[]) orderedIncludes.toArray(new String[orderedIncludes.size()]);
 	}
 
-	private void addToMap(HashMap map, int idx, String path, Object thing) {
+	protected abstract IWritableIndex getIndex();
+	protected abstract int getReadlockCount();
+	protected abstract boolean needToUpdate(String path) throws CoreException;
+	protected abstract boolean postAddToIndex(String path, IIndexFile file) throws CoreException;
+
+
+	private void addToMap(Map map, int idx, String path, Object thing) {
 		List[] lists= (List[]) map.get(path);
 		if (lists != null) 
 			lists[idx].add(thing);
@@ -316,20 +421,7 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
 		return false;
 	}
 
-	protected void prepareIndexInsertion(String path, Map symbolMap) {
-		ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
-
-		// reverse the includes
-		Collections.reverse(arrayLists[0]);
-		
-		// resolve the names
-		ArrayList names= arrayLists[2];
-		for (int j=0; j<names.size(); j++) {
-			((IASTName[]) names.get(j))[0].resolveBinding();
-		}
-	}
-
-	protected IIndexFragmentFile addToIndex(IWritableIndex index, String location, Map symbolMap) throws CoreException {
+	private IIndexFragmentFile addToIndex(IWritableIndex index, String location, Map symbolMap) throws CoreException {
 		// Remove the old symbols in the tu
 		Path path= new Path(location);
 		IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(path);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java
index eeb55938211..e70a88d8caf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java
@@ -13,15 +13,13 @@
 package org.eclipse.cdt.internal.core.pdom.indexer.fast;
 
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
 
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndexFile;
 import org.eclipse.cdt.core.model.ILanguage;
 import org.eclipse.cdt.core.model.ITranslationUnit;
 import org.eclipse.cdt.core.parser.CodeReader;
@@ -85,9 +83,6 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
 			return;
 		}
 
-		HashSet paths= new HashSet();
-		paths.add(path.toOSString());
-		codeReaderFactory.setPathCollector(paths);
 		index.acquireReadLock();
 		try {
 			// get the AST in a "Fast" way
@@ -99,118 +94,34 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
 			codeReaderFactory.clearMacroAttachements();
 				
 			// Add the new symbols
-			addSymbols(paths, ast, pm);
+			addSymbols(ast, pm);
 		}
 		finally {
 			index.releaseReadLock();
-			codeReaderFactory.setPathCollector(null);
 		}
 	}
 
-	protected void addSymbols(HashSet paths, IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
-		// Add in the includes
-		final LinkedHashMap symbolMap= new LinkedHashMap();
-		String[] orderedPaths= extractSymbols(ast, paths, symbolMap);
-		
-		for (int i=0; i<orderedPaths.length; i++) {
-			if (pm.isCanceled()) {
-				return;
-			}
-			String path= orderedPaths[i];
-			FileInfo info= codeReaderFactory.createFileInfo(path);
-		
-			// file is requested or is not yet indexed.
-			if (info.isRequested() || info.fFile == null) {
-				prepareIndexInsertion(path, symbolMap);
-			}
-			else {
-				if (fTrace) {
-					System.out.println("Indexer: skipping " + path); //$NON-NLS-1$
-				}
-				orderedPaths[i]= null;
-			}
-		}
-
-		boolean isFirstRequest= true;
-		boolean isFirstAddition= true;
-		index.acquireWriteLock(1);
-		try {
-			for (int i=0; i<orderedPaths.length; i++) {
-				if (pm.isCanceled()) 
-					return;
-				
-				String path = orderedPaths[i];
-				if (path != null) {
-					FileInfo info= codeReaderFactory.createFileInfo(path);
-					if (info.isRequested()) {
-						info.setRequested(false);
-
-						if (isFirstRequest) 
-							isFirstRequest= false;
-						else 
-							fTotalSourcesEstimate--;
-					}
-					if (fTrace) {
-						System.out.println("Indexer: adding " + path); //$NON-NLS-1$
-					}
-					info.fFile= addToIndex(index, path, symbolMap);
-
-					if (isFirstAddition) 
-						isFirstAddition= false;
-					else
-						fCompletedHeaders++;
-				}
-			}
-		} finally {
-			index.releaseWriteLock(1);
-		}
-		fCompletedSources++;
+	protected IWritableIndex getIndex() {
+		return index;
 	}
 
+	protected int getReadlockCount() {
+		return 1;
+	}
 
-	protected void parseTUs(List sources, List headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
-		// sources first
-		Iterator iter;
-		for (iter= sources.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			parseTU(tu, monitor);
-		}
+	protected boolean needToUpdate(String path) throws CoreException {
+		// file is requested or is not yet indexed.
+		FileInfo info= codeReaderFactory.createFileInfo(path);
+		return info.isRequested() || info.fFile == null;
+	}
 
-		// headers with context
-		for (iter= headers.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			FileInfo info= codeReaderFactory.createFileInfo(tu);
-			// check if header was handled while parsing a source
-			if (!info.isRequested()) {
-				iter.remove();
-			}
-			else if (info.fFile != null) {
-				ITranslationUnit context= findContext(index, info.fFile.getLocation());
-				if (context != null) {
-					parseTU(context, monitor);
-				}
-			}
-		}
-
-		// headers without context
-		if (getIndexAllFiles()) {
-			for (iter= headers.iterator(); iter.hasNext();) {
-				if (monitor.isCanceled()) 
-					return;
-				ITranslationUnit tu = (ITranslationUnit) iter.next();
-				FileInfo info= codeReaderFactory.createFileInfo(tu);
-				// check if header was handled while parsing a source
-				if (!info.isRequested()) {
-					iter.remove();
-				}
-				else {
-					parseTU(tu, monitor);
-				}
-			}
+	protected boolean postAddToIndex(String path, IIndexFile file) throws CoreException {
+		FileInfo info= codeReaderFactory.createFileInfo(path);
+		info.fFile= file;
+		if (info.isRequested()) {
+			info.setRequested(false);
+			return true;
 		}
+		return false;
 	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java
index 6f12530895a..de5ef4646f9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullHandleDelta.java
@@ -54,7 +54,8 @@ class PDOMFullHandleDelta extends PDOMFullIndexerJob {
 				}
 			}
 
-			registerTUsInReaderFactory(sources, headers, true);
+			registerTUsInReaderFactory(sources);
+			registerTUsInReaderFactory(headers);
 					
 			Iterator i= removed.iterator();
 			while (i.hasNext()) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java
index a7f019cd716..c7cba2a5f46 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerJob.java
@@ -15,13 +15,13 @@ package org.eclipse.cdt.internal.core.pdom.indexer.full;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndexFile;
 import org.eclipse.cdt.core.model.ITranslationUnit;
 import org.eclipse.cdt.internal.core.index.IWritableIndex;
 import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
@@ -35,10 +35,13 @@ import org.eclipse.core.runtime.IProgressMonitor;
  *
  */
 abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexerTask {
-
+	final static Object REQUIRED= new Object();
+	final static Object MISSING = new Object();
+	final static Object SKIP=     new Object();
+	
 	protected final PDOMFullIndexer indexer;
 	protected IWritableIndex index= null;
-	private Map filePathsToParse= null;
+	private Map filePathsToParse= new HashMap();
 
 	public PDOMFullIndexerJob(PDOMFullIndexer indexer) throws CoreException {
 		this.indexer = indexer;
@@ -52,68 +55,15 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
 		this.index = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(indexer.getProject());
 	}
 	
-	protected void registerTUsInReaderFactory(Collection sources, Collection headers, 
-			boolean requireHeaders) throws CoreException {
+	protected void registerTUsInReaderFactory(Collection sources) throws CoreException {
 		filePathsToParse= new HashMap();
 		
 		for (Iterator iter = sources.iterator(); iter.hasNext();) {
 			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			filePathsToParse.put(tu.getLocation().toOSString(), Boolean.TRUE);
-		}
-		Boolean required= Boolean.valueOf(requireHeaders);
-		for (Iterator iter = headers.iterator(); iter.hasNext();) {
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			filePathsToParse.put(tu.getLocation().toOSString(), required);
+			filePathsToParse.put(tu.getLocation().toOSString(), REQUIRED);
 		}
 	}
 	
-	protected void parseTUs(Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
-		// sources first
-		Iterator iter;
-		for (iter = sources.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			String path = tu.getLocation().toOSString();
-			if (filePathsToParse.get(path) != null) {
-				parseTU(tu, monitor);
-			}
-		}
-
-		// headers with context
-		for (iter = headers.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			String path = tu.getLocation().toOSString();
-			if (filePathsToParse.get(path)==null) {
-				iter.remove();
-			}
-			else {
-				ITranslationUnit context= findContext(index, path);
-				if (context != null) {
-					parseTU(context, monitor);
-				}
-			}
-		}
-
-		// headers without context
-		if (getIndexAllFiles()) {
-			for (iter = headers.iterator(); iter.hasNext();) {
-				if (monitor.isCanceled()) 
-					return;
-				ITranslationUnit tu = (ITranslationUnit) iter.next();
-				String path = tu.getLocation().toOSString();
-				if (filePathsToParse.get(path)==null) {
-					iter.remove();
-				}
-				else {
-					parseTU(tu, monitor);
-				}
-			}
-		}
-	}
-
 	protected void doParseTU(ITranslationUnit tu, IProgressMonitor pm) throws CoreException, InterruptedException {
 		IPath path = tu.getLocation();
 		if (path == null) {
@@ -128,51 +78,27 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
 			addSymbols(ast, pm);
 	}
 	
-	protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
-		// Add in the includes
-		final LinkedHashMap symbolMap= new LinkedHashMap(); 
-		String[] orderedPaths= extractSymbols(ast, filePathsToParse.keySet(), symbolMap);
-		
-		for (int i=0; i<orderedPaths.length; i++) {
-			if (pm.isCanceled()) {
-				return;
-			}
-			String path= orderedPaths[i];
-			prepareIndexInsertion(path, symbolMap);
-		}
+	
+	protected IWritableIndex getIndex() {
+		return index;
+	}
 
-		boolean isFirstRequest= true;
-		boolean isFirstAddition= true;
-		index.acquireWriteLock(0);
-		try {
-			for (int i=0; i<orderedPaths.length; i++) {
-				if (pm.isCanceled()) 
-					return;
-				
-				String path = orderedPaths[i];
-				Boolean required= (Boolean) filePathsToParse.remove(path);
-				if (required != null) {
-					if (required.booleanValue()) {
-						if (isFirstRequest) 
-							isFirstRequest= false;
-						else 
-							fTotalSourcesEstimate--;
-					}
+	protected int getReadlockCount() {
+		return 0;
+	}
 
-					if (fTrace) 
-						System.out.println("Indexer: adding " + path); //$NON-NLS-1$
-					
-					addToIndex(index, path, symbolMap);
-					
-					if (isFirstAddition) 
-						isFirstAddition= false;
-					else
-						fCompletedHeaders++;
-				}
-			}
-		} finally {
-			index.releaseWriteLock(0);
+	protected boolean needToUpdate(String path) throws CoreException {
+		Object required= filePathsToParse.get(path);
+		if (required == null) {
+			required= MISSING;
+			filePathsToParse.put(path, required);
 		}
-		fCompletedSources++;
+		return required != SKIP;
+	}
+
+	protected boolean postAddToIndex(String path, IIndexFile file) throws CoreException {
+		Object required= filePathsToParse.get(path);
+		filePathsToParse.put(path, SKIP);
+		return required == REQUIRED;
 	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java
index f5517127837..cc9e39a05ee 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java
@@ -34,15 +34,12 @@ class PDOMFullReindex extends PDOMFullIndexerJob {
 	public void run(final IProgressMonitor monitor) {
 		try {
 			long start = System.currentTimeMillis();	
-			boolean allfiles= getIndexAllFiles();
-			List headers= new ArrayList();
+			boolean allFiles= getIndexAllFiles();
 			List sources= new ArrayList();
+			List headers= new ArrayList();
 			
-			collectSources(indexer.getProject(), sources, headers, allfiles);
-			
-			fTotalSourcesEstimate= sources.size();
-			if (allfiles) 
-				fTotalSourcesEstimate+= headers.size();
+			collectSources(indexer.getProject(), sources, allFiles ? headers : null, allFiles);
+			fTotalSourcesEstimate= sources.size() + headers.size();
 
 			setupIndexAndReaderFactory();
 			clearIndex(index);
@@ -51,10 +48,7 @@ class PDOMFullReindex extends PDOMFullIndexerJob {
 				return;
 			}
 
-			registerTUsInReaderFactory(sources, headers, allfiles);
-			if (!allfiles) 
-				headers.clear();
-			
+			registerTUsInReaderFactory(sources);
 			parseTUs(sources, headers, monitor);
 
 			String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID