Index: org.codehaus.groovy.eclipse.codebrowsing/META-INF/MANIFEST.MF
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/META-INF/MANIFEST.MF	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/META-INF/MANIFEST.MF	(working copy)
@@ -5,10 +5,8 @@
 Bundle-Version: 1.5.1.qualifier
 Bundle-Activator: org.codehaus.groovy.eclipse.codebrowsing.GroovyBrowsingPlugin
 Bundle-Localization: plugin
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.resources,
+Require-Bundle: org.eclipse.core.resources,
  org.eclipse.jface,
- org.eclipse.ui,
  org.eclipse.text,
  org.eclipse.jface.text,
  org.eclipse.ui.workbench.texteditor,
@@ -18,7 +16,10 @@
  org.eclipse.ui.editors,
  org.codehaus.groovy.eclipse;bundle-version="1.5.1",
  org.codehaus.groovy.eclipse.ui,
- org.codehaus.groovy;bundle-version="1.1.0"
+ org.codehaus.groovy;bundle-version="1.1.0",
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.ui,
+ org.eclipse.ui.workbench
 Eclipse-LazyStart: true
 Export-Package: org.codehaus.groovy.eclipse.codebrowsing
 Bundle-Vendor: The Codehaus
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/TextUtils.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/TextUtils.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/TextUtils.java	(working copy)
@@ -18,11 +18,11 @@
 	public static int findIdentifierOffset(String text, String identifier) {
 		String notIdent = "[^a-zA-Z0-9_]";
 
-		Pattern pattern = Pattern.compile(notIdent + "(" + identifier + ")"
-				+ notIdent);
+		Pattern pattern = Pattern.compile("(^|" + notIdent + ")(" + identifier + ")("
+				+ notIdent + "|$)");
 		Matcher matcher = pattern.matcher(text);
 		if (matcher.find()) {
-			return matcher.start(1);
+			return matcher.start(2);
 		}
 		
 		return -1;
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/AbstractSourceCode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/AbstractSourceCode.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/AbstractSourceCode.java	(working copy)
@@ -1,6 +1,14 @@
 package org.codehaus.groovy.eclipse.codebrowsing;
 
+import org.codehaus.groovy.eclipse.GroovyPlugin;
 import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.IEditorDescriptor;
+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.texteditor.ITextEditor;
 
 /**
  * @see org.codehaus.groovy.eclipse.codebrowsing.ISourceCode
@@ -9,6 +17,10 @@
 public abstract class AbstractSourceCode implements ISourceCode {
 	private Object handle;
 	private IRegion region;
+	
+	public AbstractSourceCode(Object handle) {
+		this.handle = handle;
+	}
 
 	public AbstractSourceCode(Object handle, IRegion region) {
 		this.handle = handle;
@@ -22,4 +34,32 @@
 	public IRegion getRegionOfInterest() {
 		return region;
 	}
+
+	protected IEditorPart open(String fileName, IEditorInput editorInput) {
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench()
+					.getActiveWorkbenchWindow().getActivePage();
+			IEditorDescriptor desc = PlatformUI.getWorkbench()
+					.getEditorRegistry().getDefaultEditor(fileName);
+			try {
+				IEditorPart part = page.openEditor(editorInput,
+						desc.getId());
+				if (region != null && part instanceof ITextEditor) {
+					ITextEditor editor = (ITextEditor) part;
+					editor
+							.selectAndReveal(region.getOffset(), region
+									.getLength());
+				}
+				return part;
+			} catch (PartInitException e) {
+				// LOG: need own logging.
+				GroovyPlugin.getDefault().logException("Should not happen.", e);
+				e.printStackTrace();
+			}
+		} catch (NullPointerException e) {
+			// LOG: Rare case that somehow workbench or active window or
+			// page is null.
+		}
+		return null;
+	}
 }
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/impl/MethodCallExpressionProcessor.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/impl/MethodCallExpressionProcessor.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/impl/MethodCallExpressionProcessor.java	(working copy)
@@ -16,6 +16,7 @@
 import org.codehaus.groovy.eclipse.codebrowsing.IDeclarationSearchInfo;
 import org.codehaus.groovy.eclipse.codebrowsing.IDeclarationSearchProcessor;
 import org.codehaus.groovy.eclipse.codebrowsing.DeclarationProposal;
+import org.codehaus.groovy.eclipse.codebrowsing.SourceCodeFinder;
 import org.codehaus.groovy.eclipse.editor.actions.EditorPartFacade;
 import org.eclipse.jface.text.IRegion;
 
@@ -29,16 +30,22 @@
 		if (expr.getObjectExpression().getText().equals("this")) {
 			return createMethodCallProposal(DeclarationCategory.METHOD, info,
 					info.getClassNode(), expr);
-		} else {
-			String className = expr.getObjectExpression().getText();
-			for (Iterator iter = info.getModuleNode().getClasses().iterator(); iter
-					.hasNext();) {
-				ClassNode classNode = (ClassNode) iter.next();
-				if (className.endsWith(classNode.getName())) {
-					return createMethodCallProposal(
-							DeclarationCategory.STATIC_METHOD, info, classNode,
-							expr);
-				}
+		}
+		for (Iterator iter = expr.getObjectExpression().getType().getMethods(
+				info.getIdentifier()).iterator(); iter.hasNext();) {
+			MethodNode method = (MethodNode) iter.next();
+			return createMethodCallProposal(DeclarationCategory.METHOD, info,
+					expr.getObjectExpression().getType(), expr);
+		}
+
+		String className = expr.getObjectExpression().getText();
+		for (Iterator iter = info.getModuleNode().getClasses().iterator(); iter
+				.hasNext();) {
+			ClassNode classNode = (ClassNode) iter.next();
+			if (className.endsWith(classNode.getName())) {
+				return createMethodCallProposal(
+						DeclarationCategory.STATIC_METHOD, info, classNode,
+						expr);
 			}
 		}
 		return DeclarationProposal.NONE;
@@ -70,12 +77,18 @@
 				}
 
 				if (match == true) {
-					IRegion region = ASTUtils.getRegion(facade, methodNode,
-							info.getIdentifier().length());
-					if (region != null) {
+					if (expr.getObjectExpression().getText().equals("this")) {
+						IRegion region = ASTUtils.getRegion(facade, methodNode,
+								info.getIdentifier().length());
+						if (region != null) {
+							results.add(new DeclarationProposal(category, ASTUtils
+									.createDisplayString(methodNode),
+									new FileSourceCode(facade.getFile(), region)));
+						}
+					} else {
 						results.add(new DeclarationProposal(category, ASTUtils
 								.createDisplayString(methodNode),
-								new FileSourceCode(facade.getFile(), region)));
+								SourceCodeFinder.find(classNode, methodNode)));
 					}
 				}
 			}
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/ClassFileSourceCode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/ClassFileSourceCode.java	(revision 0)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/ClassFileSourceCode.java	(revision 0)
@@ -0,0 +1,24 @@
+package org.codehaus.groovy.eclipse.codebrowsing;
+
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.ui.javaeditor.InternalClassFileEditorInput;
+import org.eclipse.ui.IEditorPart;
+
+public class ClassFileSourceCode extends JavaSourceCode {
+
+	public ClassFileSourceCode(IClassFile handle) {
+		super(handle);
+	}
+
+	public ClassFileSourceCode(IClassFile handle, IJavaElement element) {
+		super(handle, element);
+	}
+
+	public boolean open() {
+		IClassFile classFile = (IClassFile) getSourceHandle();
+		IEditorPart editor = open(classFile.getElementName(), new InternalClassFileEditorInput(classFile));
+		return editor != null;
+	}
+
+}
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/astfinders/FindASTNode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/astfinders/FindASTNode.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/astfinders/FindASTNode.java	(working copy)
@@ -5,8 +5,10 @@
 
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
+import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.ImportNode;
 import org.codehaus.groovy.ast.ModuleNode;
 import org.codehaus.groovy.ast.expr.ClassExpression;
 import org.codehaus.groovy.ast.expr.Expression;
@@ -18,6 +20,8 @@
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.eclipse.codebrowsing.ASTUtils;
+import org.codehaus.groovy.eclipse.codebrowsing.SourceCodeFinder;
+import org.codehaus.groovy.eclipse.core.model.GroovyModel;
 
 /**
  * Given an identifier and its location in the document, find the ASTNode that
@@ -138,7 +142,7 @@
 
 	public void visitMethodCallExpression(MethodCallExpression call) {
 		if (validCoords(call)) {
-			if (identifier.equals(call.getMethod())) {
+			if (identifier.equals(call.getMethod().getText())) {
 				System.out.println("Method call: " + call.getMethod());
 				// Strange - columns can be equal sometimes
 				if (call.getLineNumber() == call.getLastLineNumber()
@@ -198,6 +202,25 @@
 								interfaceNodes[i], identifier, line, column);
 					}
 				}
+				
+				for (Iterator iterator = moduleNode.getImports().iterator();
+						iterator.hasNext();) {
+					ImportNode importNode = (ImportNode) iterator.next();
+					if (identifier.equals(importNode.getAlias())) {
+						throw new ASTNodeFoundException(moduleNode, classNode,
+								importNode.getType(), identifier, line, column);
+					}
+				}
+				
+				for (Iterator iterator = moduleNode.getImportPackages().iterator();
+						iterator.hasNext();) {
+					String packageName = (String) iterator.next();
+					ClassNode possibleClassNode = ClassHelper.makeWithoutCaching(packageName + identifier);
+					if (SourceCodeFinder.find(possibleClassNode) != null) {
+						throw new ASTNodeFoundException(moduleNode, classNode,
+								possibleClassNode, identifier, line, column);
+					}
+				}
 			}
 		}
 		super.visitClass(node);
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/SourceCodeFinder.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/SourceCodeFinder.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/SourceCodeFinder.java	(working copy)
@@ -1,8 +1,24 @@
 package org.codehaus.groovy.eclipse.codebrowsing;
 
+import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jface.text.Region;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
 
 /**
  * Utility class to find source code for different objects.
@@ -10,11 +26,16 @@
  * @author emp
  */
 public class SourceCodeFinder {
+
 	public static ISourceCode find(ClassNode type) {
+		return find(type, null);
+	}
+
+	public static ISourceCode find(ClassNode type, ASTNode member) {
 		String filename = type.getName().replace('.', '/');
 
-		IFile file = FileUtils.findFileInProject(filename, new String[] {
-				"groovy", "java" });
+		IFile file = FileUtils.findFileInProject(filename,
+				new String[] { "groovy" });
 
 		if (file != null) {
 			String ident = type.getNameWithoutPackage();
@@ -24,24 +45,68 @@
 				return new FileSourceCode(file, new Region(offset, ident
 						.length()));
 			}
+		} else {
+			try {
+				IJavaProject javaProject = getJavaProject();
+				IType javaType = javaProject.findType(type.getName());
+				if (javaType != null) {
+					ICompilationUnit compilationUnit = javaType
+							.getCompilationUnit();
+					IJavaElement javaElement = javaType;
+					if (member instanceof FieldNode) {
+						FieldNode fNode = (FieldNode) member;
+						javaElement = javaType.getField(fNode.getName());
+					} else if (member instanceof MethodNode) {
+						MethodNode mNode = (MethodNode) member;
+						Parameter[] params = mNode.getParameters();
+						String[] paramTypes = new String[params.length];
+						for (int i = 0; i < params.length; i++) {
+							paramTypes[i] = "L" + params[i].getType().getName() + ";";  // FIXME: handle primitives
+						}
+						javaElement = javaType.getMethod(mNode.getName(),
+								paramTypes);
+					}
+					if (compilationUnit != null) {
+						return new CompilationUnitSourceCode(compilationUnit,
+								javaElement);
+					}
+					IClassFile classFile = javaType.getClassFile();
+					if (classFile != null) {
+						return new ClassFileSourceCode(classFile, javaElement);
+					}
+				}
+			} catch (JavaModelException e) {
+				e.printStackTrace();
+			}
 		}
 
 		return null;
 	}
-	
+
+	private static IJavaProject getJavaProject() {
+		IWorkbench workbench = PlatformUI.getWorkbench();
+		IWorkbenchPage activePage = workbench.getActiveWorkbenchWindow()
+				.getActivePage();
+		FileEditorInput input = (FileEditorInput) activePage.getActiveEditor()
+				.getEditorInput();
+		IProject project = input.getFile().getProject();
+		return JavaCore.create(project);
+	}
+
 	public static void openType(ClassNode type) {
 		String packageName = type.getPackageName();
 		String typeName = type.getName();
 		openType(packageName, typeName);
 	}
-	
+
 	public static void openType(String packageName, String typeName) {
 		// Find the currently Groovy project.
 		// Get the Java project
 		// Get the package for the packageName
 		// Get the type from the package.
 		// Open the type.
-		
-		// Should declaration processor change? Use the IOpenable to open the type?
+
+		// Should declaration processor change? Use the IOpenable to open the
+		// type?
 	}
 }
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/CompilationUnitSourceCode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/CompilationUnitSourceCode.java	(revision 0)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/CompilationUnitSourceCode.java	(revision 0)
@@ -0,0 +1,33 @@
+package org.codehaus.groovy.eclipse.codebrowsing;
+
+import org.codehaus.groovy.eclipse.GroovyPlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.FileEditorInput;
+
+public class CompilationUnitSourceCode extends JavaSourceCode {
+
+	public CompilationUnitSourceCode(ICompilationUnit handle) {
+		super(handle);
+	}
+
+	public CompilationUnitSourceCode(ICompilationUnit handle, IJavaElement element) {
+		super(handle, element);
+	}
+
+	public boolean open() {
+		try {
+			ICompilationUnit cu = (ICompilationUnit) getSourceHandle();
+			IEditorPart editor = open(cu.getElementName(), new FileEditorInput((IFile) cu
+					.getCorrespondingResource()));
+			return editor != null;
+		} catch (JavaModelException e) {
+			GroovyPlugin.getDefault().logException(
+					"Error getting file resource.", e);
+		}
+		return false;
+	}
+}
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/FileSourceCode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/FileSourceCode.java	(revision 10175)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/FileSourceCode.java	(working copy)
@@ -1,15 +1,8 @@
 package org.codehaus.groovy.eclipse.codebrowsing;
 
