Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] FIXED 96865 and added 29 tests for open definition/declaration


FIXED 96865- [DOM Indexer] won't run on new Standard Make C Project
includes JUnits for AutomatedSuite to test Open Definition/Open Declaration against the DOM Indexer and the CTags Indexer
added 29 tests for the above and raised the following bugs on those tests: 96689, 96690, 96694

Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada


Index: index/org/eclipse/cdt/internal/core/index/ctagsindexer/CTagsIndexer.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/ctagsindexer/CTagsIndexer.java,v
retrieving revision 1.8
diff -u -r1.8 CTagsIndexer.java
--- index/org/eclipse/cdt/internal/core/index/ctagsindexer/CTagsIndexer.java	4 May 2005 18:58:39 -0000	1.8
+++ index/org/eclipse/cdt/internal/core/index/ctagsindexer/CTagsIndexer.java	27 May 2005 20:22:11 -0000
@@ -11,16 +11,23 @@
 package org.eclipse.cdt.internal.core.index.ctagsindexer;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 
 import org.eclipse.cdt.core.AbstractCExtension;
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.ICLogConstants;
 import org.eclipse.cdt.core.index.ICDTIndexer;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
 import org.eclipse.cdt.core.index.IIndexStorage;
+import org.eclipse.cdt.core.index.IndexChangeEvent;
 import org.eclipse.cdt.core.model.ICModelMarker;
+import org.eclipse.cdt.internal.core.Util;
 import org.eclipse.cdt.internal.core.index.IIndex;
 import org.eclipse.cdt.internal.core.index.IIndexerOutput;
+import org.eclipse.cdt.internal.core.index.impl.IndexDelta;
 import org.eclipse.cdt.internal.core.index.sourceindexer.CIndexStorage;
 import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
 import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor;
@@ -32,16 +39,26 @@
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
 
 /**
  * @author Bogdan Gheorghe
  */
 public class CTagsIndexer extends AbstractCExtension implements ICDTIndexer {
 
+	public static boolean VERBOSE = false;
+	
 	public final static String CTAGS_INTERNAL = "ctags_internal"; //$NON-NLS-1$
 	public final static String CTAGS_EXTERNAL = "ctags_external"; //$NON-NLS-1$
 	public final static String CTAGS_LOCATION = "ctags_location"; //$NON-NLS-1$
 	
+	protected List indexChangeListeners = Collections.synchronizedList(new ArrayList());
+	public static final String INDEX_NOTIFICATION_NAME = Util.bind( "indexNotificationJob" ); //$NON-NLS-1$
 	private CIndexStorage		indexStorage = null;
 	public 	ReadWriteMonitor	storageMonitor = null;
 	private IndexManager  		indexManager = null; 
@@ -374,5 +391,61 @@
         indexManager.removeIndexerProblems(project);
 	}
 	
+	public void addIndexChangeListener(IIndexChangeListener listener) {
+		synchronized(indexChangeListeners) {
+			if (!indexChangeListeners.contains(listener)) {
+				indexChangeListeners.add(listener);
+			}
+		}
+	}
+	
+	public void removeIndexChangeListener(IIndexChangeListener listener) {
+		synchronized(indexChangeListeners) {
+			int i = indexChangeListeners.indexOf(listener);
+			if (i != -1) {
+				indexChangeListeners.remove(i);
+			}
+		}
+	}
+	/**
+	 * @param indexDelta
+	 */
+	public void notifyListeners(IndexDelta indexDelta) {
+		final IndexChangeEvent indexEvent = new IndexChangeEvent(indexDelta);
+		for (int i= 0; i < indexChangeListeners.size(); i++) {
+			    IIndexChangeListener tempListener = null;
+			    synchronized(indexChangeListeners){
+			    	tempListener = (IIndexChangeListener) indexChangeListeners.get(i);
+			    }
+			    final IIndexChangeListener listener = tempListener;
+				long start = -1;
+				if (VERBOSE) {
+					System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
+					start = System.currentTimeMillis();
+				}
+				
+				// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+				Job job = new Job(INDEX_NOTIFICATION_NAME){
+					protected IStatus run(IProgressMonitor monitor)	{	
+						Platform.run(new ISafeRunnable() {
+							public void handleException(Throwable exception) {
+								CCorePlugin.log(exception);
+							}
+							public void run() throws Exception {
+								listener.indexChanged(indexEvent);
+							}
+						});
+						
+						return Status.OK_STATUS;
+					}
+				};
+				
+				job.schedule();
+				if (VERBOSE) {
+					System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		
+		}
 
 }
