diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
index 140ff612398..5c45d4fc008 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
@@ -6,6 +6,7 @@ import junit.framework.TestCase;
 
 import org.eclipse.cdt.core.testplugin.CTestPlugin;
 import org.eclipse.cdt.internal.core.pdom.db.BTree;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@@ -148,7 +149,7 @@ public class DBTest extends TestCase {
 			int record = new FindVisitor(db, name).findIn(btree);
 			assertTrue(record != 0);
 			assertEquals(i, db.getInt(record));
-			String rname = db.getString(record + Database.INT_SIZE);
+			DBString rname = db.getString(record + Database.INT_SIZE);
 			assertEquals(name, rname);
 		}
 	}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 588f518348e..32409f7c97f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -11,9 +11,12 @@
 package org.eclipse.cdt.internal.core.pdom;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.dom.ICodeReaderFactory;
@@ -70,7 +73,9 @@ public class PDOM extends PlatformObject
 	public static final int LINKAGES = Database.DATA_AREA;
 	public static final int FILE_INDEX = Database.DATA_AREA + 4;
 	
+	// Local caches
 	private BTree fileIndex;
+	private Map linkageCache = new HashMap();
 
 	private static final QualifiedName dbNameProperty
 		= new QualifiedName(CCorePlugin.PLUGIN_ID, "dbName"); //$NON-NLS-1$
@@ -95,6 +100,13 @@ public class PDOM extends PlatformObject
 		// TODO Conversion might be a nicer story down the road
 		if (db.getVersion() != VERSION) {
 			indexer.reindex();
+		} else {
+			// populate the linkage cache
+			PDOMLinkage linkage = getFirstLinkage();
+			while (linkage != null) {
+				linkageCache.put(linkage.getLanguage().getId(), linkage);
+				linkage = linkage.getNextLinkage();
+			}
 		}
 	}
 
@@ -243,6 +255,7 @@ public class PDOM extends PlatformObject
 		db.clear();
 		db.setVersion(VERSION);
 		fileIndex = null;
+		linkageCache.clear();
 	}
 
 	public boolean isEmpty() throws CoreException {
@@ -310,11 +323,16 @@ public class PDOM extends PlatformObject
 	}
 	
 	public PDOMLinkage getLinkage(ILanguage language) throws CoreException {
+		PDOMLinkage linkage = (PDOMLinkage)linkageCache.get(language.getId());
+		if (linkage != null)
+			return linkage;
+		
+		// Need to create it
 		IPDOMLinkageFactory factory = (IPDOMLinkageFactory)language.getAdapter(IPDOMLinkageFactory.class);
 		String id = language.getId();
 		int linkrec = db.getInt(LINKAGES);
 		while (linkrec != 0) {
-			if (id.equals(PDOMLinkage.getId(this, linkrec)))
+			if (PDOMLinkage.getId(this, linkrec).equals(id))
 				return factory.getLinkage(this, linkrec);
 			else
 				linkrec = PDOMLinkage.getNextLinkageRecord(this, linkrec);
@@ -327,7 +345,16 @@ public class PDOM extends PlatformObject
 		if (record == 0)
 			return null;
 		
-		String id = PDOMLinkage.getId(this, record);
+		// First check the cache. We do a linear search since there will be very few linkages
+		// in a given database.
+		Iterator i = linkageCache.values().iterator();
+		while (i.hasNext()) {
+			PDOMLinkage linkage = (PDOMLinkage)i.next();
+			if (linkage.getRecord() == record)
+				return linkage;
+		}
+		
+		String id = PDOMLinkage.getId(this, record).getString();
 		ILanguage language = LanguageManager.getInstance().getLanguage(id);
 		return getLinkage(language);
 	}
@@ -336,9 +363,14 @@ public class PDOM extends PlatformObject
 		return getLinkage(db.getInt(LINKAGES));
 	}
 	
+	public PDOMLinkage[] getLinkages() {
+		Collection values = linkageCache.values();
+		return (PDOMLinkage[])values.toArray(new PDOMLinkage[values.size()]);
+	}
 	public void insertLinkage(PDOMLinkage linkage) throws CoreException {
 		linkage.setNext(db.getInt(LINKAGES));
 		db.putInt(LINKAGES, linkage.getRecord());
+		linkageCache.put(linkage.getLanguage().getId(), linkage);
 	}
 	
 	public PDOMBinding getBinding(int record) throws CoreException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java
index 8f7fc709df8..8c0773e0f83 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java
@@ -11,6 +11,7 @@
 
 package org.eclipse.cdt.internal.core.pdom;
 
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.core.runtime.CoreException;
 
@@ -49,7 +50,7 @@ public class PDOMLanguage {
 		return pdom.getDB().getChar(record + ID);
 	}
 	
-	public String getName() throws CoreException {
+	public DBString getName() throws CoreException {
 		return pdom.getDB().getString(record + NAME);
 	}
 	
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
index bbdae6379a5..c8ed2d8d3e5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
@@ -60,7 +60,7 @@ public class PDOMManager implements IPDOMManager, IElementChangedListener {
 		}
 	};
 	
