diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog
index 5a29df6183d..6b595cdecec 100644
--- a/core/org.eclipse.cdt.core/ChangeLog
+++ b/core/org.eclipse.cdt.core/ChangeLog
@@ -1,3 +1,16 @@
+2005-04-21 Vladimir Hirsl
+	Fix for PR 91964: Dom Indexer misses give a friend declaration for forward decls
+	    Fixed detection of friend class/struct declaration.
+	Fix for PR 92060: [DOM Indexer] for C projects only seems to do macros now
+	    Taken a different approach by wrapping calls to IIndexerOutput in anticipation
+	    of its soon change.
+	
+	* index/org/eclipse/cdt/internal/core/index/domsourceindexer/CGenerateIndexVisitor.java
+	* index/org/eclipse/cdt/internal/core/index/domsourceindexer/CPPGenerateIndexerVisitor.java
+	* index/org/eclipse/cdt/internal/core/index/domsourceindexerDOMSourceIndexerRunner.java
+	* index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexerEncoderUtil.java
+	+ index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexerOutputWrapper.java
+
 2005-04-15 Vladimir Hirsl
 	Fix for PR 91405: Search does not find declarations of printf
 	Index entries form include files external to workspace were erroneously stored 
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CGenerateIndexVisitor.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CGenerateIndexVisitor.java
index fada7eb9434..d09c36c96b2 100644
--- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CGenerateIndexVisitor.java
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CGenerateIndexVisitor.java
@@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
 import org.eclipse.cdt.core.dom.ast.IVariable;
 import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
 import org.eclipse.cdt.internal.core.index.cindexstorage.ICIndexStorageConstants;
+import org.eclipse.cdt.internal.core.index.domsourceindexer.IndexerOutputWrapper.EntryType;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.Path;
 