-import org.codehaus.groovy.eclipse.GroovyPlugin;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.jface.text.IRegion;
-import org.eclipse.ui.IEditorDescriptor;
-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.ITextEditor;
 
 /**
  * Source code that is represented by a source file.
@@ -21,8 +14,7 @@
 
 	/**
 	 * @param file The file to open.
-	 * @param offset The offset in the file that is of interest.
-	 * @param length The length of the area of interest.
+	 * @param region The region in the file that is of interest.
 	 */
 	public FileSourceCode(IFile file, IRegion region) {
 		super(file, region);
@@ -30,30 +22,6 @@
 	}
 	
 	public boolean open() {
-		try {
-			IWorkbenchPage page = PlatformUI.getWorkbench()
-					.getActiveWorkbenchWindow().getActivePage();
-			IEditorDescriptor desc = PlatformUI.getWorkbench()
-					.getEditorRegistry().getDefaultEditor(((IFile)file).getName());
-			try {
-				IEditorPart part = page.openEditor(new FileEditorInput(file),
-						desc.getId());
-				IRegion hregion = getRegionOfInterest();
-				ITextEditor editor = (ITextEditor) part;
-				editor
-						.selectAndReveal(hregion.getOffset(), hregion
-								.getLength());
-			} catch (PartInitException e) {
-				// LOG: need own logging.
-				GroovyPlugin.getDefault().logException("Should not happen.", e);
-				e.printStackTrace();
-				return false;
-			}
-		} catch (NullPointerException e) {
-			// LOG: Rare case that somehow workbench or active window or
-			// page is null.
-			return false;
-		}
-		return true;
+		return open(file.getName(), new FileEditorInput(file)) != null;
 	}
 }