-	public IPDOM getPDOM(ICProject project) {
+	public synchronized IPDOM getPDOM(ICProject project) {
 		try {
 			IProject rproject = project.getProject();
 			IPDOM pdom = (IPDOM)rproject.getSessionProperty(pdomProperty);
@@ -150,19 +150,21 @@ public class PDOMManager implements IPDOMManager, IElementChangedListener {
     	if (indexerId == null) {
     		// See if it is in the ICDescriptor
     		try {
-    			ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project.getProject(), true);
-    			ICExtensionReference[] ref = desc.get(CCorePlugin.INDEXER_UNIQ_ID);
-    			if (ref != null && ref.length > 0) {
-    				indexerId = ref[0].getID();
-    			}
-    			if (indexerId != null) {
-    				// Make sure it is a valid indexer
-    		    	IExtension indexerExt = Platform.getExtensionRegistry()
-    	    			.getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
-    		    	if (indexerExt == null) {
-    		    		// It is not, forget about it.
-    		    		indexerId = null;
-    		    	}
+    			ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project.getProject(), false);
+    			if (desc != null) {
+	    			ICExtensionReference[] ref = desc.get(CCorePlugin.INDEXER_UNIQ_ID);
+	    			if (ref != null && ref.length > 0) {
+	    				indexerId = ref[0].getID();
+	    			}
+	    			if (indexerId != null) {
+	    				// Make sure it is a valid indexer
+	    		    	IExtension indexerExt = Platform.getExtensionRegistry()
+	    	    			.getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
+	    		    	if (indexerExt == null) {
+	    		    		// It is not, forget about it.
+	    		    		indexerId = null;
+	    		    	}
+	    			}
     			}
     		} catch (CoreException e) {
     		}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
index ebbb00e094a..44e6e7e6133 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
@@ -90,10 +90,6 @@ public class Chunk {
 			buffer.putChar(value.charAt(i));
 	}
 	
-	public String getString(int offset) {
-		return new String(getChars(offset));
-	}
-
 	Chunk getNextChunk() {
 		return nextChunk;
 	}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/DBString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/DBString.java
new file mode 100644
index 00000000000..2082b160fe4
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/DBString.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 QNX Software Systems and others.
+ * 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://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core.pdom.db;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A String class for strings stored in the database. The idea
+ * is to minimize how often we extract the string.
+ * 
+ * @author Doug Schaefer
+ */
+public class DBString {
+
+	private final Database db;
+	private final int offset;
+	
+	DBString(Database db, int offset) {
+		this.db = db;
+		this.offset = offset;
+	}
+	
+	public boolean equals(Object obj) {
+		if (obj == this)
+			return true;
+		
+		try {
+			if (obj instanceof DBString) {
+				DBString string = (DBString)obj;
+				if (db == string.db && offset == string.offset)
+					return true;
+				
+				Chunk chunk1 = db.getChunk(offset);
+				Chunk chunk2 = string.db.getChunk(string.offset);
+				
+				int n1 = chunk1.getChar(offset);
+				int n2 = chunk2.getChar(string.offset);
+				if (n1 != n2)
+					return false;
+				
+				for (int i = 0; i < n1; ++i) {
+					int coffset1 = offset + 2 + i * 2;
+					int coffset2 = string.offset + 2 + i * 2;
+					if (chunk1.getChar(coffset1) != chunk2.getChar(coffset2))
+						return false;
+				}
+				return true;
+			} else if (obj instanceof String) {
+				String string = (String)obj;
+				Chunk chunk = db.getChunk(offset);
+
+				// Make sure size is the same
+				int n = chunk.getChar(offset);
+				if (n != string.length())
+					return false;
+				
+				// Check each character
+				for (int i = 0; i < n; ++i) {
+					int coffset = offset + 2 + i * 2;
+					if (chunk.getChar(coffset) != string.charAt(i))
+						return false;
+				}
+				
+				return true;
+			}
+		} catch (CoreException e) {
+			CCorePlugin.log(e);
+		}
+		return false;
+	}
+	
+	public int hashCode() {
+		// Custom hash code function to allow DBStrings in hashmaps.
+		return offset;
+	}
+	
+	public String getString() throws CoreException {
+		return new String(db.getChars(offset));
+	}
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
index 08df72278ea..5103a5a5fd0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
@@ -297,9 +297,8 @@ public class Database {
 		return record;
 	}
 	
-	public String getString(int offset) throws CoreException {
-		Chunk chunk = getChunk(offset);
-		return chunk.getString(offset);
+	public DBString getString(int offset) throws CoreException {
+		return new DBString(this, offset);
 	}
 	
 	public int getNumChunks() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
index d3b1096f2cb..75388a83582 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
@@ -144,7 +144,7 @@ public abstract class PDOMBinding extends PDOMNode implements IBinding {
 	
 	public String getName() {
 		try {
-			return super.getName();
+			return super.getDBName().getString();
 		} catch (CoreException e) {
 			CCorePlugin.log(e);
 		}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
index dcaf3c8f0b6..00a7a1dda26 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
@@ -16,6 +16,7 @@ import java.util.LinkedList;
 import java.util.Map;
 
 import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@@ -94,7 +95,7 @@ public class PDOMFile {
 		return record;
 	}
 	
-	public String getFileName() throws CoreException {
+	public DBString getFileName() throws CoreException {
 		return pdom.getDB().getString(record + FILE_NAME);
 	}
 	
@@ -178,7 +179,7 @@ public class PDOMFile {
 		LinkedList todo = new LinkedList();
 		
 		// Add me in to make sure we don't get caught in a circular include
-		String myFileName = getFileName();
+		DBString myFileName = getFileName();
 		files.put(myFileName, this);
 		
 		todo.addLast(this);
@@ -187,7 +188,7 @@ public class PDOMFile {
 			PDOMInclude includedBy = getFirstIncludedBy();
 			while (includedBy != null) {
 				PDOMFile incFile = includedBy.getIncludedBy();
-				String incFileName = incFile.getFileName();
+				DBString incFileName = incFile.getFileName();
 				if (files.get(incFileName) == null) {
 					files.put(incFileName, incFile);
 					todo.addLast(incFile);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
index a35b8ff11a1..9f4f63c151a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
@@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.core.model.ILanguage;
 import org.eclipse.cdt.internal.core.pdom.PDOM;
 import org.eclipse.cdt.internal.core.pdom.db.BTree;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
 import org.eclipse.core.runtime.CoreException;
@@ -87,7 +88,7 @@ public abstract class PDOMLinkage extends PDOMNode {
 		return RECORD_SIZE;
 	}
 
-	public static String getId(PDOM pdom, int record) throws CoreException {
+	public static DBString getId(PDOM pdom, int record) throws CoreException {
 		Database db = pdom.getDB();
 		int namerec = db.getInt(record + ID_OFFSET);
 		return db.getString(namerec);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
index 044e13306f0..d18811ecd63 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
@@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.core.runtime.CoreException;
 
@@ -287,7 +288,7 @@ public class PDOMName implements IASTName, IASTFileLocation {
 	public String getFileName() {
 		try {
 			PDOMFile file = getFile();
-			return file != null ? file.getFileName() : null;
+			return file != null ? file.getFileName().getString() : null;
 		} catch (CoreException e) {
 			CCorePlugin.log(e);
 			return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java
index 8a7ec1883b8..a11a719158e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java
@@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.pdom.dom;
 import org.eclipse.cdt.core.dom.IPDOMNode;
 import org.eclipse.cdt.core.dom.IPDOMVisitor;
 import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@@ -89,7 +90,7 @@ public abstract class PDOMNode implements IPDOMNode{
 		return pdom.getLinkage(linkagerec);
 	}
 	
-	public String getName() throws CoreException {
+	public DBString getDBName() throws CoreException {
 		Database db = pdom.getDB();
 		int namerec = db.getInt(record + NAME_OFFSET);
 		return db.getString(namerec);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
index ada649993b5..4196a8b430b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
@@ -13,10 +13,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.c;
 
 import org.eclipse.cdt.core.dom.ast.DOMException;
 import org.eclipse.cdt.core.dom.ast.IASTName;
-import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.IVariable;
-import org.eclipse.cdt.internal.core.dom.parser.c.CVariable;
 import org.eclipse.cdt.internal.core.pdom.PDOM;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
@@ -31,8 +29,10 @@ public class PDOMCVariable extends PDOMBinding implements IVariable {
 
 	public PDOMCVariable(PDOM pdom, PDOMNode parent, IASTName name) throws CoreException {
 		super(pdom, parent, name, PDOMCLinkage.CVARIABLE);
-		CVariable binding = (CVariable)name.getBinding();
-		IType type = binding.getType();
+		IVariable binding = (IVariable)name.getBinding();
+		if (binding != null) {
+			IType type = binding.getType();
+		}
 	}
 
 	public PDOMCVariable(PDOM pdom, int record) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsBindingFinder.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsBindingFinder.java
index d0837f848bb..3ea8af4a692 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsBindingFinder.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsBindingFinder.java
@@ -36,7 +36,7 @@ public class CtagsBindingFinder implements IPDOMVisitor {
 	
 	public boolean visit(IPDOMNode node) throws CoreException {
 		PDOMBinding binding = (PDOMBinding)node;
-		if (binding.getName().equals(name)) {
+		if (name.equals(binding.getDBName())) {
 			int type = binding.getBindingType();
 			for (int i = 0; i < types.length; ++i) {
 				if (type == types[i]) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCName.java
index 48bbb23c2f6..71a00332e0c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCName.java
@@ -13,6 +13,8 @@ package org.eclipse.cdt.internal.core.pdom.indexer.ctags;
 
 import java.util.Map;
 
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMNode;
 import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
 import org.eclipse.cdt.core.dom.ast.ASTVisitor;
 import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
@@ -21,12 +23,13 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
 import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.dom.ast.IBinding;
-import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
-import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
-import org.eclipse.cdt.core.model.ILanguage;
-import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
+import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCFunction;
+import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCLinkage;
+import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCVariable;
 import org.eclipse.core.runtime.CoreException;
 
 /**
@@ -40,6 +43,7 @@ public class CtagsCName implements IASTName, IASTFileLocation {
 	private final int lineNum;
 	private final String elementName;
 	private final Map fields;
+	private PDOMBinding binding;
 	private int kind; // Enum from below
 	
 	private final static int K_UNKNOWN = 0;
@@ -99,7 +103,7 @@ public class CtagsCName implements IASTName, IASTFileLocation {
     }
     
 	public IBinding getBinding() {
-		throw new PDOMNotImplementedError();
+		return binding;
 	}
 
 	public boolean isDeclaration() {
@@ -107,7 +111,8 @@ public class CtagsCName implements IASTName, IASTFileLocation {
 	}
 
 	public boolean isDefinition() {
-		throw new PDOMNotImplementedError();
+		// TODO base on kind
+		return true;
 	}
 
 	public boolean isReference() {
@@ -115,12 +120,48 @@ public class CtagsCName implements IASTName, IASTFileLocation {
 		return false;
 	}
 
-	public IBinding resolveBinding() {
+	private PDOMBinding makeNewBinding(IPDOMNode scope) throws CoreException {
 		switch (kind) {
+		case K_VARIABLE:
+			return new PDOMCVariable(linkage.getPDOM(), (PDOMNode)scope, this);
+		case K_FUNCTION:
+			return new PDOMCFunction(linkage.getPDOM(), (PDOMNode)scope, this);
 		default:
 			return null;
 		}
 	}
+	
+	public IBinding resolveBinding() {
+		try {
+			IPDOMNode scope = linkage;
+			int[] types = null;
+			switch (kind) {
+			case K_VARIABLE:
+				types = new int[] { PDOMCLinkage.CVARIABLE };
+				break;
+			case K_FUNCTION:
+				types = new int[] { PDOMCLinkage.CFUNCTION };
+				break;
+			default:
+				return null;
+			}
+			
+			CtagsBindingFinder finder = new CtagsBindingFinder(elementName, types);
+			scope.accept(finder);
+			PDOMBinding[] bindings = finder.getBindings();
+			if (bindings.length == 0)
+				binding = makeNewBinding(scope);
+			else if (bindings.length == 1)
+				binding = bindings[0];
+			else
+				// TODO resolve overloads
+				binding = bindings[0];
+			return binding;
+		} catch (CoreException e) {
+			CCorePlugin.log(e);
+			return null;
+		}
+	}
 
 	public IBinding[] resolvePrefix() {
 		throw new PDOMNotImplementedError();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCPPName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCPPName.java
index e889a6d726e..13013733a81 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCPPName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsCPPName.java
@@ -27,6 +27,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
+import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPFunction;
 import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage;
 import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPVariable;
 import org.eclipse.core.runtime.CoreException;
@@ -58,6 +59,8 @@ public class CtagsCPPName implements IASTName, IASTFileLocation {
 	private final static int K_UNION = 11;
 	private final static int K_VARIABLE = 12;
 	private final static int K_EXTERNALVAR = 13;
+	
+	private PDOMBinding binding;
 
 	private final static String[] kinds = { // Order must match value of enum above
 			null, // unknown kinds
@@ -100,7 +103,7 @@ public class CtagsCPPName implements IASTName, IASTFileLocation {
     }
     
 	public IBinding getBinding() {
-		throw new PDOMNotImplementedError();
+		return binding;
 	}
 
 	public boolean isDeclaration() {
@@ -121,6 +124,8 @@ public class CtagsCPPName implements IASTName, IASTFileLocation {
 		switch (kind) {
 		case K_VARIABLE:
 			return new PDOMCPPVariable(linkage.getPDOM(), (PDOMNode)scope, this);
+		case K_FUNCTION:
+			return new PDOMCPPFunction(linkage.getPDOM(), (PDOMNode)scope, this);
 		default:
 			return null;
 		}
@@ -134,6 +139,9 @@ public class CtagsCPPName implements IASTName, IASTFileLocation {
 			case K_VARIABLE:
 				types = new int[] { PDOMCPPLinkage.CPPVARIABLE };
 				break;
+			case K_FUNCTION:
+				types = new int[] { PDOMCPPLinkage.CPPFUNCTION };
+				break;
 			default:
 				return null;
 			}
@@ -142,12 +150,13 @@ public class CtagsCPPName implements IASTName, IASTFileLocation {
 			scope.accept(finder);
 			PDOMBinding[] bindings = finder.getBindings();
 			if (bindings.length == 0)
-				return makeNewBinding(scope);
+				binding = makeNewBinding(scope);
 			else if (bindings.length == 1)
-				return bindings[0];
+				binding = bindings[0];
 			else
 				// TODO resolve overloads
-				return bindings[0];
+				binding = bindings[0];
+			return binding;
 		} catch (CoreException e) {
 			CCorePlugin.log(e);
 			return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java
index 26b510b10f4..076049f6318 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java
@@ -16,7 +16,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.core.model.ICElementDelta;
 import org.eclipse.cdt.core.model.ITranslationUnit;
@@ -92,6 +91,8 @@ public class CtagsHandleDelta extends CtagsIndexerJob {
 			return e.getStatus();
 		} catch (InterruptedException e) {
 			return Status.CANCEL_STATUS;
+		} finally {
+			pdom.fireChange();
 		}
 	}
 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java
index 48da84cc3e3..2625595bee7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java
@@ -12,6 +12,8 @@
 package org.eclipse.cdt.internal.core.pdom.indexer.ctags;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.ICExtensionReference;
 import org.eclipse.cdt.core.dom.IPDOM;
 import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.model.ICElementDelta;
@@ -38,7 +40,7 @@ public class CtagsIndexer implements IPDOMIndexer {
 	private String ctagsFileName = ""; //$NON-NLS-1$
 	
 	public void handleDelta(ICElementDelta delta) {
-		// TODO Auto-generated method stub
+		new CtagsHandleDelta(this,delta).schedule();
 	}
 
 	public void reindex() throws CoreException {
@@ -67,17 +69,55 @@ public class CtagsIndexer implements IPDOMIndexer {
 		if (prefs == null)
 			return;
 		
-		useCtagsOnPath = prefs.getBoolean(useCtagsOnPathId, getDefaultUseCtagsOnPath());
-		ctagsCommand = prefs.get(ctagsCommandId, getDefaultCtagsCommand());
-		useInternalCtagsFile = prefs.getBoolean(useInternalCtagsFileId, getDefaultUseInternalCtagsFile());
-		ctagsFileName = prefs.get(ctagsFileNameId, getDefaultCtagsFileName());
+		ctagsCommand = prefs.get(ctagsCommandId, null);
+		if (ctagsCommand != null) {
+			useCtagsOnPath = prefs.getBoolean(useCtagsOnPathId, getDefaultUseCtagsOnPath());
+			useInternalCtagsFile = prefs.getBoolean(useInternalCtagsFileId, getDefaultUseInternalCtagsFile());
+			ctagsFileName = prefs.get(ctagsFileNameId, getDefaultCtagsFileName());
+		} else {
+			// Not defined yet check in cdescriptor
+			try {
+				ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project, false);
+				if (desc != null) {
+					ICExtensionReference[] cext = desc.get(CCorePlugin.INDEXER_UNIQ_ID);
+					if (cext.length > 0) {
+						for (int i = 0; i < cext.length; i++) {
+							String orig = cext[i].getExtensionData("ctagslocationtype"); //$NON-NLS-1$
+							useCtagsOnPath = orig != null
+								? !orig.equals("ctags_path_specified")
+								: getDefaultUseCtagsOnPath();
+							
+							orig = cext[i].getExtensionData("ctagslocation"); //$NON-NLS-1$
+							ctagsCommand = orig != null ? orig : getDefaultCtagsCommand();
+							
+							orig = cext[i].getExtensionData("ctagfiletype"); //$NON-NLS-1$
+							useInternalCtagsFile = orig != null
+								? !orig.equals("ctags_external") //$NON-NLS-1$
+								: getDefaultUseInternalCtagsFile();
+
+							orig = cext[i].getExtensionData("ctagfilelocation"); //$NON-NLS-1$
+							ctagsFileName = orig != null ? orig : getDefaultCtagsFileName();
+							
+						}
+					}
+				}
+			} catch (CoreException e) {
+			}
+			
+			if (ctagsCommand == null) {
+				useCtagsOnPath = getDefaultUseCtagsOnPath();
+				ctagsCommand = getDefaultCtagsCommand();
+				useInternalCtagsFile = getDefaultUseInternalCtagsFile();
+				ctagsFileName = getDefaultCtagsFileName();
+			}
+		}
 	}
 
 	public void setPreferences(
 			boolean useCtagsOnPath,
 			String ctagsCommand,
 			boolean useInternalCtagsFile,
-			String ctagsFileName) {
+			String ctagsFileName) throws CoreException {
 		
 		IProject project = pdom.getProject().getProject();
     	IEclipsePreferences prefs = new ProjectScope(project.getProject()).getNode(CCorePlugin.PLUGIN_ID);
@@ -115,6 +155,7 @@ public class CtagsIndexer implements IPDOMIndexer {
 			} catch (BackingStoreException e) {
 	    		CCorePlugin.log(e);
 			}
+			reindex();
 		}
 		
 	}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java
index dd3e07da636..c1ba4da7eb6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java
@@ -12,6 +12,7 @@
 package org.eclipse.cdt.internal.core.pdom.indexer.ctags;
 
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.HashMap;
@@ -46,6 +47,10 @@ public abstract class CtagsIndexerJob extends Job {
 	// Indexing functions
 	void runCtags(IPath sourcePath) {
 		String ctagsFileName = indexer.getResolvedCtagsFileName();
+		File ctagsFile = new File(ctagsFileName);
+		if (ctagsFile.exists())
+			ctagsFile.delete();
+		
     	String[] cmd = new String[] {
     			indexer.getResolvedCtagsCommand(),
     			"--excmd=number", //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java
index b09843878e5..d9c4b6e8758 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java
@@ -12,9 +12,7 @@
 package org.eclipse.cdt.internal.core.pdom.indexer.ctags;
 
 import org.eclipse.cdt.core.model.ICProject;
-import org.eclipse.cdt.core.model.IIncludeReference;
 import org.eclipse.cdt.core.model.ISourceRoot;
-import org.eclipse.cdt.core.parser.util.ArrayUtil;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -35,33 +33,34 @@ public class CtagsReindex extends CtagsIndexerJob {
 		try {
 			// What do we need to index
 			final ICProject project = pdom.getProject();
-			final IIncludeReference[] pincludes = project.getIncludeReferences();
-			IIncludeReference[] includes = new IIncludeReference[pincludes.length];
-			System.arraycopy(pincludes, 0, includes, 0, pincludes.length);
+//			final IIncludeReference[] pincludes = project.getIncludeReferences();
+//			IIncludeReference[] includes = new IIncludeReference[pincludes.length];
+//			System.arraycopy(pincludes, 0, includes, 0, pincludes.length);
 			
 			// Find common prefix paths
-			for (int i = 0; i < includes.length; ++i) {
-				if (includes[i] == null)
-					continue;
-				IPath pathi = includes[i].getPath();
-				for (int j = i + 1; j < includes.length; ++j) {
-					if (includes[j] == null)
-						continue;
-					IPath pathj = includes[j].getPath();
-					if (pathi.isPrefixOf(pathj)) {
-						includes[j] = null;
-					} else if (pathj.isPrefixOf(pathi)) {
-						includes[i] = null;
-						break;
-					}
-				}
-			}
+//			for (int i = 0; i < includes.length; ++i) {
+//				if (includes[i] == null)
+//					continue;
+//				IPath pathi = includes[i].getPath();
+//				for (int j = i + 1; j < includes.length; ++j) {
+//					if (includes[j] == null)
+//						continue;
+//					IPath pathj = includes[j].getPath();
+//					if (pathi.isPrefixOf(pathj)) {
+//						includes[j] = null;
+//					} else if (pathj.isPrefixOf(pathi)) {
+//						includes[i] = null;
+//						break;
+//					}
+//				}
+//			}
 			
-			includes = (IIncludeReference[])ArrayUtil.removeNulls(IIncludeReference.class, includes);
+//			includes = (IIncludeReference[])ArrayUtil.removeNulls(IIncludeReference.class, includes);
 			
 			ISourceRoot[] sourceRoots = project.getAllSourceRoots();
 
-			monitor.beginTask("Indexing", sourceRoots.length + includes.length + 1);
+			monitor.beginTask("Indexing", sourceRoots.length + 1);
+//					+ includes.length + 1);
 			
 			// Clear out the PDOM
 			if (monitor.isCanceled())
@@ -71,13 +70,13 @@ public class CtagsReindex extends CtagsIndexerJob {
 			monitor.worked(1);
 			
 			// Index the include path
-			for (int i = 0; i < includes.length; ++i) {
-				if (monitor.isCanceled())
-					return Status.CANCEL_STATUS;
-				monitor.subTask(includes[i].getElementName());
-				runCtags(includes[i].getPath());
-				monitor.worked(1);
-			}
+//			for (int i = 0; i < includes.length; ++i) {
+//				if (monitor.isCanceled())
+//					return Status.CANCEL_STATUS;
+//				monitor.subTask(includes[i].getElementName());
+//				runCtags(includes[i].getPath());
+//				monitor.worked(1);
+//			}
 			
 			// Index the source roots
 		    for (int i = 0; i < sourceRoots.length; ++i) {
@@ -95,6 +94,7 @@ public class CtagsReindex extends CtagsIndexerJob {
 			return e.getStatus();
 		} finally {
 		    monitor.done();
+		    pdom.fireChange();
 		}
 		return Status.OK_STATUS;
 	}
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 6770958db84..09767fd7bc9 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
@@ -147,7 +147,7 @@ public class PDOMFullHandleDelta extends PDOMFullIndexerJob {
 			if (includedBy.length > 0) {
 				IProject project = tu.getCProject().getProject();
 				for (int i = 0; i < includedBy.length; ++i) {
-					String incfilename = includedBy[i].getFileName();
+					String incfilename = includedBy[i].getFileName().getString();
 					if (CoreModel.isValidSourceUnitName(project, incfilename)) {
 						if (changed.get(incfilename) == null) {
 							IFile[] rfiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(incfilename));
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
index e294e209353..eb9f771992f 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java
@@ -219,12 +219,12 @@ public class IndexView extends ViewPart implements PDOM.IListener {
 			try {
 				if (element instanceof ICProject) {
 					PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM((ICProject)element);
-					PDOMLinkage firstLinkage = pdom.getFirstLinkage();
-					if (firstLinkage == null)
+					PDOMLinkage[] linkages = pdom.getLinkages();
+					if (linkages.length == 0)
 						return false;
-					else if (firstLinkage.getNextLinkage() == null)
+					else if (linkages.length == 1)
 						// Skipping linkages if only one
-						return hasChildren(firstLinkage);
+						return hasChildren(linkages[0]);
 					else
 						return true;
 				} else if (element instanceof IPDOMNode) {
@@ -270,13 +270,13 @@ public class IndexView extends ViewPart implements PDOM.IListener {
 				return "null :(";
 			} else if (element instanceof PDOMNode) {
 				try {
-					return ((PDOMNode)element).getName();
+					return ((PDOMNode)element).getDBName().getString();
 				} catch (CoreException e) {
 					return e.getMessage();
 				}
 			} else if (element instanceof LinkageCache) {
 				try {
-					return ((LinkageCache)element).getName();
+					return ((LinkageCache)element).getName().getString();
 				} catch (CoreException e) {
 					return e.getMessage();
 				}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/LinkageCache.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/LinkageCache.java
index 6c711270c1a..28928d08dcc 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/LinkageCache.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/LinkageCache.java
@@ -12,6 +12,7 @@
 package org.eclipse.cdt.internal.ui.indexview;
 
 import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.db.DBString;
 import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@@ -82,7 +83,7 @@ public class LinkageCache {
 		return pdom.getBinding(cache[index]);
 	}
 	
-	public String getName() throws CoreException {
-		return linkage.getName();
+	public DBString getName() throws CoreException {
+		return linkage.getDBName();
 	}
 }
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CTagsIndexerBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CTagsIndexerBlock.java
index abe4fb5b904..fca7bc2a7ea 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CTagsIndexerBlock.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CTagsIndexerBlock.java
@@ -11,18 +11,19 @@
 package org.eclipse.cdt.ui.dialogs;
 
 import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.ICDescriptor;
-import org.eclipse.cdt.core.ICExtensionReference;
+import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.internal.core.pdom.indexer.ctags.CtagsIndexer;
 import org.eclipse.cdt.internal.ui.CUIMessages;
 import org.eclipse.cdt.internal.ui.util.SWTUtil;
 import org.eclipse.cdt.ui.CUIPlugin;
 import org.eclipse.cdt.ui.index.AbstractIndexerPage;
 import org.eclipse.cdt.utils.ui.controls.ControlFactory;
-import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -39,16 +40,15 @@ import org.eclipse.swt.widgets.Text;
  */
 public class CTagsIndexerBlock extends AbstractIndexerPage {
 	
+	protected CtagsIndexer ctagsIndexer;
+	
 	protected boolean internalTagsFile = true;
-    protected boolean externalTagsFile = false;
     protected Button internalCTagsFile;
     protected Button externalCTagsFile;
-    protected Button indexIncludePaths;
 	protected Button browseButton;
 	protected Text cTagsFile;
 	
 	protected boolean useDefaultCTags = true;
-    protected boolean useSpecifiedCTagsExecutable = false;
 	protected Button useCTagsPath;
 	protected Button useCTagsExecutable;
 	protected Button browseButtonCTagsExec;
@@ -60,120 +60,50 @@ public class CTagsIndexerBlock extends AbstractIndexerPage {
 	public final static String PREF_CTAGS_LOCATION_TYPE = CUIPlugin.PLUGIN_ID + ".ctagslocationtype"; //$NON-NLS-1$
 	public final static String PREF_CTAGS_LOCATION = CUIPlugin.PLUGIN_ID + ".ctagslocation"; //$NON-NLS-1$
 	
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.ui.index.AbstractIndexerPage#initialize(org.eclipse.core.resources.IProject)
-     */
     public void initialize(ICProject project) {
-		
 		this.currentProject = project;
 		try {
-			loadPersistedValues(project.getProject());
+			loadPersistedValues(project);
 		} catch (CoreException e) {}
-		
     }
 
 	public void performApply(IProgressMonitor monitor) throws CoreException {
-		
-			if (monitor == null) {
-				monitor = new NullProgressMonitor();
-			}
-
-			monitor.beginTask(CUIMessages.getString("IndexerOptiosn.task.savingAttributes "), 1);  //$NON-NLS-1$
-			ICOptionContainer container = getContainer();
-			IProject proj = null;
-	        String internalExternalCTagsString = ""; //internalTagsFile ? CTagsIndexer.CTAGS_INTERNAL  : CTagsIndexer.CTAGS_EXTERNAL;
-			String cTagsFileLocation = ""; //$NON-NLS-1$
-			if (!internalTagsFile)
-				cTagsFileLocation = cTagsFile.getText();
-			
-			String indexIncludeFiles = new Boolean(indexIncludePaths.getSelection()).toString();
-			
-			String cTagsLocationType = ""; //useDefaultCTags ? CTagsIndexer.CTAGS_PATH_DEFAULT : CTagsIndexer.CTAGS_PATH_SPECIFIED;
-			String cTagsLocation = ""; //$NON-NLS-1$
-			if (!useDefaultCTags)
-				cTagsLocation=cTagsExecutable.getText();
-				
-			//if external has been chosen, ensure that there is a cTagsFileLocation selected; otherwise default
-			//to internal file
-//			if (internalExternalCTagsString.equals(CTagsIndexer.CTAGS_EXTERNAL) && cTagsFileLocation.equals("")) //$NON-NLS-1$
-//				internalExternalCTagsString=CTagsIndexer.CTAGS_INTERNAL;
-			
-			//if an external CPaths has been selected but no path has been provided, switch back to default setting
-//			if (cTagsLocationType.equals(CTagsIndexer.CTAGS_PATH_SPECIFIED) && cTagsLocation.equals("")) //$NON-NLS-1$
-//				cTagsLocationType=CTagsIndexer.CTAGS_PATH_DEFAULT;
-			
-			if (container != null){
-				proj = container.getProject();
-			}
-			else{
-				proj = currentProject.getProject();
-			}
-			
-			if (proj != null) {
-				ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(proj, false);
-				ICExtensionReference[] cext = cdesc.get(CCorePlugin.INDEXER_UNIQ_ID);
-				if (cext.length > 0) {
-					for (int i = 0; i < cext.length; i++) {
-						String orig = cext[i].getExtensionData("ctagfiletype"); //$NON-NLS-1$
-						if (orig == null || !orig.equals(internalExternalCTagsString)) {
-							cext[i].setExtensionData("ctagfiletype", internalExternalCTagsString); //$NON-NLS-1$
-						}
-						orig = cext[i].getExtensionData("ctagfilelocation"); //$NON-NLS-1$
-						if (orig == null || !orig.equals(cTagsFileLocation)) {
-							cext[i].setExtensionData("ctagfilelocation", cTagsFileLocation); //$NON-NLS-1$
-						}
-						orig = cext[i].getExtensionData("ctagsindexincludes"); //$NON-NLS-1$
-						if (orig == null || !orig.equals(indexIncludeFiles)) {
-							cext[i].setExtensionData("ctagsindexincludes", indexIncludeFiles); //$NON-NLS-1$
-							if (indexIncludeFiles.equals( "true")){ //$NON-NLS-1$
-//								CCorePlugin.getDefault().getCoreModel().getIndexManager().addResource(proj,proj);
-							}
-						}
-						orig = cext[i].getExtensionData("ctagslocationtype"); //$NON-NLS-1$
-						if (orig == null || !orig.equals(cTagsLocationType)) {
-							cext[i].setExtensionData("ctagslocationtype", cTagsLocationType); //$NON-NLS-1$
-						}
-						orig = cext[i].getExtensionData("ctagslocation"); //$NON-NLS-1$
-						if (orig == null || !orig.equals(cTagsLocation)) {
-							cext[i].setExtensionData("ctagslocation", cTagsLocation); //$NON-NLS-1$
-						}
-					}
-				}
-			} else {
-				if (prefStore != null) {
-					prefStore.setValue(PREF_INTOREXT_CTAGS, internalExternalCTagsString);
-					prefStore.setValue(PREF_CTAGS_FILE_LOCATION_CTAGS,cTagsFileLocation);
-					prefStore.setValue(PREF_CTAGS_INDEXINCLUDEFILES,indexIncludeFiles);
-					prefStore.setValue(PREF_CTAGS_LOCATION_TYPE,cTagsLocationType);
-					prefStore.setValue(PREF_CTAGS_LOCATION,cTagsLocation);
-				}
-			}
+		if (monitor == null) {
+			monitor = new NullProgressMonitor();
 		}
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults()
-     */
-    public void performDefaults() {
+
+		monitor.beginTask(CUIMessages.getString("IndexerOptiosn.task.savingAttributes "), 1);  //$NON-NLS-1$
+		if (ctagsIndexer != null) {
+			ctagsIndexer.setPreferences(
+					useDefaultCTags,
+					cTagsExecutable.getText(),
+					internalTagsFile,
+					cTagsFile.getText());
+		} else {
+			CtagsIndexer.setDefaultPreferences(
+					useDefaultCTags,
+					cTagsExecutable.getText(),
+					internalTagsFile,
+					cTagsFile.getText());
+		}
+	}
+
+	public void performDefaults() {
     	//ctag file options
 		internalTagsFile=true;
-		externalTagsFile=false;
 		internalCTagsFile.setSelection(true);
 		externalCTagsFile.setSelection(false);
 		cTagsFile.setText(""); //$NON-NLS-1$
 		browseButton.setEnabled(false);
 		//ctag path options
 		useDefaultCTags=true;
-		useSpecifiedCTagsExecutable=false;
 		useCTagsPath.setSelection(true);
 		useCTagsExecutable.setSelection(false);
 		cTagsExecutable.setText(""); //$NON-NLS-1$
 		browseButtonCTagsExec.setEnabled(false);
-		//index include paths
-		indexIncludePaths.setSelection(false);
     }
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
-     */
-    public void createControl(Composite parent) {
+
+	public void createControl(Composite parent) {
         Composite page = ControlFactory.createComposite(parent, 1);	
 		
         Group cTagsExecutableGroup = ControlFactory.createGroup(page,CUIMessages.getString("CTagsIndexerBlock.ctagsLocation"),3); //$NON-NLS-1$
@@ -184,13 +114,8 @@ public class CTagsIndexerBlock extends AbstractIndexerPage {
     	SelectionListener cTagsListener =  new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent event) {				
 				useDefaultCTags  = useCTagsPath.getSelection();
-				useSpecifiedCTagsExecutable = useCTagsExecutable.getSelection();
-				
 				if (useDefaultCTags){
-//					setButtonState(CTagsIndexer.CTAGS_PATH_DEFAULT);
-				}
-				if (useSpecifiedCTagsExecutable){
-//					setButtonState(CTagsIndexer.CTAGS_PATH_SPECIFIED);
+					setCommandState();
 				}
 			}
 		};
@@ -223,15 +148,6 @@ public class CTagsIndexerBlock extends AbstractIndexerPage {
         });
         //
 		
-        Group includeGroup = ControlFactory.createGroup(page,CUIMessages.getString("CTagsIndexerBlock.includeGroup"),1); //$NON-NLS-1$
-        GridData gd2 = (GridData) includeGroup.getLayoutData();
-        gd2.grabExcessHorizontalSpace = true;
-        gd2.horizontalAlignment = GridData.FILL;
-       
-        indexIncludePaths = ControlFactory.createCheckBox(includeGroup,CUIMessages.getString("CTagsIndexerBlock.indexIncludes"));//$NON-NLS-1$ //$NON-NLS-2$
-		((GridData)indexIncludePaths.getLayoutData()).horizontalSpan =1;
-		((GridData)indexIncludePaths.getLayoutData()).grabExcessHorizontalSpace = true;
-    
 		Group group = ControlFactory.createGroup(page, CUIMessages.getString("CTagsIndexerBlock.blockName"),3); //$NON-NLS-1$
         
         GridData gd = (GridData) group.getLayoutData();
@@ -242,13 +158,8 @@ public class CTagsIndexerBlock extends AbstractIndexerPage {
 		SelectionListener cListener =  new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent event) {				
 				internalTagsFile = internalCTagsFile.getSelection();
-				externalTagsFile = externalCTagsFile.getSelection();
-				
-				if (externalTagsFile){
-//					setButtonState(CTagsIndexer.CTAGS_EXTERNAL);
-				}
 				if (internalTagsFile){
-//					setButtonState(CTagsIndexer.CTAGS_INTERNAL);
+					setFilenameState();
 				}
 			}
 		};
@@ -294,83 +205,41 @@ public class CTagsIndexerBlock extends AbstractIndexerPage {
         return fileName;
     }
     
-	public void loadPersistedValues(IProject project) throws CoreException {
+	public void loadPersistedValues(ICProject project) throws CoreException {
+		IPDOMIndexer indexer = CCorePlugin.getPDOMManager().getPDOM(project).getIndexer();
+		if (!(indexer instanceof CtagsIndexer))
+			throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, 0, "Wrong indexer", null));
+		ctagsIndexer = (CtagsIndexer)indexer;
+
+		useDefaultCTags = ctagsIndexer.useCtagsOnPath();
+		cTagsExecutable.setText(ctagsIndexer.getCtagsCommand());
+		setCommandState();
 		
-		ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(project, false);
-		ICExtensionReference[] cext = cdesc.get(CCorePlugin.INDEXER_UNIQ_ID);
-		if (cext.length > 0) {
-			for (int i = 0; i < cext.length; i++) {
-				String orig = cext[i].getExtensionData("ctagfiletype"); //$NON-NLS-1$
-				if (orig != null){
-					setButtonState(orig);
-				}
-
-				orig = cext[i].getExtensionData("ctagfilelocation"); //$NON-NLS-1$
-				if (orig != null){
-					cTagsFile.setText(orig);
-				}
-				
-				orig = cext[i].getExtensionData("ctagsindexincludes"); //$NON-NLS-1$
-				if (orig != null){
-					if (new Boolean(orig).booleanValue()){
-						indexIncludePaths.setSelection(true);
-					} else {
-						indexIncludePaths.setSelection(false);
-					}
-				}
-				
-				orig = cext[i].getExtensionData("ctagslocationtype"); //$NON-NLS-1$
-				if (orig != null){
-					setButtonState(orig);
-				}
-				
-				orig = cext[i].getExtensionData("ctagslocation"); //$NON-NLS-1$
-				if (orig != null){
-					cTagsExecutable.setText(orig);
-				}
-			}
-		}
-	
+		internalTagsFile = ctagsIndexer.useInternalCtagsFile();
+		cTagsFile.setText(ctagsIndexer.getCtagsFileName());
+		setFilenameState();
 	}
 	
-	private void setButtonState(String orig){
-//		if (orig.equals(CTagsIndexer.CTAGS_INTERNAL)){ 
-//			internalTagsFile=true;
-//			externalTagsFile=false;
-//			internalCTagsFile.setSelection(true);
-//			externalCTagsFile.setSelection(false);
-//			browseButton.setEnabled(false);
-//		} else if (orig.equals(CTagsIndexer.CTAGS_EXTERNAL)){
-//			externalTagsFile=true;
-//			internalTagsFile=false;
-//			externalCTagsFile.setSelection(true);
-//			internalCTagsFile.setSelection(false);
-//			browseButton.setEnabled(true);
-//		} else if(orig.equals(CTagsIndexer.CTAGS_PATH_DEFAULT)){
-//			useDefaultCTags=true;
-//			useSpecifiedCTagsExecutable=false;
-//			useCTagsPath.setSelection(true);
-//			useCTagsExecutable.setSelection(false);
-//			browseButtonCTagsExec.setEnabled(false);
-//		} else if(orig.equals(CTagsIndexer.CTAGS_PATH_SPECIFIED)){
-//			useDefaultCTags=false;
-//			useSpecifiedCTagsExecutable=true;
-//			useCTagsPath.setSelection(false);
-//			useCTagsExecutable.setSelection(true);
-//			browseButtonCTagsExec.setEnabled(true);
-//		}
+	private void setCommandState() {
+		useCTagsPath.setSelection(useDefaultCTags);
+		useCTagsExecutable.setSelection(!useDefaultCTags);
+		browseButtonCTagsExec.setEnabled(!useDefaultCTags);
 	}
-
+	
+	private void setFilenameState() {
+		internalCTagsFile.setSelection(internalTagsFile);
+		externalCTagsFile.setSelection(!internalTagsFile);
+		browseButton.setEnabled(!internalTagsFile);
+	}
+	
 	public void loadPreferences() {
-		String indexerId=prefStore.getString(PREF_INTOREXT_CTAGS);
-		if (!indexerId.equals("")) { //$NON-NLS-1$
-		  setButtonState(indexerId);
-		}
+		useDefaultCTags = CtagsIndexer.getDefaultUseCtagsOnPath();
+		cTagsExecutable.setText(CtagsIndexer.getDefaultCtagsCommand());
+		setCommandState();
 		
-		indexerId=prefStore.getString(PREF_CTAGS_FILE_LOCATION_CTAGS);
-		if (!indexerId.equals("")) { //$NON-NLS-1$
-			cTagsFile.setText(indexerId);
-		}
+		internalTagsFile = CtagsIndexer.getDefaultUseInternalCtagsFile();
+		cTagsFile.setText(CtagsIndexer.getDefaultCtagsFileName());
+		setFilenameState();
 	}
 
 	public void removePreferences() {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
index 7e1a4358d14..c0aaa1e307d 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
@@ -16,6 +16,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMManager;
 import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ICProject;
 import org.eclipse.cdt.internal.ui.CUIMessages;
@@ -338,7 +339,9 @@ public class IndexerBlock extends AbstractCOptionPage {
 		
 			if ( project != null) {
 				ICProject cproject = CoreModel.getDefault().create(project);
-				CCorePlugin.getPDOMManager().setIndexerId(cproject, indexerID);
+				IPDOMManager manager = CCorePlugin.getPDOMManager();
+				if (!indexerID.equals(manager.getIndexerId(cproject)))
+					manager.setIndexerId(cproject, indexerID);
 				if (currentPage != null && currentPage.getControl() != null) {
 					currentPage.performApply(new SubProgressMonitor(monitor, 1));
 				}