@@ -93,12 +94,7 @@ public class CGenerateIndexVisitor extends CASTVisitor {
      * @throws DOMException
      */
     private void processName(IASTName name) throws DOMException {
-        // Quick check to see if the name is a reference in an external header file
-		//if (IndexEncoderUtil.nodeInExternalHeader(name) && name.isReference())
-		if (IndexEncoderUtil.nodeInExternalHeader(name))
-			return;
-
-		IBinding binding = name.resolveBinding();
+        IBinding binding = name.resolveBinding();
         // check for IProblemBinding
         if (binding instanceof IProblemBinding) {
             IProblemBinding problem = (IProblemBinding) binding;
@@ -109,7 +105,6 @@ public class CGenerateIndexVisitor extends CASTVisitor {
             }
             return;
         }
-
         // Get the location
         IASTFileLocation loc = IndexEncoderUtil.getFileLocation(name);
         if (loc != null) {
@@ -143,90 +138,59 @@ public class CGenerateIndexVisitor extends CASTVisitor {
      * @param indexFlag
      * @throws DOMException 
      */
-    
     private void processNameBinding(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber) throws DOMException {
         // determine type
+        EntryType entryType = null;
         if (binding instanceof ICompositeType) {
             int compositeKey = ((ICompositeType) binding).getKey();
             ASTNodeProperty prop = name.getPropertyInParent();
             switch (compositeKey) {
                 case ICompositeType.k_struct:
+                    entryType = IndexerOutputWrapper.STRUCT;
                     if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        if (name.isDeclaration()) {
-                            indexer.getOutput().addFwd_StructDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }                   
-                        else if (name.isReference()) {
-                            indexer.getOutput().addFwd_StructRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }
-                    else
-                        if (name.isDeclaration()) {
-                            indexer.getOutput().addStructDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }                   
-                        else if (name.isReference()) {
-                            indexer.getOutput().addStructRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }
+                        entryType = IndexerOutputWrapper.FWD_STRUCT;
                     break;
-                case ICompositeType.k_union:     
+                case ICompositeType.k_union:
+                    entryType = IndexerOutputWrapper.UNION;
                     if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        if (name.isDeclaration()) {
-                            indexer.getOutput().addFwd_UnionDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }                   
-                        else if (name.isReference()) {
-                            indexer.getOutput().addFwd_UnionRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }
-                    else
-                        if (name.isDeclaration()) {
-                            indexer.getOutput().addUnionDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }                   
-                        else if (name.isReference()) {
-                            indexer.getOutput().addUnionRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                        }
+                        entryType = IndexerOutputWrapper.FWD_UNION;
                     break;
             }
         }
         else if (binding instanceof IEnumeration)
-            if (name.isDeclaration()) {
-                indexer.getOutput().addEnumDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }                   
-            else if (name.isReference()) {
-                indexer.getOutput().addEnumRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }
+            entryType = IndexerOutputWrapper.ENUM;
         else if (binding instanceof ITypedef)
-            if (name.isDeclaration()) {
-                indexer.getOutput().addTypedefDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }                   
-            else if (name.isReference()) {
-                indexer.getOutput().addTypedefRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }
+            entryType = IndexerOutputWrapper.TYPEDEF;
         else if (binding instanceof IEnumerator)
-            if (name.isDeclaration()) {
-                indexer.getOutput().addEnumtorDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }                   
-            else if (name.isReference()) {
-                indexer.getOutput().addEnumtorRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }
+            entryType = IndexerOutputWrapper.ENUMERATOR;
         else if (binding instanceof IField) 
-            if (name.isDeclaration()) {
-                indexer.getOutput().addFieldDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }                   
-            else if (name.isReference()) {
-                indexer.getOutput().addFieldRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }
+            entryType = IndexerOutputWrapper.FIELD;
         else if (binding instanceof IParameter ||
                  binding instanceof IVariable) 
-            if (name.isDeclaration()) {
-                indexer.getOutput().addVarDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }                   
-            else if (name.isReference()) {
-                indexer.getOutput().addVarRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            }
+            entryType = IndexerOutputWrapper.VAR;
         else if (binding instanceof IFunction)
+            entryType = IndexerOutputWrapper.FUNCTION;
+        
+        if (entryType != null) {
             if (name.isDeclaration()) {
-                indexer.getOutput().addFunctionDecl(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
+                IndexerOutputWrapper.addNameDecl(indexer.getOutput(),
+                        getFullyQualifiedName(name),
+                        entryType,
+						fileNumber, 
+                        loc.getNodeOffset(),
+                        loc.getNodeLength(),
+                        ICIndexStorageConstants.OFFSET);
             }                   
             else if (name.isReference()) {
-                indexer.getOutput().addFunctionRef(fileNumber, getFullyQualifiedName(name),loc.getNodeOffset(),loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
+                IndexerOutputWrapper.addNameRef(indexer.getOutput(),
+                        getFullyQualifiedName(name),
+                        entryType,
+						fileNumber, 
+                        loc.getNodeOffset(),
+                        loc.getNodeLength(),
+                        ICIndexStorageConstants.OFFSET);
             }
+        }
     }
 
     /**
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CPPGenerateIndexVisitor.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CPPGenerateIndexVisitor.java
index fe8b08b6554..54b9f3939c2 100644
--- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CPPGenerateIndexVisitor.java
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/CPPGenerateIndexVisitor.java
@@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
 import org.eclipse.cdt.core.dom.ast.ITypedef;
 import org.eclipse.cdt.core.dom.ast.IVariable;
 import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@@ -37,7 +38,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.ICSearchConstants.LimitTo;
 import org.eclipse.cdt.internal.core.index.cindexstorage.ICIndexStorageConstants;
+import org.eclipse.cdt.internal.core.index.domsourceindexer.IndexerOutputWrapper.EntryType;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.Path;
 
@@ -123,7 +127,7 @@ public class CPPGenerateIndexVisitor extends CPPASTVisitor {
             //or if it occurs in another file
             int indexFlag = IndexEncoderUtil.calculateIndexFlags(indexer, loc);
     
-            processNameBinding(name, binding, loc, indexFlag); // function will determine Ref or Decl
+            processNameBinding(name, binding, loc, indexFlag, null); // function will determine limitTo
         }
     }
 
@@ -150,162 +154,152 @@ public class CPPGenerateIndexVisitor extends CPPASTVisitor {
      * @param limitTo 
      * @throws DOMException
      */
-    
-    private void processNameDeclBinding(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber) throws DOMException {
-    	if (binding instanceof ICompositeType) {
-            ICompositeType compBinding = (ICompositeType) binding;
-            int compositeKey = compBinding.getKey();
-            ASTNodeProperty prop = name.getPropertyInParent();
-            switch (compositeKey) {
-                case ICPPClassType.k_class:                 
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_ClassDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addClassDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-                case ICompositeType.k_struct:                   
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_StructDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addStructDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-                case ICompositeType.k_union:                   
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_UnionDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addUnionDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-            }
-            addDerivedAndFriendDeclaration(name, compBinding, loc, fileNumber);
-        }
-        else if (binding instanceof IEnumeration)
-        	 indexer.getOutput().addEnumDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ITypedef)
-        	 indexer.getOutput().addTypedefDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ICPPNamespace)
-        	 indexer.getOutput().addNamespaceDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IEnumerator)
-        	 indexer.getOutput().addEnumtorDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IField) 
-        	 indexer.getOutput().addFieldDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IParameter ||
-                 binding instanceof IVariable) 
-        	 indexer.getOutput().addVarDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ICPPMethod)
-        	 indexer.getOutput().addMethodDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IFunction) {
-        	 indexer.getOutput().addFunctionDecl(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            // TODO In case we want to add friend function declarations to index
-            // addDerivedAndFriendDeclaration(name, binding, loc, fileNumber);
-        }
-        else if (binding instanceof ICPPUsingDeclaration) {
-            ICPPDelegate[] delegates = ((ICPPUsingDeclaration)binding).getDelegates();
-            for (int i = 0; i < delegates.length; i++) {
-                IBinding orig = delegates[i].getBinding();
-                processNameRefBinding(name, orig, loc, fileNumber); // reference to the original binding
-                processNameDeclBinding(name, delegates[i], loc, fileNumber); // declaration of the new name
-            }
-            return;
-        }
-    }
-    
-    private void processNameRefBinding(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber) throws DOMException {
-    	if (binding instanceof ICompositeType) {
-            ICompositeType compBinding = (ICompositeType) binding;
-            int compositeKey = compBinding.getKey();
-            ASTNodeProperty prop = name.getPropertyInParent();
-            switch (compositeKey) {
-                case ICPPClassType.k_class:                 
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_ClassRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addClassRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-                case ICompositeType.k_struct:                   
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_StructRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addStructRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-                case ICompositeType.k_union:                   
-                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
-                        indexer.getOutput().addFwd_UnionRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    else
-                        indexer.getOutput().addUnionRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-                    break;
-            }
-            addDerivedAndFriendDeclaration(name, compBinding, loc, fileNumber);
-        }
-        else if (binding instanceof IEnumeration)
-        	 indexer.getOutput().addEnumRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ITypedef)
-        	 indexer.getOutput().addTypedefRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ICPPNamespace)
-        	 indexer.getOutput().addNamespaceRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IEnumerator)
-        	 indexer.getOutput().addEnumtorRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IField) 
-        	 indexer.getOutput().addFieldRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IParameter ||
-                 binding instanceof IVariable) 
-        	 indexer.getOutput().addVarRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof ICPPMethod)
-        	 indexer.getOutput().addMethodRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-        else if (binding instanceof IFunction) {
-        	 indexer.getOutput().addFunctionRef(fileNumber, getFullyQualifiedName(binding), loc.getNodeOffset(), loc.getNodeLength(),ICIndexStorageConstants.OFFSET);
-            // TODO In case we want to add friend function declarations to index
-            // addDerivedAndFriendDeclaration(name, binding, loc, fileNumber);
-        }
-        else if (binding instanceof ICPPUsingDeclaration) {
-            ICPPDelegate[] delegates = ((ICPPUsingDeclaration)binding).getDelegates();
-            for (int i = 0; i < delegates.length; i++) {
-                IBinding orig = delegates[i].getBinding();
-                processNameRefBinding(name, orig, loc, fileNumber); // reference to the original binding
-                processNameDeclBinding(name, delegates[i], loc, fileNumber); // declaration of the new name
-            }
-            return;
-        }
-    }
-    private void processNameBinding(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber) throws DOMException {
+    private void processNameBinding(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber, LimitTo limitTo) throws DOMException {
+        // determine LimitTo
+        if (limitTo == null) {
             if (name.isDeclaration()) {
-            	processNameDeclBinding(name, binding, loc, fileNumber);
+                limitTo = ICSearchConstants.DECLARATIONS;
             }
             else if (name.isReference()) {
-            	processNameRefBinding(name, binding, loc, fileNumber);
-            }           
-//            else 
-//            	ICSearchConstants.UNKNOWN_LIMIT_TO;
+                limitTo = ICSearchConstants.REFERENCES;
+            }
+            else {
+                limitTo = ICSearchConstants.UNKNOWN_LIMIT_TO;
+            }
+        }
+        
+        // determine type
+        EntryType entryType = null;
+        if (binding instanceof ICompositeType) {
+            ICompositeType compBinding = (ICompositeType) binding;
+            int compositeKey = compBinding.getKey();
+            ASTNodeProperty prop = name.getPropertyInParent();
+            switch (compositeKey) {
+                case ICPPClassType.k_class:
+                    entryType = IndexerOutputWrapper.CLASS;
+                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
+                        entryType = IndexerOutputWrapper.FWD_CLASS;
+                    break;
+                case ICompositeType.k_struct:
+                    entryType = IndexerOutputWrapper.STRUCT;
+                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
+                        entryType = IndexerOutputWrapper.FWD_STRUCT;
+                    break;
+                case ICompositeType.k_union:
+                    entryType = IndexerOutputWrapper.UNION;
+                    if (name.isDeclaration() && prop == IASTElaboratedTypeSpecifier.TYPE_NAME)
+                        entryType = IndexerOutputWrapper.FWD_UNION;
+                    break;
+            }
+			addDerivedDeclaratiion(name, compBinding, loc, fileNumber);
+	        if (isFriendDeclaration(name, binding)) {
+				entryType = IndexerOutputWrapper.FRIEND; 
+	        }
+        }
+        else if (binding instanceof IEnumeration)
+            entryType = IndexerOutputWrapper.ENUM;
+        else if (binding instanceof ITypedef)
+            entryType = IndexerOutputWrapper.TYPEDEF;
+        else if (binding instanceof ICPPNamespace)
+            entryType = IndexerOutputWrapper.NAMESPACE;
+        else if (binding instanceof IEnumerator)
+            entryType = IndexerOutputWrapper.ENUMERATOR;
+        else if (binding instanceof IField) 
+            entryType = IndexerOutputWrapper.FIELD;
+        else if (binding instanceof IParameter ||
+                 binding instanceof IVariable) 
+            entryType = IndexerOutputWrapper.VAR;
+        else if (binding instanceof ICPPMethod) {
+            entryType = IndexerOutputWrapper.METHOD;
+            // TODO In case we want to add friend method declarations to index
+//          if (isFriendDeclaration(name, binding)) {
+//			    entryType = IndexerOutputWrapper.FRIEND; 
+//          }
+        }
+        else if (binding instanceof IFunction) {
+            entryType = IndexerOutputWrapper.FUNCTION;
+            // TODO In case we want to add friend function declarations to index
+//	        if (isFriendDeclaration(name, binding)) {
+//				entryType = IndexerOutputWrapper.FRIEND; 
+//	        }
+        }
+        else if (binding instanceof ICPPUsingDeclaration) {
+            ICPPDelegate[] delegates = ((ICPPUsingDeclaration)binding).getDelegates();
+            for (int i = 0; i < delegates.length; i++) {
+                IBinding orig = delegates[i].getBinding();
+                processNameBinding(name, orig, loc, fileNumber, ICSearchConstants.REFERENCES); // reference to the original binding
+                processNameBinding(name, delegates[i], loc, fileNumber, ICSearchConstants.DECLARATIONS); // declaration of the new name
+            }
+            return;
+        }
+        
+        if (entryType != null) {
+			if (limitTo == ICSearchConstants.DECLARATIONS) {
+	            IndexerOutputWrapper.addNameDecl(indexer.getOutput(),
+						getFullyQualifiedName(binding),
+						entryType,
+	                    fileNumber, 
+	                    loc.getNodeOffset(),
+	                    loc.getNodeLength(),
+	                    ICIndexStorageConstants.OFFSET);
+			}
+			else if (limitTo == ICSearchConstants.REFERENCES) {
+	            IndexerOutputWrapper.addNameRef(indexer.getOutput(),
+						getFullyQualifiedName(binding),
+						entryType,
+	                    fileNumber, 
+	                    loc.getNodeOffset(),
+	                    loc.getNodeLength(),
+	                    ICIndexStorageConstants.OFFSET);
+			}
+        }
     }
 
     /**
      * @param name
+     * @param compBinding
+     * @param loc
+     * @param fileNumber
+     * @throws DOMException
+     */
+	private void addDerivedDeclaratiion(IASTName name, ICompositeType compBinding, IASTFileLocation loc, int fileNumber) throws DOMException {
+        ASTNodeProperty prop = name.getPropertyInParent();
+        int compositeKey = compBinding.getKey();
+        if (compositeKey == ICPPClassType.k_class || compositeKey == ICompositeType.k_struct) {
+            if (prop == ICPPASTBaseSpecifier.NAME) {
+                // base class
+	            IndexerOutputWrapper.addNameDecl(indexer.getOutput(), getFullyQualifiedName(compBinding),
+						IndexerOutputWrapper.DERIVED,
+	                    fileNumber, 
+	                    loc.getNodeOffset(),
+	                    loc.getNodeLength(),
+	                    ICIndexStorageConstants.OFFSET);
+            }
+        }
+	}
+
+	/**
+     * @param name
      * @param fileNumber 
      * @param loc 
-     * @param compBinding
+     * @param binding
      * @throws DOMException 
      */