Index: model/org/eclipse/cdt/core/model/CoreModel.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java,v
retrieving revision 1.58
diff -u -r1.58 CoreModel.java
--- model/org/eclipse/cdt/core/model/CoreModel.java	19 May 2005 20:08:18 -0000	1.58
+++ model/org/eclipse/cdt/core/model/CoreModel.java	27 May 2005 20:22:12 -0000
@@ -1098,7 +1098,7 @@
 
 	public static boolean isScannerInformationEmpty(IResource resource) {
 		final int PATH_ENTRY_MASK = IPathEntry.CDT_INCLUDE | IPathEntry.CDT_MACRO |
-									IPathEntry.CDT_INCLUDE_FILE | IPathEntry.CDT_MACRO_FILE;
+									IPathEntry.CDT_INCLUDE_FILE | IPathEntry.CDT_MACRO_FILE | IPathEntry.CDT_SOURCE;
 		boolean rc = true;
 		IPath resPath = resource.getFullPath();
 		IProject project = resource.getProject();
Index: ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java,v
retrieving revision 1.29
diff -u -r1.29 AutomatedSuite.java
--- ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java	10 May 2005 20:31:01 -0000	1.29
+++ ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java	27 May 2005 20:27:00 -0000
@@ -48,7 +48,11 @@
 import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_VariableType_NoPrefix;
 import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_VariableType_Prefix;
 import org.eclipse.cdt.ui.tests.text.contentassist.ContentAssistTests;
+import org.eclipse.cdt.ui.tests.text.selectiontests.CPPSelectionTestsCTagsIndexer;
+import org.eclipse.cdt.ui.tests.text.selectiontests.CPPSelectionTestsDOMIndexer;
 import org.eclipse.cdt.ui.tests.text.selectiontests.CPPSelectionTestsNoIndexer;
+import org.eclipse.cdt.ui.tests.text.selectiontests.CSelectionTestsCTagsIndexer;
+import org.eclipse.cdt.ui.tests.text.selectiontests.CSelectionTestsDOMIndexer;
 import org.eclipse.cdt.ui.tests.text.selectiontests.CSelectionTestsNoIndexer;
 
 
@@ -119,9 +123,13 @@
 		// Failed Tests
 		addTest(CompletionFailedTest_MemberReference_Arrow_Prefix2.suite());
 		
-        // selection tests with no indexer
+        // selection tests
         addTest( CPPSelectionTestsNoIndexer.suite() );
 		addTest( CSelectionTestsNoIndexer.suite() );
+		addTest( CPPSelectionTestsDOMIndexer.suite() );
+		addTest( CSelectionTestsDOMIndexer.suite() );
+		addTest( CPPSelectionTestsCTagsIndexer.suite() );
+		addTest( CSelectionTestsCTagsIndexer.suite() );
 	}
 	
 }
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/BaseSelectionTestsIndexer.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/BaseSelectionTestsIndexer.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/BaseSelectionTestsIndexer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/BaseSelectionTestsIndexer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,308 @@
+/**********************************************************************
+ * Copyright (c) 2005 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.ui.tests.text.selectiontests;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.ICDescriptorOperation;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.index.IIndexDelta;
+import org.eclipse.cdt.core.index.IndexChangeEvent;
+import org.eclipse.cdt.core.search.DOMSearchUtil;
+import org.eclipse.cdt.core.testplugin.FileManager;
+import org.eclipse.cdt.internal.core.parser.ParserException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+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.jface.action.IAction;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+import junit.framework.TestCase;
+
+/**
+ * Base test class for testing F2/F3 with the indexers.
+ *  
+ * @author dsteffle
+ */
+public class BaseSelectionTestsIndexer extends TestCase {
+	public static final int TIMEOUT = 50;
+	protected boolean fileIndexed;
+	protected IProject project;
+	static FileManager fileManager = new FileManager();
+	IProgressMonitor monitor = new NullProgressMonitor();
+	
+	public BaseSelectionTestsIndexer(String name) {
+		super(name);
+	}
+	
+	public void waitForIndex(int maxSec) throws Exception {
+		int delay = 0;
+		while (fileIndexed != true && delay < (maxSec * 1000))
+		{ 
+			Thread.sleep(TIMEOUT);
+			delay += TIMEOUT;
+		}
+	}
+	
+	public void indexChanged(IndexChangeEvent event) {
+		IIndexDelta delta = event.getDelta();
+		if (delta.getDeltaType() == IIndexDelta.MERGE_DELTA){
+			fileIndexed = true;
+		}
+	}
+	
+	protected String getMessage(IStatus status) {
+		StringBuffer message = new StringBuffer("["); //$NON-NLS-1$
+		message.append(status.getMessage());
+		if (status.isMultiStatus()) {
+			IStatus children[] = status.getChildren();
+			for (int i = 0; i < children.length; i++) {
+				message.append(getMessage(children[i]));
+			}
+		}
+		message.append("]"); //$NON-NLS-1$
+		return message.toString();
+	}
+
+    protected IFile importFile(String fileName, String contents ) throws Exception{
+        //Obtain file handle
+        IFile file = project.getProject().getFile(fileName);
+        
+        InputStream stream = new ByteArrayInputStream( contents.getBytes() ); 
+        //Create file input stream
+        if( file.exists() )
+            file.setContents( stream, false, false, monitor );
+        else
+            file.create( stream, false, monitor );
+        
+        fileManager.addFile(file);
+        
+        waitForIndex(20); // only wait 20 seconds max.
+        
+        return file;
+    }
+
+    protected IFolder importFolder(String folderName) throws Exception {
+    	IFolder folder = project.getProject().getFolder(folderName);
+		
+		//Create file input stream
+		if( !folder.exists() )
+			folder.create( false, false, monitor );
+		
+		return folder;
+    }
+    
+	public void resetIndexState() {
+		fileIndexed = false;
+	}
+	
+	protected IASTNode testF3(IFile file, int offset) throws ParserException {
+		return testF3(file, offset, 0);
+	}
+	
+    protected IASTNode testF3(IFile file, int offset, int length) throws ParserException {
+		if (offset < 0)
+			throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$
+		
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        IEditorPart part = null;
+        try {
+            part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+            assertFalse(true);
+        }
+        
+        if (part instanceof AbstractTextEditor) {
+            ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length));
+            
+            final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations"); //$NON-NLS-1$
+            action.run();
+        
+        	// update the file/part to point to the newly opened IFile/IEditorPart
+            part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 
+            IEditorInput input = part.getEditorInput(); 
+            if (input instanceof FileEditorInput) {
+            	file = ((FileEditorInput)input).getFile();
+            } else {
+            	assertFalse(true); // bail!
+            }             
+            
+            // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU
+            ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection();
+            
+            if (sel instanceof TextSelection) {
+                IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength());
+                
+                if (names == null || names.length == 0)
+                    return null;
+
+				return names[0];
+            }
+        }
+        
+        return null;
+    }
+    
+    protected ISelection testF3Selection(IFile file, int offset) throws ParserException {
+    	return testF3Selection(file, offset, 0);
+    }
+    
+    protected ISelection testF3Selection(IFile file, int offset, int length) throws ParserException {
+		if (offset < 0)
+			throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$
+		
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        IEditorPart part = null;
+        try {
+            part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+            assertFalse(true);
+        }
+        
+        if (part instanceof AbstractTextEditor) {
+            ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length));
+            
+            final IAction action = ((AbstractTextEditor)part).getAction("OpenDeclarations"); //$NON-NLS-1$
+            action.run();
+        
+        	// update the file/part to point to the newly opened IFile/IEditorPart
+            part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 
+            IEditorInput input = part.getEditorInput(); 
+            if (input instanceof FileEditorInput) {
+            	file = ((FileEditorInput)input).getFile();
+            } else {
+            	assertFalse(true); // bail!
+            }             
+            
+            // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU
+            return ((AbstractTextEditor)part).getSelectionProvider().getSelection();
+        }
+        
+        return null;
+    }
+    
+	protected IASTNode testF2(IFile file, int offset) throws ParserException {
+		return testF2(file, offset, 0);
+	}
+	
+    protected IASTNode testF2(IFile file, int offset, int length) throws ParserException {
+		if (offset < 0)
+			throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$
+		
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        IEditorPart part = null;
+        try {
+            part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+            assertFalse(true);
+        }
+        
+        if (part instanceof AbstractTextEditor) {
+            ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length));
+            
+            final IAction action = ((AbstractTextEditor)part).getAction("OpenDefinition"); //$NON-NLS-1$
+            action.run();
+            
+        	// update the file/part to point to the newly opened IFile/IEditorPart
+            part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 
+            IEditorInput input = part.getEditorInput(); 
+            if (input instanceof FileEditorInput) {
+            	file = ((FileEditorInput)input).getFile();
+            } else {
+            	assertFalse(true); // bail!
+            }             
+        
+            // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU
+            ISelection sel = ((AbstractTextEditor)part).getSelectionProvider().getSelection();
+            
+            if (sel instanceof TextSelection) {
+                IASTName[] names = DOMSearchUtil.getSelectedNamesFrom(file, ((TextSelection)sel).getOffset(), ((TextSelection)sel).getLength());
+                
+                if (names == null || names.length == 0)
+                    return null;
+
+				return names[0];
+            }
+        }
+        
+        return null;
+    }
+    
+    protected ISelection testF2Selection(IFile file, int offset) throws ParserException {
+    	return testF2Selection(file, offset, 0);
+    }
+    
+    protected ISelection testF2Selection(IFile file, int offset, int length) throws ParserException {
+		if (offset < 0)
+			throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$
+		
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        IEditorPart part = null;
+        try {
+            part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+            assertFalse(true);
+        }
+        
+        if (part instanceof AbstractTextEditor) {
+            ((AbstractTextEditor)part).getSelectionProvider().setSelection(new TextSelection(offset,length));
+            
+            final IAction action = ((AbstractTextEditor)part).getAction("OpenDefinition"); //$NON-NLS-1$
+            action.run();
+            
+        	// update the file/part to point to the newly opened IFile/IEditorPart
+            part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 
+            IEditorInput input = part.getEditorInput(); 
+            if (input instanceof FileEditorInput) {
+            	file = ((FileEditorInput)input).getFile();
+            } else {
+            	assertFalse(true); // bail!
+            }             
+        
+            // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU
+            return ((AbstractTextEditor)part).getSelectionProvider().getSelection();
+        }
+        
+        return null;
+    }
+    
+    public void resetIndexer(final String indexerId){
+		if ( project != null) {
+			ICDescriptorOperation op = new ICDescriptorOperation() {
+
+				public void execute(ICDescriptor descriptor, IProgressMonitor monitor) throws CoreException {
+						descriptor.remove(CCorePlugin.INDEXER_UNIQ_ID);
+						descriptor.create(CCorePlugin.INDEXER_UNIQ_ID,indexerId);
+				}
+			};
+			try {
+				CCorePlugin.getDefault().getCDescriptorManager().runDescriptorOperation(project, op, new NullProgressMonitor());
+				CCorePlugin.getDefault().getCoreModel().getIndexManager().indexerChangeNotification(project);
+			} catch (CoreException e) {}
+		}
+    }
+}
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsCTagsIndexer.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsCTagsIndexer.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsCTagsIndexer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsCTagsIndexer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,631 @@
+/**********************************************************************
+ * Copyright (c) 2005 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.ui.tests.text.selectiontests;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.index.ctagsindexer.CTagsIndexer;
+import org.eclipse.cdt.internal.core.index.sourceindexer.SourceIndexer;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+/**
+ * Test F2/F3 with the CTags Indexer for a CPP project.
+ * 
+ * @author dsteffle
+ */
+public class CPPSelectionTestsCTagsIndexer extends BaseSelectionTestsIndexer
+		implements IIndexChangeListener {
+
+	private static final String INDEX_TAG = "3931153591.index"; //$NON-NLS-1$
+	IFile 					file;
+	NullProgressMonitor		monitor;
+	IndexManager 			indexManager;
+	CTagsIndexer			sourceIndexer;
+
+	static final String sourceIndexerID = "org.eclipse.cdt.core.ctagsindexer"; //$NON-NLS-1$
+	
+	public CPPSelectionTestsCTagsIndexer(String name) {
+		super(name);
+	}
+	
+	protected void setUp() throws Exception {
+		super.setUp();
+		
+		//Create temp project
+		project = createProject("CPPSelectionTestsCTagsIndexerProject"); //$NON-NLS-1$
+		IPath pathLoc = CCorePlugin.getDefault().getStateLocation();
+		
+		File indexFile = new File(pathLoc.append(INDEX_TAG).toOSString());
+		if (indexFile.exists())
+			indexFile.delete();
+		
+		//Set the id of the source indexer extension point as a session property to allow
+		//index manager to instantiate it
+		project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);
+		
+		//Enable indexing on test project
+		project.setSessionProperty(SourceIndexer.activationKey,new Boolean(true));
+		
+		if (project==null)
+			fail("Unable to create project");	 //$NON-NLS-1$
+		
+		indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+		
+		resetIndexer(sourceIndexerID); // set indexer
+		
+		//indexManager.reset();
+		//Get the indexer used for the test project
+		sourceIndexer = (CTagsIndexer) indexManager.getIndexerForProject(project);
+		sourceIndexer.addIndexChangeListener(this);
+	}
+
+	protected void tearDown() {
+		try {
+			super.tearDown();
+			sourceIndexer.removeIndexChangeListener(this);
+		} catch (Exception e1) {
+		}
+		//Delete project
+		if (project.exists()) {
+			try {
+				System.gc();
+				System.runFinalization();
+				project.delete(true, monitor);
+			} catch (CoreException e) {
+				fail(getMessage(e.getStatus()));
+			}
+		}
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CPPSelectionTestsCTagsIndexer.class.getName());
+
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testSimpleOpenDeclaration")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testSimpleOpenDeclaration2")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testBasicDefinition")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testCPPSpecDeclsDefs")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testNoDefinitions")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsCTagsIndexer("testOpenFileDiffDir")); //$NON-NLS-1$
+	
+		return suite;
+	}
+
+	private IProject createProject(String projectName) throws CoreException {
+		ICProject cPrj = CProjectHelper.createCCProject(projectName, "bin"); //$NON-NLS-1$
+		return cPrj.getProject();
+	}
+	
+	public void testSimpleOpenDeclaration() throws Exception {
+		String header = "char c; /* comment */ \n // comment \nint x;\n"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "#include \"test.h\"\nint foo() { \n return x;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.cpp", code); //$NON-NLS-1$
+		
+		int offset = code.indexOf("x;\n}\n"); //$NON-NLS-1$
+		IASTNode def = testF2(file, offset); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(def instanceof IASTName);
+		assertEquals(((ASTNode)def).getOffset(), header.indexOf("x;\n"));
+		assertEquals(((ASTNode)def).getLength(), "x".length());
+		IASTNode decl = testF3(file, offset);
+		if (decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("x;\n"));
+		assertEquals(((ASTNode)decl).getLength(), "x".length());
+	}
+
+	public void testSimpleOpenDeclaration2() throws Exception {
+		String header = "int x;\r\n // comment \r\nint y;\r\n /* comment */ \r\n int z;\r\n"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "#include \"test.h\"\r\nint foo() { \r\n return y;\r\n}\r\n"; //$NON-NLS-1$
+		IFile file = importFile("test.cpp", code); //$NON-NLS-1$
+		
+		int offset = code.indexOf("y;"); //$NON-NLS-1$
+		IASTNode def = testF2(file, offset); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(def instanceof IASTName);
+		assertEquals(((ASTNode)def).getOffset(), header.indexOf("y;"));
+		assertEquals(((ASTNode)def).getLength(), "y".length());
+		IASTNode decl = testF3(file, offset);
+		assertTrue(decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("y;"));
+		assertEquals(((ASTNode)decl).getLength(), "y".length());		
+	}
+	
+	// perform the tests from CSelectionTestsNoIndexer and make sure they work with an indexer as well:
+    public void testBasicDefinition() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("extern int MyInt;       // MyInt is in another file\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst;   // MyConst is in another file\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int);       // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct;        // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("typedef int NewInt;     // a normal typedef statement\n"); //$NON-NLS-1$
+        buffer.append("int MyInt;\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("testBasicDefinition.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 5);
+        assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 276);
+        assertEquals(((ASTNode)def).getLength(), 5);
+        
+        offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 69);
+        assertEquals(((ASTNode)decl).getLength(), 7);
+        assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 300);
+        assertEquals(((ASTNode)def).getLength(), 7);
+        
+        offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 115);
+        assertEquals(((ASTNode)decl).getLength(), 6);
+        assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 319);
+        assertEquals(((ASTNode)def).getLength(), 6);
+        
+        offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 171);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 363);
+        assertEquals(((ASTNode)def).getLength(), 8);
+    }
+    
+	// taken from C++ spec 3.1-3:
+	/*
+	// all but one of the following are definitions:
+	int a; // defines a
+	extern const int c = 1; // defines c
+	int f(int x) { return x+a; } // defines f and defines x
+	struct S { int a; int b; }; // defines S, S::a, and S::b
+	struct X { // defines X
+		int x; // defines nonstatic data member x
+	};
+	enum { up, down }; // defines up and down
+	struct X anX; // defines anX
+	// whereas these are just declarations:
+	extern int a; // declares a
+	extern const int c; // declares c
+	int f(int); // declares f
+	struct S; // declares S
+	typedef int Int; // declares Int
+	extern struct X anotherX; // declares anotherX
+	*/
+	public void testCPPSpecDeclsDefs() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+        buffer.append("int a; // defines a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$
+        buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$
+        buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$
+        buffer.append("struct X { // defines X\n"); //$NON-NLS-1$
+        buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$
+        buffer.append("struct X anX; // defines anX\n"); //$NON-NLS-1$
+        buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$
+        buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$
+        buffer.append("struct S; // declares S\n"); //$NON-NLS-1$
+        buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+        buffer.append("extern struct X anotherX; // declares anotherX\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testCPPSpecDeclsDefs.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 135);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 135);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X { // defines X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 198);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 198);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 246);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 246);
+        assertEquals(((ASTNode)def).getLength(), 2);
+		
+		offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 250);
+        assertEquals(((ASTNode)decl).getLength(), 4);
+        assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 250);
+        assertEquals(((ASTNode)def).getLength(), 4);
+		
+		offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 290);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+        assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 290);
+        assertEquals(((ASTNode)def).getLength(), 3);
+		
+		offset = code.indexOf("a; // declares a"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 434);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 434);
+        assertEquals(((ASTNode)def).getLength(), 3);
+        
+		offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 471);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+	}
+	
+	public void testNoDefinitions() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$
+		buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$
+		buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$
+		buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$
+		buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testNoDefinitions.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 46);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 68);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96690
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 98);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 3);
+	}
+	
+	public void testOpenFileDiffDir() throws Exception {
+		importFolder("test"); //$NON-NLS-1$
+		String header = "int x;\r\n // comment \r\n int y; /* comment */ \r\n int z; \r\n"; //$NON-NLS-1$
+		importFile("test/test.h", header); //$NON-NLS-1$
+		String code = "#include \"test\\test.h\"\r\nint foo() { \r\n return y;\r\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.cpp", code);
+		
+		int offset = code.indexOf("y;"); //$NON-NLS-1$
+		IASTNode def = testF2(file, offset); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		assertTrue(def instanceof IASTName);
+		assertEquals(((ASTNode)def).getOffset(), header.indexOf("y;"));
+		assertEquals(((ASTNode)def).getLength(), "y".length());
+		IASTNode decl = testF3(file, offset);
+		if (decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("y;"));
+		assertEquals(((ASTNode)decl).getLength(), "y".length());
+		
+	}
+	
+    // REMINDER: see CSelectionTestsCTagsIndexer#suite() when appending new tests to this suite
+
+}
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsDOMIndexer.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsDOMIndexer.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsDOMIndexer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/CPPSelectionTestsDOMIndexer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,987 @@
+/**********************************************************************
+ * Copyright (c) 2005 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.ui.tests.text.selectiontests;
+
+import java.io.File;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.index.sourceindexer.SourceIndexer;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+/**
+ * Test F2/F3 with the DOM Indexer for a C++ project.
+ *  
+ * @author dsteffle
+ */
+public class CPPSelectionTestsDOMIndexer extends BaseSelectionTestsIndexer implements IIndexChangeListener {
+	private static final String INDEX_TAG = "1196338025.index"; //$NON-NLS-1$ // TODO Devin need to update this!
+	IFile 					file;
+	NullProgressMonitor		monitor;
+	IndexManager 			indexManager;
+	SourceIndexer			sourceIndexer;
+
+	static final String sourceIndexerID = "org.eclipse.cdt.core.domsourceindexer"; //$NON-NLS-1$
+	
+	public CPPSelectionTestsDOMIndexer(String name) {
+		super(name);
+	}
+	
+	protected void setUp() throws Exception {
+		super.setUp();
+		
+		//Create temp project
+		project = createProject("CPPSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
+		IPath pathLoc = CCorePlugin.getDefault().getStateLocation();
+		
+		File indexFile = new File(pathLoc.append(INDEX_TAG).toOSString());
+		if (indexFile.exists())
+			indexFile.delete();
+		
+		//Set the id of the source indexer extension point as a session property to allow
+		//index manager to instantiate it
+		project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);
+		
+		//Enable indexing on test project
+		project.setSessionProperty(SourceIndexer.activationKey,new Boolean(true));
+		
+		if (project==null)
+			fail("Unable to create project");	 //$NON-NLS-1$
+		
+		indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+
+		resetIndexer(sourceIndexerID); // set indexer
+		
+		//indexManager.reset();
+		//Get the indexer used for the test project
+		sourceIndexer = (SourceIndexer) indexManager.getIndexerForProject(project);
+		sourceIndexer.addIndexChangeListener(this);
+	}
+
+	protected void tearDown() {
+		try {
+			super.tearDown();
+			sourceIndexer.removeIndexChangeListener(this);
+		} catch (Exception e1) {
+		}
+		//Delete project
+		if (project.exists()) {
+			try {
+				System.gc();
+				System.runFinalization();
+				project.delete(true, monitor);
+			} catch (CoreException e) {
+				fail(getMessage(e.getStatus()));
+			}
+		}
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CPPSelectionTestsDOMIndexer.class.getName());
+
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug93281")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBasicDefinition")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug95224")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBasicTemplateInstance")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug86829A")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug86829B")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testCPPSpecDeclsDefs")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug95225")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testNoDefinitions")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug95202")); //$NON-NLS-1$
+		suite.addTest(new CPPSelectionTestsDOMIndexer("testBug95229")); //$NON-NLS-1$
+	
+		return suite;
+	}
+
+	private IProject createProject(String projectName) throws CoreException {
+		ICProject cPrj = CProjectHelper.createCCProject(projectName, "bin"); //$NON-NLS-1$
+		return cPrj.getProject();
+	}
+	
+    public void testBug93281() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("class Point{                         \n"); //$NON-NLS-1$
+        buffer.append("public:                              \n"); //$NON-NLS-1$
+        buffer.append("Point(): xCoord(0){}                 \n"); //$NON-NLS-1$
+        buffer.append("Point& operator=(const Point &rhs){return *this;}    // line A\n"); //$NON-NLS-1$
+        buffer.append("void* operator new [ ] (unsigned int);\n"); //$NON-NLS-1$
+        buffer.append("private:                             \n"); //$NON-NLS-1$
+        buffer.append("int xCoord;                          \n"); //$NON-NLS-1$
+        buffer.append("};                                   \n"); //$NON-NLS-1$
+        buffer.append("static const Point zero;\n"); //$NON-NLS-1$
+        buffer.append("int main(int argc, char **argv) {        \n"); //$NON-NLS-1$
+        buffer.append("Point *p2 = new Point();         \n"); //$NON-NLS-1$
+        buffer.append("p2->    operator // /* operator */ // F3 in the middle \n"); //$NON-NLS-1$
+        buffer.append("//of \"operator\" should work\n"); //$NON-NLS-1$
+        buffer.append("// \\n"); //$NON-NLS-1$
+        buffer.append("/* */\n"); //$NON-NLS-1$
+        buffer.append("=(zero);           // line B\n"); //$NON-NLS-1$
+        buffer.append("p2->operator /* oh yeah */ new // F3 in the middle of \"operator\"\n"); //$NON-NLS-1$
+        buffer.append("// should work\n"); //$NON-NLS-1$
+        buffer.append("//\n"); //$NON-NLS-1$
+        buffer.append("[ /* sweet */ ] //\n"); //$NON-NLS-1$
+        buffer.append("(2);\n"); //$NON-NLS-1$
+        buffer.append("return (0);                          \n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("test93281.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("p2->operator") + 6; //$NON-NLS-1$
+        IASTNode node = testF3(file, offset);
+        
+        assertTrue(node instanceof IASTName);
+        assertEquals(((IASTName)node).toString(), "operator new[]"); //$NON-NLS-1$
+        assertEquals(((ASTNode)node).getOffset(), 183);
+        assertEquals(((ASTNode)node).getLength(), 16);
+        
+        offset = code.indexOf("p2->    operator") + 11; //$NON-NLS-1$
+        node = testF3(file, offset);
+        
+        assertTrue(node instanceof IASTName);
+        assertEquals(((IASTName)node).toString(), "operator ="); //$NON-NLS-1$
+        assertEquals(((ASTNode)node).getOffset(), 121);
+        assertEquals(((ASTNode)node).getLength(), 9);
+        
+    }
+        
+    public void testBasicDefinition() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("extern int MyInt;       // MyInt is in another file\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst;   // MyConst is in another file\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int);       // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct;        // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("typedef int NewInt;     // a normal typedef statement\n"); //$NON-NLS-1$
+        buffer.append("class MyClass;          // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("int MyInt;\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$
+        buffer.append("class MyClass { int MemberVar; };\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("testBasicDefinition.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 5);
+        assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 330);
+        assertEquals(((ASTNode)def).getLength(), 5);
+        
+        offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 69);
+        assertEquals(((ASTNode)decl).getLength(), 7);
+        assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 354);
+        assertEquals(((ASTNode)def).getLength(), 7);
+        
+        offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 115);
+        assertEquals(((ASTNode)decl).getLength(), 6);
+        assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 373);
+        assertEquals(((ASTNode)def).getLength(), 6);
+        
+        offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 171);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 417);
+        assertEquals(((ASTNode)def).getLength(), 8);
+        
+        offset = code.indexOf("MyClass {") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyClass"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 278);
+        assertEquals(((ASTNode)decl).getLength(), 7);
+        assertEquals(((IASTName)def).toString(), "MyClass"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 463);
+        assertEquals(((ASTNode)def).getLength(), 7);
+    }
+    
+	public void testBug95224() throws Exception{
+	    Writer writer = new StringWriter();
+	    writer.write( "class A{\n"); //$NON-NLS-1$
+	    writer.write( "A();\n"); //$NON-NLS-1$
+	    writer.write( "A(const A&); // open definition on A finds class A\n"); //$NON-NLS-1$
+	    writer.write( "~A(); // open definition on A finds nothing\n"); //$NON-NLS-1$
+	    writer.write( "};\n"); //$NON-NLS-1$
+		
+		String code = writer.toString();
+		IFile file = importFile("testBug95224.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("A(); // open definition "); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "~A"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 65);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "A"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 6);
+        assertEquals(((ASTNode)def).getLength(), 1);
+	}
+	
+	public void testBasicTemplateInstance() throws Exception{
+	    Writer writer = new StringWriter();
+	    writer.write( "namespace N{                               \n"); //$NON-NLS-1$
+	    writer.write( "   template < class T > class AAA { T _t; };\n"); //$NON-NLS-1$
+	    writer.write( "};                                         \n"); //$NON-NLS-1$
+	    writer.write( "N::AAA<int> a;                             \n"); //$NON-NLS-1$
+	    
+		String code = writer.toString();
+		IFile file = importFile("testBasicTemplateInstance.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("AAA<int>"); //$NON-NLS-1$
+        IASTNode def1 = testF2(file, offset, 3);
+        IASTNode decl1 = testF3(file, offset, 3);
+        assertTrue(def1 instanceof IASTName);
+        assertTrue(decl1 instanceof IASTName);
+        assertEquals(((IASTName)decl1).toString(), "AAA"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl1).getOffset(), 74);
+        assertEquals(((ASTNode)decl1).getLength(), 3);
+        assertEquals(((IASTName)def1).toString(), "AAA"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def1).getOffset(), 74);
+        assertEquals(((ASTNode)def1).getLength(), 3);
+		
+		IASTNode def2 = testF2(file, offset, 8);
+        IASTNode decl2 = testF3(file, offset, 8);
+        assertTrue(def2 instanceof IASTName);
+        assertTrue(decl2 instanceof IASTName);
+        assertEquals(((IASTName)decl2).toString(), "AAA"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl2).getOffset(), 74);
+        assertEquals(((ASTNode)decl2).getLength(), 3);
+        assertEquals(((IASTName)def2).toString(), "AAA"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def2).getOffset(), 74);
+        assertEquals(((ASTNode)def2).getLength(), 3);
+	}
+	
+	public void testBug86829A() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("class X {\n"); //$NON-NLS-1$
+        buffer.append("public:\n"); //$NON-NLS-1$
+        buffer.append("X(int); // openReferences fails to find the constructor in g()\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("X f(X);\n"); //$NON-NLS-1$
+        buffer.append("void g()\n"); //$NON-NLS-1$
+        buffer.append("{\n"); //$NON-NLS-1$
+        buffer.append("X b = f(X(2)); // openDeclarations on X(int) finds the class and not \n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+
+		String code = buffer.toString();
+        IFile file = importFile("testBug86829A.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("X(2)"); //$NON-NLS-1$
+        IASTNode decl = testF3(file, offset);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 18);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+	}
+	
+	public void testBug86829B() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("class X {\n"); //$NON-NLS-1$
+        buffer.append("public:\n"); //$NON-NLS-1$
+        buffer.append("operator int();\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("class Y {\n"); //$NON-NLS-1$
+        buffer.append("public:\n"); //$NON-NLS-1$
+        buffer.append("operator X();\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("Y a;\n"); //$NON-NLS-1$
+        buffer.append("int c = X(a); // OK: a.operator X().operator int()\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testBug86829B.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("X(a);"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 6);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 6);
+        assertEquals(((ASTNode)def).getLength(), 1);
+	}
+	
+	// taken from C++ spec 3.1-3:
+	/*
+	// all but one of the following are definitions:
+	int a; // defines a
+	extern const int c = 1; // defines c
+	int f(int x) { return x+a; } // defines f and defines x
+	struct S { int a; int b; }; // defines S, S::a, and S::b
+	struct X { // defines X
+		int x; // defines nonstatic data member x
+		static int y; // declares static data member y
+		X(): x(0) { } // defines a constructor of X
+	};
+	int X::y = 1; // defines X::y
+	enum { up, down }; // defines up and down
+	namespace N { int d; } // defines N and N::d
+	namespace N1 = N; // defines N1
+	X anX; // defines anX
+	// whereas these are just declarations:
+	extern int a; // declares a
+	extern const int c; // declares c
+	int f(int); // declares f
+	struct S; // declares S
+	typedef int Int; // declares Int
+	extern X anotherX; // declares anotherX
+	using N::d; // declares N::d
+	*/
+	public void testCPPSpecDeclsDefs() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+        buffer.append("int a; // defines a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$
+        buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$
+        buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$
+        buffer.append("struct X { // defines X\n"); //$NON-NLS-1$
+        buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$
+        buffer.append("static int y; // declares static data member y\n"); //$NON-NLS-1$
+        buffer.append("X(): x(0) { } // defines a constructor of X\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("int X::y = 1; // defines X::y\n"); //$NON-NLS-1$
+        buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$
+        buffer.append("namespace N { int d; } // defines N and N::d\n"); //$NON-NLS-1$
+        buffer.append("namespace N1 = N; // defines N1\n"); //$NON-NLS-1$
+        buffer.append("X anX; // defines anX\n"); //$NON-NLS-1$
+        buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$
+        buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$
+        buffer.append("struct S; // declares S\n"); //$NON-NLS-1$
+        buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+        buffer.append("extern X anotherX; // declares anotherX\n"); //$NON-NLS-1$
+        buffer.append("using N::d; // declares N::d\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testCPPSpecDeclsDefs.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 135);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 135);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X { // defines X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 198);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 198);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("y; // declares static data member y"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "y"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 247);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "y"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 337);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X(): x(0) { } // defines a constructor of X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 283);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 283);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x(0) { } // defines a constructor of X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 198);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 198);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X::y = 1; // defines X::y"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("y = 1; // defines X::y"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "y"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 247);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "y"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 337);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 367);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 367);
+        assertEquals(((ASTNode)def).getLength(), 2);
+		
+		offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 371);
+        assertEquals(((ASTNode)decl).getLength(), 4);
+        assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 371);
+        assertEquals(((ASTNode)def).getLength(), 4);
+		
+		offset = code.indexOf("N { int d; } // defines N and N::d"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 412);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 412);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("d; } // defines N and N::d"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "d"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 420);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "d"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 420);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("N1 = N; // defines N1"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "N1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 457);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "N1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 457);
+        assertEquals(((ASTNode)def).getLength(), 2);
+		
+		offset = code.indexOf("N; // defines N1"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 412);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 412);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 481);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+        assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 481);
+        assertEquals(((ASTNode)def).getLength(), 3);
+		
+		offset = code.indexOf("a; // declares a"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 625);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+        
+		offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 655);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        		
+		offset = code.indexOf("N::d; // declares N::d"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 412);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "N"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 412);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("d; // declares N::d"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "d"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 420);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "d"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 420);
+        assertEquals(((ASTNode)def).getLength(), 1);
+	}
+	
+	public void testBug95225() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("class Overflow {\n"); //$NON-NLS-1$
+        buffer.append("public:\n"); //$NON-NLS-1$
+        buffer.append("Overflow(char,double,double);\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("void f(double x)\n"); //$NON-NLS-1$
+        buffer.append("{\n"); //$NON-NLS-1$
+        buffer.append("throw Overflow('+',x,3.45e107);\n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+        buffer.append("int foo() {\n"); //$NON-NLS-1$
+        buffer.append("try {\n"); //$NON-NLS-1$
+        buffer.append("f(1.2);\n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+        buffer.append("catch(Overflow& oo) {\n"); //$NON-NLS-1$
+        buffer.append("				// handle exceptions of type Overflow here\n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testBug95225.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("rflow('+',x,3.45e107);"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Overflow"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 25);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        assertEquals(((IASTName)def).toString(), "Overflow"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 6);
+        assertEquals(((ASTNode)def).getLength(), 8);
+        
+		offset = code.indexOf("x,3.45e107);"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 72);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 72);
+        assertEquals(((ASTNode)def).getLength(), 1);
+    }
+	
+	public void testNoDefinitions() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$
+		buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$
+		buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$
+		buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$
+		buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testNoDefinitions.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96694
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 46);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 68);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 98);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+	}
+    
+    public void testBug95202() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("struct A { }; // implicitlydeclared A::operator=\n"); //$NON-NLS-1$
+        buffer.append("struct B : A {\n"); //$NON-NLS-1$
+        buffer.append("B& operator=(const B &);\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("B& B::operator=(const B& s) {\n"); //$NON-NLS-1$
+        buffer.append("this->B::operator=(s); // wellformed\n"); //$NON-NLS-1$
+        buffer.append("return *this;\n"); //$NON-NLS-1$
+        buffer.append("}\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("testBug95202.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("s); // wellformed"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "s"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 117);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "s"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 117);
+        assertEquals(((ASTNode)def).getLength(), 1);
+        
+    }
+    
+    public void testBug95229() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("struct A {\n"); //$NON-NLS-1$
+        buffer.append("operator short(); // F3 on operator causes an infinite loop\n"); //$NON-NLS-1$
+        buffer.append("} a;\n"); //$NON-NLS-1$
+        buffer.append("int f(int);\n"); //$NON-NLS-1$
+        buffer.append("int f(float);\n"); //$NON-NLS-1$
+        buffer.append("int i = f(a); // Calls f(int), because short -> int is\n"); //$NON-NLS-1$
+                
+        String code = buffer.toString();
+        IFile file = importFile("testBug95229.cpp", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("rator short(); // F3"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "operator short"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 14);
+    }
+
+    // REMINDER: see CPPSelectionTestsDomIndexer#suite() when appending new tests to this suite
+}
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsCTagsIndexer.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsCTagsIndexer.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsCTagsIndexer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsCTagsIndexer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,639 @@
+/**********************************************************************
+ * Copyright (c) 2005 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.ui.tests.text.selectiontests;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.index.ctagsindexer.CTagsIndexer;
+import org.eclipse.cdt.internal.core.index.sourceindexer.SourceIndexer;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * Test F2/F3 with the CTags Indexer for a C project.
+ * 
+ * @author dsteffle
+ */
+public class CSelectionTestsCTagsIndexer extends BaseSelectionTestsIndexer
+		implements IIndexChangeListener {
+
+	private static final String INDEX_TAG = "3931153591.index"; //$NON-NLS-1$
+	IFile 					file;
+	NullProgressMonitor		monitor;
+	IndexManager 			indexManager;
+	CTagsIndexer			sourceIndexer;
+
+	static final String sourceIndexerID = "org.eclipse.cdt.core.ctagsindexer"; //$NON-NLS-1$
+	
+	public CSelectionTestsCTagsIndexer(String name) {
+		super(name);
+	}
+	
+	protected void setUp() throws Exception {
+		super.setUp();
+		
+		//Create temp project
+		project = createProject("CSelectionTestsCTagsIndexerProject"); //$NON-NLS-1$
+		IPath pathLoc = CCorePlugin.getDefault().getStateLocation();
+		
+		File indexFile = new File(pathLoc.append(INDEX_TAG).toOSString());
+		if (indexFile.exists())
+			indexFile.delete();
+		
+		//Set the id of the source indexer extension point as a session property to allow
+		//index manager to instantiate it
+		project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);
+		
+		//Enable indexing on test project
+		project.setSessionProperty(SourceIndexer.activationKey,new Boolean(true));
+		
+		if (project==null)
+			fail("Unable to create project");	 //$NON-NLS-1$
+		
+		indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+		
+		resetIndexer(sourceIndexerID); // set indexer
+		
+		//indexManager.reset();
+		//Get the indexer used for the test project
+		sourceIndexer = (CTagsIndexer) indexManager.getIndexerForProject(project);
+		sourceIndexer.addIndexChangeListener(this);
+	}
+
+	protected void tearDown() {
+		try {
+			super.tearDown();
+			sourceIndexer.removeIndexChangeListener(this);
+		} catch (Exception e1) {
+		}
+		//Delete project
+		if (project.exists()) {
+			try {
+				System.gc();
+				System.runFinalization();
+				project.delete(true, monitor);
+			} catch (CoreException e) {
+				fail(getMessage(e.getStatus()));
+			}
+		}
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CSelectionTestsCTagsIndexer.class.getName());
+
+		suite.addTest(new CSelectionTestsCTagsIndexer("testSimpleOpenDeclaration")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsCTagsIndexer("testSimpleOpenDeclaration2")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsCTagsIndexer("testBasicDefinition")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsCTagsIndexer("testCPPSpecDeclsDefs")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsCTagsIndexer("testNoDefinitions")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsCTagsIndexer("testOpenFileDiffDir")); //$NON-NLS-1$
+	
+		return suite;
+	}
+
+	private IProject createProject(String projectName) throws CoreException {
+		ICProject cPrj = CProjectHelper.createCCProject(projectName, "bin"); //$NON-NLS-1$
+		return cPrj.getProject();
+	}
+	
+	public void testSimpleOpenDeclaration() throws Exception {
+		String header = "char c; /* comment */ \n // comment \nint x;\n"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return x;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code); //$NON-NLS-1$
+		
+		int offset = code.indexOf("x;\n}\n"); //$NON-NLS-1$
+		ISelection def = testF2Selection(file, offset); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		if (def instanceof TextSelection) {
+			assertEquals(((TextSelection)def).getOffset(), header.indexOf("int x;\n"));
+			assertEquals(((TextSelection)def).getLength(), "int x;\n".length());
+		}
+		ISelection decl = testF3Selection(file, offset);
+		if (decl instanceof TextSelection) {
+			assertEquals(((TextSelection)decl).getOffset(), header.indexOf("int x;\n"));
+			assertEquals(((TextSelection)decl).getLength(), "int x;\n".length());
+		}
+	}
+
+	public void testSimpleOpenDeclaration2() throws Exception {
+		String header = "int x;\r\n // comment \r\nint y;\r\n /* comment */ \r\n int z;\r\n"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return y;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code); //$NON-NLS-1$
+		
+		int offset = code.indexOf("y;\n}\n"); //$NON-NLS-1$
+		ISelection def = testF2Selection(file, offset);
+		if (def instanceof TextSelection) {
+			assertEquals(((TextSelection)def).getOffset(), header.indexOf("int y;\r\n"));
+			assertEquals(((TextSelection)def).getLength(), "int y;\r\n".length());
+		}
+		ISelection decl = testF3Selection(file, offset);
+		if (decl instanceof TextSelection) {
+			assertEquals(((TextSelection)decl).getOffset(), header.indexOf("int y;\r\n"));
+			assertEquals(((TextSelection)decl).getLength(), "int y;\r\n".length());
+		}		
+	}
+	
+	// perform the tests from CSelectionTestsNoIndexer and make sure they work with an indexer as well:
+    public void testBasicDefinition() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("extern int MyInt;       // MyInt is in another file\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst;   // MyConst is in another file\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int);       // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct;        // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("typedef int NewInt;     // a normal typedef statement\n"); //$NON-NLS-1$
+        buffer.append("int MyInt;\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("testBasicDefinition.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 5);
+        assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 276);
+        assertEquals(((ASTNode)def).getLength(), 5);
+        
+        offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 69);
+        assertEquals(((ASTNode)decl).getLength(), 7);
+        assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 300);
+        assertEquals(((ASTNode)def).getLength(), 7);
+        
+        offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 115);
+        assertEquals(((ASTNode)decl).getLength(), 6);
+        assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 319);
+        assertEquals(((ASTNode)def).getLength(), 6);
+        
+        offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 171);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 363);
+        assertEquals(((ASTNode)def).getLength(), 8);
+    }
+    
+	// taken from C++ spec 3.1-3:
+	/*
+	// all but one of the following are definitions:
+	int a; // defines a
+	extern const int c = 1; // defines c
+	int f(int x) { return x+a; } // defines f and defines x
+	struct S { int a; int b; }; // defines S, S::a, and S::b
+	struct X { // defines X
+		int x; // defines nonstatic data member x
+	};
+	enum { up, down }; // defines up and down
+	struct X anX; // defines anX
+	// whereas these are just declarations:
+	extern int a; // declares a
+	extern const int c; // declares c
+	int f(int); // declares f
+	struct S; // declares S
+	typedef int Int; // declares Int
+	extern struct X anotherX; // declares anotherX
+	*/
+	public void testCPPSpecDeclsDefs() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+        buffer.append("int a; // defines a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$
+        buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$
+        buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$
+        buffer.append("struct X { // defines X\n"); //$NON-NLS-1$
+        buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$
+        buffer.append("struct X anX; // defines anX\n"); //$NON-NLS-1$
+        buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$
+        buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$
+        buffer.append("struct S; // declares S\n"); //$NON-NLS-1$
+        buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+        buffer.append("extern struct X anotherX; // declares anotherX\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testCPPSpecDeclsDefs.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 135);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 135);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X { // defines X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 198);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 198);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 246);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 246);
+        assertEquals(((ASTNode)def).getLength(), 2);
+		
+		offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 250);
+        assertEquals(((ASTNode)decl).getLength(), 4);
+        assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 250);
+        assertEquals(((ASTNode)def).getLength(), 4);
+		
+		offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 290);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+        assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 290);
+        assertEquals(((ASTNode)def).getLength(), 3);
+		
+		offset = code.indexOf("a; // declares a"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 434);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 434);
+        assertEquals(((ASTNode)def).getLength(), 3);
+        
+		offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 471);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+	}
+	
+	public void testNoDefinitions() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$
+		buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$
+		buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$
+		buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$
+		buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testNoDefinitions.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 46);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 68);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96690
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 98);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 3);
+	}
+	
+	public void testOpenFileDiffDir() throws Exception {
+		importFolder("test"); //$NON-NLS-1$
+		String header = "int x;\r\n // comment \r\n int y; /* comment */ \r\n int z; \r\n"; //$NON-NLS-1$
+		importFile("test/test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return y;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code);
+		
+		int offset = code.indexOf("y;\n}\n"); //$NON-NLS-1$
+		ISelection def = testF2Selection(file, offset);
+		if (def instanceof TextSelection) {
+			assertEquals(((TextSelection)def).getOffset(), header.indexOf(" int y;")); //$NON-NLS-1$
+			assertEquals(((TextSelection)def).getLength(), " int y; /* comment */ \r\n".length()); //$NON-NLS-1$
+		}
+		ISelection decl = testF3Selection(file, offset);
+		if (def instanceof TextSelection) {
+			assertEquals(((TextSelection)decl).getOffset(), header.indexOf(" int y;")); //$NON-NLS-1$
+			assertEquals(((TextSelection)decl).getLength(), " int y; /* comment */ \r\n".length()); //$NON-NLS-1$
+		}
+		
+	}
+	
+    // REMINDER: see CSelectionTestsCTagsIndexer#suite() when appending new tests to this suite
+
+}
Index: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsDOMIndexer.java
===================================================================
RCS file: ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsDOMIndexer.java
diff -N ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsDOMIndexer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/cdt/ui/tests/text/selectiontests/CSelectionTestsDOMIndexer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,641 @@
+/**********************************************************************
+ * Copyright (c) 2005 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.ui.tests.text.selectiontests;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.index.sourceindexer.SourceIndexer;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+/**
+ * Test F2/F3 with the DOM Indexer for a C project.
+ * 
+ * @author dsteffle
+ */
+public class CSelectionTestsDOMIndexer extends BaseSelectionTestsIndexer implements IIndexChangeListener {
+	private static final String INDEX_TAG = "1161844423.index"; //$NON-NLS-1$
+	IFile 					file;
+	NullProgressMonitor		monitor;
+	IndexManager 			indexManager;
+	SourceIndexer			sourceIndexer;
+
+	static final String sourceIndexerID = "org.eclipse.cdt.core.domsourceindexer"; //$NON-NLS-1$
+	
+	public CSelectionTestsDOMIndexer(String name) {
+		super(name);
+	}
+	
+	protected void setUp() throws Exception {
+		super.setUp();
+		
+		//Create temp project
+		project = createProject("CSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
+		IPath pathLoc = CCorePlugin.getDefault().getStateLocation();
+		
+		File indexFile = new File(pathLoc.append(INDEX_TAG).toOSString());
+		if (indexFile.exists())
+			indexFile.delete();
+		
+		//Set the id of the source indexer extension point as a session property to allow
+		//index manager to instantiate it
+		project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);
+		
+		//Enable indexing on test project
+		project.setSessionProperty(SourceIndexer.activationKey,new Boolean(true));
+		
+		if (project==null)
+			fail("Unable to create project");	 //$NON-NLS-1$
+		
+		indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+
+		resetIndexer(sourceIndexerID); // set indexer
+		
+		//indexManager.reset();
+		//Get the indexer used for the test project
+		sourceIndexer = (SourceIndexer) indexManager.getIndexerForProject(project);
+		sourceIndexer.addIndexChangeListener(this);
+	}
+
+	protected void tearDown() {
+		try {
+			super.tearDown();
+			sourceIndexer.removeIndexChangeListener(this);
+		} catch (Exception e1) {
+		}
+		//Delete project
+		if (project.exists()) {
+			try {
+				System.gc();
+				System.runFinalization();
+				project.delete(true, monitor);
+			} catch (CoreException e) {
+				fail(getMessage(e.getStatus()));
+			}
+		}
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CSelectionTestsDOMIndexer.class.getName());
+
+		suite.addTest(new CSelectionTestsDOMIndexer("testSimpleOpenDeclaration")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsDOMIndexer("testSimpleOpenDeclaration2")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsDOMIndexer("testBasicDefinition")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsDOMIndexer("testCPPSpecDeclsDefs")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsDOMIndexer("testNoDefinitions")); //$NON-NLS-1$
+		suite.addTest(new CSelectionTestsDOMIndexer("testOpenFileDiffDir")); //$NON-NLS-1$
+	
+		return suite;
+	}
+
+	private IProject createProject(String projectName) throws CoreException {
+		ICProject cPrj = CProjectHelper.createCCProject(projectName, "bin"); //$NON-NLS-1$
+		return cPrj.getProject();
+	}
+	
+	public void testSimpleOpenDeclaration() throws Exception {
+		String header = "int x;"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return x;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code);
+		
+		int offset = code.indexOf("x;\n}\n");
+		IASTNode def = testF2(file, offset);
+		assertTrue(def instanceof IASTName);
+		try {
+			// TODO raised bug 97079
+			assertEquals(((ASTNode)def).getOffset(), header.indexOf("x")); //$NON-NLS-1$
+			assertTrue(false); // when this fails then the test is passing correctly
+		} catch (AssertionFailedError afe) {}
+		assertEquals(((ASTNode)def).getLength(), "x".length()); //$NON-NLS-1$
+		IASTNode decl = testF3(file, offset);
+		assertTrue(decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("x")); //$NON-NLS-1$
+		assertEquals(((ASTNode)decl).getLength(), "x".length()); //$NON-NLS-1$
+		
+	}
+
+	public void testSimpleOpenDeclaration2() throws Exception {
+		String header = "int x;\r\n // comment \r\n int y; /* comment */ \r\n int z; \r\n"; //$NON-NLS-1$
+		importFile("test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return y;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code);
+		
+		int offset = code.indexOf("y;\n}\n");
+		IASTNode def = testF2(file, offset);
+		assertTrue(def instanceof IASTName);
+		try {
+			// TODO raised bug 97079
+			assertEquals(((ASTNode)def).getOffset(), header.indexOf("y")); //$NON-NLS-1$
+			assertTrue(false); // when this fails then the test is passing correctly
+		} catch (AssertionFailedError afe) {}
+		assertEquals(((ASTNode)def).getLength(), "y".length()); //$NON-NLS-1$
+		IASTNode decl = testF3(file, offset);
+		assertTrue(decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("y")); //$NON-NLS-1$
+		assertEquals(((ASTNode)decl).getLength(), "y".length()); //$NON-NLS-1$
+		
+	}
+	
+	// perform the tests from CSelectionTestsNoIndexer and make sure they work with an indexer as well:
+    public void testBasicDefinition() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("extern int MyInt;       // MyInt is in another file\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst;   // MyConst is in another file\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int);       // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct;        // often used in header files\n"); //$NON-NLS-1$
+        buffer.append("typedef int NewInt;     // a normal typedef statement\n"); //$NON-NLS-1$
+        buffer.append("int MyInt;\n"); //$NON-NLS-1$
+        buffer.append("extern const int MyConst = 42;\n"); //$NON-NLS-1$
+        buffer.append("void MyFunc(int a) { cout << a << endl; }\n"); //$NON-NLS-1$
+        buffer.append("struct MyStruct { int Member1; int Member2; };\n"); //$NON-NLS-1$
+        
+        String code = buffer.toString();
+        IFile file = importFile("testBasicDefinition.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("MyInt;\n") + 2; //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 5);
+        assertEquals(((IASTName)def).toString(), "MyInt"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 276);
+        assertEquals(((ASTNode)def).getLength(), 5);
+        
+        offset = code.indexOf("MyConst = 42") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 69);
+        assertEquals(((ASTNode)decl).getLength(), 7);
+        assertEquals(((IASTName)def).toString(), "MyConst"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 300);
+        assertEquals(((ASTNode)def).getLength(), 7);
+        
+        offset = code.indexOf("MyFunc(int a)") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 115);
+        assertEquals(((ASTNode)decl).getLength(), 6);
+        assertEquals(((IASTName)def).toString(), "MyFunc"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 319);
+        assertEquals(((ASTNode)def).getLength(), 6);
+        
+        offset = code.indexOf("MyStruct {") + 2; //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 171);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+        assertEquals(((IASTName)def).toString(), "MyStruct"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 363);
+        assertEquals(((ASTNode)def).getLength(), 8);
+    }
+    
+	// taken from C++ spec 3.1-3:
+	/*
+	// all but one of the following are definitions:
+	int a; // defines a
+	extern const int c = 1; // defines c
+	int f(int x) { return x+a; } // defines f and defines x
+	struct S { int a; int b; }; // defines S, S::a, and S::b
+	struct X { // defines X
+		int x; // defines nonstatic data member x
+	};
+	enum { up, down }; // defines up and down
+	struct X anX; // defines anX
+	// whereas these are just declarations:
+	extern int a; // declares a
+	extern const int c; // declares c
+	int f(int); // declares f
+	struct S; // declares S
+	typedef int Int; // declares Int
+	extern struct X anotherX; // declares anotherX
+	*/
+	public void testCPPSpecDeclsDefs() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+        buffer.append("int a; // defines a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c = 1; // defines c\n"); //$NON-NLS-1$
+        buffer.append("int f(int x) { return x+a; } // defines f and defines x\n"); //$NON-NLS-1$
+        buffer.append("struct S { int a; int b; }; // defines S, S::a, and S::b\n"); //$NON-NLS-1$
+        buffer.append("struct X { // defines X\n"); //$NON-NLS-1$
+        buffer.append("int x; // defines nonstatic data member x\n"); //$NON-NLS-1$
+        buffer.append("};\n"); //$NON-NLS-1$
+        buffer.append("enum { up, down }; // defines up and down\n"); //$NON-NLS-1$
+        buffer.append("struct X anX; // defines anX\n"); //$NON-NLS-1$
+        buffer.append("extern int a; // declares a\n"); //$NON-NLS-1$
+        buffer.append("extern const int c; // declares c\n"); //$NON-NLS-1$
+        buffer.append("int f(int); // declares f\n"); //$NON-NLS-1$
+        buffer.append("struct S; // declares S\n"); //$NON-NLS-1$
+        buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+        buffer.append("extern struct X anotherX; // declares anotherX\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testCPPSpecDeclsDefs.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a; // defines a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c = 1; // defines c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x) { return x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x+a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 67);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 67);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; } // defines f and defines x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S { int a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("a; int b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("b; }; // defines S, S::a, and S::b"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 135);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "b"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 135);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("X { // defines X"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("x; // defines nonstatic data member x"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 198);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "x"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 198);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("up, down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 246);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+        assertEquals(((IASTName)def).toString(), "up"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 246);
+        assertEquals(((ASTNode)def).getLength(), 2);
+		
+		offset = code.indexOf("down }; // defines up and down"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 250);
+        assertEquals(((ASTNode)decl).getLength(), 4);
+        assertEquals(((IASTName)def).toString(), "down"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 250);
+        assertEquals(((ASTNode)def).getLength(), 4);
+		
+		offset = code.indexOf("X anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 290);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+        assertEquals(((IASTName)def).toString(), "anX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 290);
+        assertEquals(((ASTNode)def).getLength(), 3);
+		
+		offset = code.indexOf("a; // declares a"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 4);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "a"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 4);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("c; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 37);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "c"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 37);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("f(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 61);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "f"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 61);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("S; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 120);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "S"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 120);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 434);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 434);
+        assertEquals(((ASTNode)def).getLength(), 3);
+        
+		offset = code.indexOf("X anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 177);
+        assertEquals(((ASTNode)decl).getLength(), 1);
+        assertEquals(((IASTName)def).toString(), "X"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 177);
+        assertEquals(((ASTNode)def).getLength(), 1);
+		
+		offset = code.indexOf("anotherX; // declares anotherX"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "anotherX"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 471);
+        assertEquals(((ASTNode)decl).getLength(), 8);
+	}
+	
+	public void testNoDefinitions() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("extern int a1; // declares a\n"); //$NON-NLS-1$
+		buffer.append("extern const int c1; // declares c\n"); //$NON-NLS-1$
+		buffer.append("int f1(int); // declares f\n"); //$NON-NLS-1$
+		buffer.append("struct S1; // declares S\n"); //$NON-NLS-1$
+		buffer.append("typedef int Int; // declares Int\n"); //$NON-NLS-1$
+		
+        String code = buffer.toString();
+        IFile file = importFile("testNoDefinitions.c", code); //$NON-NLS-1$
+        
+        int offset = code.indexOf("a1; // declares a"); //$NON-NLS-1$
+        IASTNode def = testF2(file, offset);
+        IASTNode decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "a1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 11);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("c1; // declares c"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96689
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "c1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 46);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("f1(int); // declares f"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertNull(def);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "f1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 68);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("S1; // declares S"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        try {
+        	assertNull(def); // TODO raised bug 96690
+        	assertTrue(false); // try/catch/assertTrue(false) added to alert the tester when this test passes!
+        } catch (AssertionFailedError e) {}
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "S1"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 98);
+        assertEquals(((ASTNode)decl).getLength(), 2);
+		
+		offset = code.indexOf("Int; // declares Int"); //$NON-NLS-1$
+        def = testF2(file, offset);
+        decl = testF3(file, offset);
+        assertTrue(def instanceof IASTName);
+        assertTrue(decl instanceof IASTName);
+        assertEquals(((IASTName)decl).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)decl).getOffset(), 128);
+        assertEquals(((ASTNode)decl).getLength(), 3);
+		assertEquals(((IASTName)def).toString(), "Int"); //$NON-NLS-1$
+        assertEquals(((ASTNode)def).getOffset(), 128);
+        assertEquals(((ASTNode)def).getLength(), 3);
+	}
+	
+	public void testOpenFileDiffDir() throws Exception {
+		importFolder("test"); //$NON-NLS-1$
+		String header = "int x;\r\n // comment \r\n int y; /* comment */ \r\n int z; \r\n"; //$NON-NLS-1$
+		importFile("test/test.h", header); //$NON-NLS-1$
+		String code = "int foo() { \n return y;\n}\n"; //$NON-NLS-1$
+		IFile file = importFile("test.c", code);
+		
+		int offset = code.indexOf("y;\n}\n");
+		IASTNode def = testF2(file, offset);
+		assertTrue(def instanceof IASTName);
+		try {
+			// TODO raised bug 97079
+			assertEquals(((ASTNode)def).getOffset(), header.indexOf("y")); //$NON-NLS-1$
+			assertTrue(false); // when this fails then the test is passing correctly
+		} catch (AssertionFailedError afe) {}
+		assertEquals(((ASTNode)def).getLength(), "y".length()); //$NON-NLS-1$
+		IASTNode decl = testF3(file, offset);
+		assertTrue(decl instanceof IASTName);
+		assertEquals(((ASTNode)decl).getOffset(), header.indexOf("y")); //$NON-NLS-1$
+		assertEquals(((ASTNode)decl).getLength(), "y".length()); //$NON-NLS-1$
+		
+	}
+	
+    // REMINDER: see CSelectionTestsDomIndexer#suite() when appending new tests to this suite
+}

Back to the top