Index: org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/JavaSourceCode.java
===================================================================
--- org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/JavaSourceCode.java	(revision 0)
+++ org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/JavaSourceCode.java	(revision 0)
@@ -0,0 +1,74 @@
+package org.codehaus.groovy.eclipse.codebrowsing;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+
+public abstract class JavaSourceCode extends AbstractSourceCode {
+
+	private IJavaElement element;
+
+	public JavaSourceCode(Object handle) {
+		super(handle);
+	}
+
+	public JavaSourceCode(Object handle, IJavaElement element) {
+		super(handle);
+		this.element = element;
+	}
+
+	protected IEditorPart open(String fileName, IEditorInput editorInput) {
+		IEditorPart editor = super.open(fileName, editorInput);
+		if (element != null) {
+			JavaEditor javaEditor = (JavaEditor) editor;
+			if (element.getElementType() == IJavaElement.METHOD) {
+				// FIXME: this seems like a lot of work to get the open method 
+				IMethod method = (IMethod) element;
+				if (!method.exists()) {
+					try {
+						IJavaModel model = element.getJavaModel();
+						IType type = (IType) method.getParent();
+						IJavaProject project = type.getJavaProject();
+						project = model
+								.getJavaProject(project.getElementName());
+						type = project.findType(type.getFullyQualifiedName());
+						IMethod[] methods = type.getMethods();
+						for (int i = 0; i < methods.length; i++) {
+							if (methods[i].getElementName().equals(
+									method.getElementName())
+									&& methods[i].getNumberOfParameters() == method
+											.getNumberOfParameters()) {
+								// compare parameter types
+								boolean match = true;
+								String[] origParamTypes = method
+										.getParameterTypes();
+								String[] paramTypes = origParamTypes;
+								for (int j = 0; j < paramTypes.length; j++) {
+									if (!paramTypes[j]
+											.equals(origParamTypes[j])) {
+										match = false;
+										break;
+									}
+								}
+								if (match) {
+									element = method = methods[i];
+									break;
+								}
+							}
+						}
+					} catch (JavaModelException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+			javaEditor.setSelection(element);
+		}
+		return editor;
+	}
+}