-    private void addDerivedAndFriendDeclaration(IASTName name, IBinding binding, IASTFileLocation loc, int fileNumber) throws DOMException {
+    private boolean isFriendDeclaration(IASTName name, IBinding binding) throws DOMException {
+		boolean rc = false;
+		if (!name.isDeclaration())
+			return rc;
         ASTNodeProperty prop = name.getPropertyInParent();
         if (binding instanceof ICompositeType) {
             ICompositeType compBinding = (ICompositeType) binding;
             int compositeKey = compBinding.getKey();
-            if (compositeKey == ICPPClassType.k_class ||
-                    compositeKey == ICompositeType.k_struct) {
-                if (prop == ICPPASTBaseSpecifier.NAME) {
-                    // base class
-                    indexer.getOutput().addDerivedDecl(fileNumber, 
-                            getFullyQualifiedName(binding),
-                            loc.getNodeOffset(),
-                            loc.getNodeLength(),
-                            ICIndexStorageConstants.OFFSET);
-                }
-                else if (prop == IASTElaboratedTypeSpecifier.TYPE_NAME) {
-                    // friend 
-                    indexer.getOutput().addFriendDecl(fileNumber, 
-                            getFullyQualifiedName(binding),
-                            loc.getNodeOffset(),
-                            loc.getNodeLength(),
-                            ICIndexStorageConstants.OFFSET);
+            if (compositeKey == ICPPClassType.k_class || compositeKey == ICompositeType.k_struct) {
+                if (prop == IASTElaboratedTypeSpecifier.TYPE_NAME) {
+					IASTElaboratedTypeSpecifier elaboratedTypeSpec = (IASTElaboratedTypeSpecifier) name.getParent();
+					if (elaboratedTypeSpec instanceof ICPPASTDeclSpecifier) {
+						ICPPASTDeclSpecifier cppDeclSpec = (ICPPASTDeclSpecifier) elaboratedTypeSpec;
+						rc = cppDeclSpec.isFriend();
+					}
                 }
             }
         }
@@ -320,17 +314,12 @@ public class CPPGenerateIndexVisitor extends CPPASTVisitor {
 //                    IASTDeclSpecifier declSpec = sDecl.getDeclSpecifier();
 //                    if (declSpec instanceof ICPPASTSimpleDeclSpecifier) {
 //                        ICPPASTSimpleDeclSpecifier fDeclSpec = (ICPPASTSimpleDeclSpecifier) declSpec;
-//                        if (fDeclSpec.isFriend()) {
-//                            // friend 
-//                            indexer.getOutput().addRef(fileNumber, IndexEncoderUtil.encodeEntry(
-//                                        getFullyQualifiedName(binding),
-//                                        ICIndexStorageConstants.FRIEND,
-//                                        ICSearchConstants.DECLARATIONS));
-//                        }
+//                        rc = fDeclSpec.isFriend();
 //                    }
 //                }
 //            }
 //        }
+		return rc;
     }
 
     /**
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/DOMSourceIndexerRunner.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/DOMSourceIndexerRunner.java
index bb427abbe3d..0ca8af2f763 100644
--- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/DOMSourceIndexerRunner.java
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/DOMSourceIndexerRunner.java
@@ -202,10 +202,14 @@ public class DOMSourceIndexerRunner extends AbstractIndexer {
             getOutput().addIncludeRef(fileNumber, include);
             getOutput().addRelatives(fileNumber, include, 
                     (parent != null) ? parent.getIncludeDirective().getPath() : null);
-            getOutput().addIncludeRef(fileNumber, 
-                        new char[][] {include.toCharArray()},
-                        1,1, ICIndexStorageConstants.LINE
-                        );
+			
+            IndexerOutputWrapper.addNameRef(getOutput(),
+                    new char[][] {include.toCharArray()}, 
+					IndexerOutputWrapper.INCLUDE,
+					fileNumber,
+					1,
+					1,
+					ICIndexStorageConstants.OFFSET);
             
             /* See if this file has been encountered before */
             indexer.haveEncounteredHeader(resourceFile.getProject().getFullPath(), new Path(include));
@@ -224,9 +228,11 @@ public class DOMSourceIndexerRunner extends AbstractIndexer {
             // Get the location
             IASTFileLocation loc = IndexEncoderUtil.getFileLocation(macro);
             int fileNumber = IndexEncoderUtil.calculateIndexFlags(this, loc);
-            getOutput().addMacroDecl(fileNumber,
+            IndexerOutputWrapper.addNameDecl(getOutput(),
                     new char[][] {macro.toCharArray()},
-                    loc.getNodeOffset(),
+					IndexerOutputWrapper.MACRO,
+					fileNumber,
+					loc.getNodeOffset(),
                     loc.getNodeLength(),
                     ICIndexStorageConstants.OFFSET);
         }
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexEncoderUtil.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexEncoderUtil.java
index 53677a532d3..c2f5e06b00b 100644
--- a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexEncoderUtil.java
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexEncoderUtil.java
@@ -84,12 +84,5 @@ public class IndexEncoderUtil {
         }
         return fileLoc;
     }
-	
-	public static boolean nodeInExternalHeader(IASTNode node) {
-		String fileName = node.getContainingFilename();
-		return (CCorePlugin.getWorkspace().getRoot().getFileForLocation(new Path(fileName)) == null)
-				? true : false;
-	}
-
 
 }
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexerOutputWrapper.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexerOutputWrapper.java
new file mode 100644
index 00000000000..94e8aa86fc9
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/domsourceindexer/IndexerOutputWrapper.java
@@ -0,0 +1,206 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.internal.core.index.domsourceindexer;
+
+import org.eclipse.cdt.internal.core.index.IIndexerOutput;
+
+
+/**
+ * Wrapper for calls to IIndexerOutput 
+ * (in anticipation that the interface is going to change)
+ * 
+ * @author vhirsl
+ */
+class IndexerOutputWrapper {
+    static class EntryType {
+        public int toInt() {
+            return type;
+        }
+        private EntryType(int type) {
+            this.type = type;
+        }
+        private int type;
+        
+    }
+	private final static int CLASS_CONST = 1;
+	private final static int STRUCT_CONST = 2;
+	private final static int UNION_CONST = 3;
+	private final static int ENUM_CONST = 4;
+	private final static int VAR_CONST = 5;
+	private final static int TYPEDEF_CONST = 6;
+	private final static int DERIVED_CONST = 7;
+	private final static int FRIEND_CONST = 8;
+	private final static int FWD_CLASS_CONST = 9;
+	private final static int FWD_STRUCT_CONST = 10;
+	private final static int FWD_UNION_CONST = 11;
+	private final static int NAMESPACE_CONST = 12;
+	private final static int ENUMERATOR_CONST = 13;
+	private final static int FIELD_CONST = 14;
+	private final static int METHOD_CONST = 15;
+	private final static int FUNCTION_CONST = 16;
+	private final static int MACRO_CONST = 17;
+	private final static int INCLUDE_CONST = 18;
+	
+	
+    // entry types
+    final static EntryType CLASS = new EntryType(CLASS_CONST);
+    final static EntryType STRUCT = new EntryType(STRUCT_CONST);
+    final static EntryType UNION = new EntryType(UNION_CONST);
+    final static EntryType ENUM = new EntryType(ENUM_CONST);
+    final static EntryType VAR = new EntryType(VAR_CONST);
+    final static EntryType TYPEDEF = new EntryType(TYPEDEF_CONST);
+    final static EntryType DERIVED = new EntryType(DERIVED_CONST);
+    final static EntryType FRIEND = new EntryType(FRIEND_CONST);
+    final static EntryType FWD_CLASS = new EntryType(FWD_CLASS_CONST);
+    final static EntryType FWD_STRUCT = new EntryType(FWD_STRUCT_CONST);
+    final static EntryType FWD_UNION = new EntryType(FWD_UNION_CONST);
+    final static EntryType NAMESPACE = new EntryType(NAMESPACE_CONST);
+    final static EntryType ENUMERATOR = new EntryType(ENUMERATOR_CONST);
+    final static EntryType FIELD = new EntryType(FIELD_CONST);
+    final static EntryType METHOD = new EntryType(METHOD_CONST);
+    final static EntryType FUNCTION = new EntryType(FUNCTION_CONST);
+    final static EntryType MACRO = new EntryType(MACRO_CONST);
+    final static EntryType INCLUDE = new EntryType(INCLUDE_CONST);
+
+
+	private IndexerOutputWrapper() {
+	}
+
+	static void addNameDecl(IIndexerOutput indexerOutput,
+							  char[][] name,
+							  EntryType entryType,
+							  int fileNumber,
+							  int offset,
+							  int length,
+							  int offsetType) {
+		//TODO temporary until all bindings are completed
+		if (name == null) 
+			name = new char[][] {"NPE".toCharArray()}; //$NON-NLS-1$
+		switch (entryType.toInt()) {
+			case CLASS_CONST:
+				indexerOutput.addClassDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case STRUCT_CONST:
+				indexerOutput.addStructDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case UNION_CONST:
+				indexerOutput.addUnionDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case ENUM_CONST:
+				indexerOutput.addEnumDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case VAR_CONST:
+				indexerOutput.addVarDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case TYPEDEF_CONST:
+				indexerOutput.addTypedefDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case DERIVED_CONST:
+				indexerOutput.addDerivedDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FRIEND_CONST:
+				indexerOutput.addFriendDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_CLASS_CONST:
+				indexerOutput.addFwd_ClassDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_STRUCT_CONST:
+				indexerOutput.addFwd_StructDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_UNION_CONST:
+				indexerOutput.addFwd_UnionDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case NAMESPACE_CONST:
+				indexerOutput.addNamespaceDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case ENUMERATOR_CONST:
+				indexerOutput.addEnumtorDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FIELD_CONST:
+				indexerOutput.addFieldDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case METHOD_CONST:
+				indexerOutput.addMethodDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case FUNCTION_CONST:
+				indexerOutput.addFunctionDecl(fileNumber, name, offset, length, offsetType);
+				break;
+			case MACRO_CONST:
+				indexerOutput.addMacroDecl(fileNumber, name, offset, length, offsetType);
+				break;
+		}
+	}
+	
+	static void addNameRef(IIndexerOutput indexerOutput,
+ 						   char[][] name,
+						   EntryType entryType,
+						   int fileNumber,
+						   int offset,
+						   int length,
+						   int offsetType) {
+		//TODO temporary until all bindings are completed
+		if (name == null) 
+			name = new char[][] {"NPE".toCharArray()}; //$NON-NLS-1$
+		switch (entryType.toInt()) {
+			case CLASS_CONST:
+				indexerOutput.addClassRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case STRUCT_CONST:
+				indexerOutput.addStructRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case UNION_CONST:
+				indexerOutput.addUnionRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case ENUM_CONST:
+				indexerOutput.addEnumRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case VAR_CONST:
+				indexerOutput.addVarRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case TYPEDEF_CONST:
+				indexerOutput.addTypedefRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case DERIVED_CONST:
+				indexerOutput.addDerivedRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FRIEND_CONST:
+				indexerOutput.addFriendRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_CLASS_CONST:
+				indexerOutput.addFwd_ClassRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_STRUCT_CONST:
+				indexerOutput.addFwd_StructRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FWD_UNION_CONST:
+				indexerOutput.addFwd_UnionRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case NAMESPACE_CONST:
+				indexerOutput.addNamespaceRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case ENUMERATOR_CONST:
+				indexerOutput.addEnumtorRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FIELD_CONST:
+				indexerOutput.addFieldRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case METHOD_CONST:
+				indexerOutput.addMethodRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case FUNCTION_CONST:
+				indexerOutput.addFunctionRef(fileNumber, name, offset, length, offsetType);
+				break;
+			case INCLUDE_CONST:
+				indexerOutput.addIncludeRef(fileNumber, name, offset, length, offsetType);
+				break;
+		}
+	}
+}