/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors;

import static com.android.SdkConstants.ANDROID_PKG;
import static com.android.SdkConstants.ANDROID_PREFIX;
import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.ANDROID_THEME_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_CLASS;
import static com.android.SdkConstants.ATTR_CONTEXT;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_ON_CLICK;
import static com.android.SdkConstants.CLASS_ACTIVITY;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_DOCS;
import static com.android.SdkConstants.FD_DOCS_REFERENCE;
import static com.android.SdkConstants.FN_RESOURCE_BASE;
import static com.android.SdkConstants.FN_RESOURCE_CLASS;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.TAG_RESOURCES;
import static com.android.SdkConstants.TAG_STYLE;
import static com.android.SdkConstants.TOOLS_URI;
import static com.android.SdkConstants.VIEW;
import static com.android.SdkConstants.VIEW_FRAGMENT;
import static com.android.xml.AndroidManifest.ATTRIBUTE_NAME;
import static com.android.xml.AndroidManifest.ATTRIBUTE_PACKAGE;
import static com.android.xml.AndroidManifest.NODE_ACTIVITY;
import static com.android.xml.AndroidManifest.NODE_SERVICE;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.ide.common.resources.ResourceFile;
import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.ResourceUrl;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.ide.eclipse.adt.io.IFolderWrapper;
import com.android.io.FileWrapper;
import com.android.io.IAbstractFile;
import com.android.io.IAbstractFolder;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.sdklib.IAndroidTarget;
import com.android.utils.Pair;

import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.NamespaceContext;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLLocator;
import org.apache.xerces.xni.XNIException;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.IJavaElement;
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.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.text.JavaWordFinder;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Class containing hyperlink resolvers for XML and Java files to jump to associated
 * resources -- Java Activity and Service classes, XML layout and string declarations,
 * image drawables, etc.
 */
@SuppressWarnings("restriction")
public class Hyperlinks {
    private static final String CATEGORY = "category";                            //$NON-NLS-1$
    private static final String ACTION = "action";                                //$NON-NLS-1$
    private static final String PERMISSION = "permission";                        //$NON-NLS-1$
    private static final String USES_PERMISSION = "uses-permission";              //$NON-NLS-1$
    private static final String CATEGORY_PKG_PREFIX = "android.intent.category."; //$NON-NLS-1$
    private static final String ACTION_PKG_PREFIX = "android.intent.action.";     //$NON-NLS-1$
    private static final String PERMISSION_PKG_PREFIX = "android.permission.";    //$NON-NLS-1$

    private Hyperlinks() {
        // Not instantiatable. This is a container class containing shared code
        // for the various inner classes that are actual hyperlink resolvers.
    }

    /**
     * Returns whether a string represents a valid fully qualified name for a view class.
     * Does not check for existence.
     */
    @VisibleForTesting
    static boolean isViewClassName(String name) {
        int length = name.length();
        if (length < 2 || name.indexOf('.') == -1) {
            return false;
        }

        boolean lastWasDot = true;
        for (int i = 0; i < length; i++) {
            char c = name.charAt(i);
            if (lastWasDot) {
                if (!Character.isJavaIdentifierStart(c)) {
                    return false;
                }
                lastWasDot = false;
            } else {
                if (c == '.') {
                    lastWasDot = true;
                } else if (!Character.isJavaIdentifierPart(c)) {
                    return false;
                }
            }
        }

        return !lastWasDot;
    }

    /** Determines whether the given attribute <b>name</b> is linkable */
    private static boolean isAttributeNameLink(XmlContext context) {
        // We could potentially allow you to link to builtin Android properties:
        //   ANDROID_URI.equals(attribute.getNamespaceURI())
        // and then jump into the res/values/attrs.xml document that is available
        // in the SDK data directory (path found via
        // IAndroidTarget.getPath(IAndroidTarget.ATTRIBUTES)).
        //
        // For now, we're not doing that.
        //
        // We could also allow to jump into custom attributes in custom view
        // classes. Not yet implemented.

        return false;
    }

    /** Determines whether the given attribute <b>value</b> is linkable */
    private static boolean isAttributeValueLink(XmlContext context) {
        // Everything else here is attribute based
        Attr attribute = context.getAttribute();
        if (attribute == null) {
            return false;
        }

        if (isClassAttribute(context) || isOnClickAttribute(context)
                || isManifestName(context) || isStyleAttribute(context)) {
            return true;
        }

        String value = attribute.getValue();
        if (value.startsWith(NEW_ID_PREFIX)) {
            // It's a value -declaration-, nowhere else to jump
            // (though we could consider jumping to the R-file; would that
            // be helpful?)
            return !ATTR_ID.equals(attribute.getLocalName());
        }

        ResourceUrl resource = ResourceUrl.parse(value);
        if (resource != null) {
            return true;
        }

        return false;
    }

    /** Determines whether the given element <b>name</b> is linkable */
    private static boolean isElementNameLink(XmlContext context) {
        if (isClassElement(context)) {
            return true;
        }

        return false;
    }

    /**
     * Returns true if this node/attribute pair corresponds to a manifest reference to
     * an activity.
     */
    private static boolean isActivity(XmlContext context) {
        // Is this an <activity> or <service> in an AndroidManifest.xml file? If so, jump
        // to it
        Attr attribute = context.getAttribute();
        String tagName = context.getElement().getTagName();
        if (NODE_ACTIVITY.equals(tagName) && ATTRIBUTE_NAME.equals(attribute.getLocalName())
                && ANDROID_URI.equals(attribute.getNamespaceURI())) {
            return true;
        }

        return false;
    }

    /**
     * Returns true if this node/attribute pair corresponds to a manifest android:name reference
     */
    private static boolean isManifestName(XmlContext context) {
        Attr attribute = context.getAttribute();
        if (attribute != null && ATTRIBUTE_NAME.equals(attribute.getLocalName())
                && ANDROID_URI.equals(attribute.getNamespaceURI())) {
            if (getEditor() instanceof ManifestEditor) {
                return true;
            }
        }

        return false;
    }

    /**
     * Opens the declaration corresponding to an android:name reference in the
     * AndroidManifest.xml file
     */
    private static boolean openManifestName(IProject project, XmlContext context) {
        if (isActivity(context)) {
            String fqcn = getActivityClassFqcn(context);
            return AdtPlugin.openJavaClass(project, fqcn);
        } else if (isService(context)) {
            String fqcn = getServiceClassFqcn(context);
            return AdtPlugin.openJavaClass(project, fqcn);
        } else if (isBuiltinPermission(context)) {
            String permission = context.getAttribute().getValue();
            // Mutate something like android.permission.ACCESS_CHECKIN_PROPERTIES
            // into relative doc url android/Manifest.permission.html#ACCESS_CHECKIN_PROPERTIES
            assert permission.startsWith(PERMISSION_PKG_PREFIX);
            String relative = "android/Manifest.permission.html#" //$NON-NLS-1$
                    + permission.substring(PERMISSION_PKG_PREFIX.length());

            URL url = getDocUrl(relative);
            if (url != null) {
                AdtPlugin.openUrl(url);
                return true;
            } else {
                return false;
            }
        } else if (isBuiltinIntent(context)) {
            String intent = context.getAttribute().getValue();
            // Mutate something like android.intent.action.MAIN into
            // into relative doc url android/content/Intent.html#ACTION_MAIN
            String relative;
            if (intent.startsWith(ACTION_PKG_PREFIX)) {
                relative = "android/content/Intent.html#ACTION_" //$NON-NLS-1$
                        + intent.substring(ACTION_PKG_PREFIX.length());
            } else if (intent.startsWith(CATEGORY_PKG_PREFIX)) {
                relative = "android/content/Intent.html#CATEGORY_" //$NON-NLS-1$
                        + intent.substring(CATEGORY_PKG_PREFIX.length());
            } else {
                return false;
            }
            URL url = getDocUrl(relative);
            if (url != null) {
                AdtPlugin.openUrl(url);
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    /** Returns true if this represents a style attribute */
    private static boolean isStyleAttribute(XmlContext context) {
        String tag = context.getElement().getTagName();
        return TAG_STYLE.equals(tag);
    }

    /**
     * Returns true if this represents a {@code <view class="foo.bar.Baz">} class
     * attribute, or a {@code <fragment android:name="foo.bar.Baz">} class attribute
     */
    private static boolean isClassAttribute(XmlContext context) {
        Attr attribute = context.getAttribute();
        if (attribute == null) {
            return false;
        }
        String tag = context.getElement().getTagName();
        String attributeName = attribute.getLocalName();
        return ATTR_CLASS.equals(attributeName) && (VIEW.equals(tag) || VIEW_FRAGMENT.equals(tag))
                || ATTR_NAME.equals(attributeName) && VIEW_FRAGMENT.equals(tag)
                || (ATTR_CONTEXT.equals(attributeName)
                        && TOOLS_URI.equals(attribute.getNamespaceURI()));
    }

    /** Returns true if this represents an onClick attribute specifying a method handler */
    private static boolean isOnClickAttribute(XmlContext context) {
        Attr attribute = context.getAttribute();
        if (attribute == null) {
            return false;
        }
        return ATTR_ON_CLICK.equals(attribute.getLocalName()) && attribute.getValue().length() > 0;
    }

    /** Returns true if this represents a {@code <foo.bar.Baz>} custom view class element */
    private static boolean isClassElement(XmlContext context) {
        if (context.getAttribute() != null) {
            // Don't match the outer element if the user is hovering over a specific attribute
            return false;
        }
        // If the element looks like a fully qualified class name (e.g. it's a custom view
        // element) offer it as a link
        String tag = context.getElement().getTagName();
        return isViewClassName(tag);
    }

    /** Returns the FQCN for a class declaration at the given context */
    private static String getClassFqcn(XmlContext context) {
        if (isClassAttribute(context)) {
            String value = context.getAttribute().getValue();
            if (!value.isEmpty() && value.charAt(0) == '.') {
                IProject project = getProject();
                if (project != null) {
                    ManifestInfo info = ManifestInfo.get(project);
                    String pkg = info.getPackage();
                    if (pkg != null) {
                        value = pkg + value;
                    }
                }
            }
            return value;
        } else if (isClassElement(context)) {
            return context.getElement().getTagName();
        }

        return null;
    }

    /**
     * Returns true if this node/attribute pair corresponds to a manifest reference to
     * an service.
     */
    private static boolean isService(XmlContext context) {
        Attr attribute = context.getAttribute();
        Element node = context.getElement();

        // Is this an <activity> or <service> in an AndroidManifest.xml file? If so, jump to it
        String nodeName = node.getNodeName();
        if (NODE_SERVICE.equals(nodeName) && ATTRIBUTE_NAME.equals(attribute.getLocalName())
                && ANDROID_URI.equals(attribute.getNamespaceURI())) {
            return true;
        }

        return false;
    }

    /**
     * Returns a URL pointing to the Android reference documentation, either installed
     * locally or the one on android.com
     *
     * @param relative a relative url to append to the root url
     * @return a URL pointing to the documentation
     */
    private static URL getDocUrl(String relative) {
        // First try to find locally installed documentation
        File sdkLocation = new File(Sdk.getCurrent().getSdkOsLocation());
        File docs = new File(sdkLocation, FD_DOCS + File.separator + FD_DOCS_REFERENCE);
        try {
            if (docs.exists()) {
                String s = docs.toURI().toURL().toExternalForm();
                if (!s.endsWith("/")) { //$NON-NLS-1$
                    s += "/";           //$NON-NLS-1$
                }
                return new URL(s + relative);
            }
            // If not, fallback to the online documentation
            return new URL("http://developer.android.com/reference/" + relative); //$NON-NLS-1$
        } catch (MalformedURLException e) {
            AdtPlugin.log(e, "Can't create URL for %1$s", docs);
            return null;
        }
    }

    /** Returns true if the context is pointing to a permission name reference */
    private static boolean isBuiltinPermission(XmlContext context) {
        Attr attribute = context.getAttribute();
        Element node = context.getElement();

        // Is this an <activity> or <service> in an AndroidManifest.xml file? If so, jump to it
        String nodeName = node.getNodeName();
        if ((USES_PERMISSION.equals(nodeName) || PERMISSION.equals(nodeName))
                && ATTRIBUTE_NAME.equals(attribute.getLocalName())
                && ANDROID_URI.equals(attribute.getNamespaceURI())) {
            String value = attribute.getValue();
            if (value.startsWith(PERMISSION_PKG_PREFIX)) {
                return true;
            }
        }

        return false;
    }

    /** Returns true if the context is pointing to an intent reference */
    private static boolean isBuiltinIntent(XmlContext context) {
        Attr attribute = context.getAttribute();
        Element node = context.getElement();

        // Is this an <activity> or <service> in an AndroidManifest.xml file? If so, jump to it
        String nodeName = node.getNodeName();
        if ((ACTION.equals(nodeName) || CATEGORY.equals(nodeName))
                && ATTRIBUTE_NAME.equals(attribute.getLocalName())
                && ANDROID_URI.equals(attribute.getNamespaceURI())) {
            String value = attribute.getValue();
            if (value.startsWith(ACTION_PKG_PREFIX) || value.startsWith(CATEGORY_PKG_PREFIX)) {
                return true;
            }
        }

        return false;
    }


    /**
     * Returns the fully qualified class name of an activity referenced by the given
     * AndroidManifest.xml node
     */
    private static String getActivityClassFqcn(XmlContext context) {
        Attr attribute = context.getAttribute();
        Element node = context.getElement();
        StringBuilder sb = new StringBuilder();
        Element root = node.getOwnerDocument().getDocumentElement();
        String pkg = root.getAttribute(ATTRIBUTE_PACKAGE);
        String className = attribute.getValue();
        if (className.startsWith(".")) { //$NON-NLS-1$
            sb.append(pkg);
        } else if (className.indexOf('.') == -1) {
            // According to the <activity> manifest element documentation, this is not
            // valid ( http://developer.android.com/guide/topics/manifest/activity-element.html )
            // but it appears in manifest files and appears to be supported by the runtime
            // so handle this in code as well:
            sb.append(pkg);
            sb.append('.');
        } // else: the class name is already a fully qualified class name
        sb.append(className);
        return sb.toString();
    }

    /**
     * Returns the fully qualified class name of a service referenced by the given
     * AndroidManifest.xml node
     */
    private static String getServiceClassFqcn(XmlContext context) {
        // Same logic
        return getActivityClassFqcn(context);
    }

    /**
     * Returns the XML tag containing an element description for value items of the given
     * resource type
     *
     * @param type the resource type to query the XML tag name for
     * @return the tag name used for value declarations in XML of resources of the given
     *         type
     */
    public static String getTagName(ResourceType type) {
        if (type == ResourceType.ID) {
            // Ids are recorded in <item> tags instead of <id> tags
            return SdkConstants.TAG_ITEM;
        }

        return type.getName();
    }

    /**
     * Computes the actual exact location to jump to for a given XML context.
     *
     * @param context the XML context to be opened
     * @return true if the request was handled successfully
     */
    private static boolean open(XmlContext context) {
        IProject project = getProject();
        if (project == null) {
            return false;
        }

        if (isManifestName(context)) {
            return openManifestName(project, context);
        } else if (isClassElement(context) || isClassAttribute(context)) {
            return AdtPlugin.openJavaClass(project, getClassFqcn(context));
        } else if (isOnClickAttribute(context)) {
            return openOnClickMethod(project, context.getAttribute().getValue());
        } else {
            return false;
        }
    }

    /** Opens a path (which may not be in the workspace) */
    private static void openPath(IPath filePath, IRegion region, int offset) {
        IEditorPart sourceEditor = getEditor();
        IWorkbenchPage page = sourceEditor.getEditorSite().getPage();

        IFile file = AdtUtils.pathToIFile(filePath);
        if (file != null && file.exists()) {
            try {
                AdtPlugin.openFile(file, region);
                return;
            } catch (PartInitException ex) {
                AdtPlugin.log(ex, "Can't open %$1s", filePath); //$NON-NLS-1$
            }
        } else {
            // It's not a path in the workspace; look externally
            // (this is probably an @android: path)
            if (filePath.isAbsolute()) {
                IFileStore fileStore = EFS.getLocalFileSystem().getStore(filePath);
                if (!fileStore.fetchInfo().isDirectory() && fileStore.fetchInfo().exists()) {
                    try {
                        IEditorPart target = IDE.openEditorOnFileStore(page, fileStore);
                        if (target instanceof MultiPageEditorPart) {
                            MultiPageEditorPart part = (MultiPageEditorPart) target;
                            IEditorPart[] editors = part.findEditors(target.getEditorInput());
                            if (editors != null) {
                                for (IEditorPart editor : editors) {
                                    if (editor instanceof StructuredTextEditor) {
                                        StructuredTextEditor ste = (StructuredTextEditor) editor;
                                        part.setActiveEditor(editor);
                                        ste.selectAndReveal(offset, 0);
                                        break;
                                    }
                                }
                            }
                        }

                        return;
                    } catch (PartInitException ex) {
                        AdtPlugin.log(ex, "Can't open %$1s", filePath); //$NON-NLS-1$
                    }
                }
            }
        }

        // Failed: display message to the user
        displayError(String.format("Could not find resource %1$s", filePath));
    }

    private static void displayError(String message) {
        // Failed: display message to the user
        IEditorSite editorSite = getEditor().getEditorSite();
        IStatusLineManager status = editorSite.getActionBars().getStatusLineManager();
        status.setErrorMessage(message);
    }

    /**
     * Opens a Java method referenced by the given on click attribute method name
     *
     * @param project the project containing the click handler
     * @param method the method name of the on click handler
     * @return true if the method was opened, false otherwise
     */
    public static boolean openOnClickMethod(IProject project, String method) {
        // Search for the method in the Java index, filtering by the required click handler
        // method signature (public and has a single View parameter), and narrowing the scope
        // first to Activity classes, then to the whole workspace.
        final AtomicBoolean success = new AtomicBoolean(false);
        SearchRequestor requestor = new SearchRequestor() {
            @Override
            public void acceptSearchMatch(SearchMatch match) throws CoreException {
                Object element = match.getElement();
                if (element instanceof IMethod) {
                    IMethod methodElement = (IMethod) element;
                    String[] parameterTypes = methodElement.getParameterTypes();
                    if (parameterTypes != null
                            && parameterTypes.length == 1
                            && ("Qandroid.view.View;".equals(parameterTypes[0]) //$NON-NLS-1$
                                    || "QView;".equals(parameterTypes[0]))) {   //$NON-NLS-1$
                        // Check that it's public
                        if (Flags.isPublic(methodElement.getFlags())) {
                            JavaUI.openInEditor(methodElement);
                            success.getAndSet(true);
                        }
                    }
                }
            }
        };
        try {
            IJavaSearchScope scope = null;
            IType activityType = null;
            IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
            if (javaProject != null) {
                activityType = javaProject.findType(CLASS_ACTIVITY);
                if (activityType != null) {
                    scope = SearchEngine.createHierarchyScope(activityType);
                }
            }
            if (scope == null) {
                scope = SearchEngine.createWorkspaceScope();
            }

            SearchParticipant[] participants = new SearchParticipant[] {
                SearchEngine.getDefaultSearchParticipant()
            };
            int matchRule = SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE;
            SearchPattern pattern = SearchPattern.createPattern("*." + method,
                    IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, matchRule);
            SearchEngine engine = new SearchEngine();
            engine.search(pattern, participants, scope, requestor, new NullProgressMonitor());

            boolean ok = success.get();
            if (!ok && activityType != null) {
                // TODO: Create a project+dependencies scope and search only that scope

                // Try searching again with a complete workspace scope this time
                scope = SearchEngine.createWorkspaceScope();
                engine.search(pattern, participants, scope, requestor, new NullProgressMonitor());

                // TODO: There could be more than one match; add code to consider them all
                // and pick the most likely candidate and open only that one.

                ok = success.get();
            }
            return ok;
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }
        return false;
    }

    /**
     * Returns the current configuration, if the associated UI editor has been initialized
     * and has an associated configuration
     *
     * @return the configuration for this file, or null
     */
    private static FolderConfiguration getConfiguration() {
        IEditorPart editor = getEditor();
        if (editor != null) {
            LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(editor);
            GraphicalEditorPart graphicalEditor =
                delegate == null ? null : delegate.getGraphicalEditor();

            if (graphicalEditor != null) {
                return graphicalEditor.getConfiguration();
            } else {
                // TODO: Could try a few more things to get the configuration:
                // (1) try to look at the file.getPersistentProperty(NAME_CONFIG_STATE)
                //    which will return previously saved state. This isn't necessary today
                //    since no editors seem to be lazily initialized.
                // (2) attempt to use the configuration from any of the other open
                //    files, especially files in the same directory as this one.
            }

            // Create a configuration from the current file
            IProject project = null;
            IEditorInput editorInput = editor.getEditorInput();
            if (editorInput instanceof FileEditorInput) {
                IFile file = ((FileEditorInput) editorInput).getFile();
                project = file.getProject();
                ProjectResources pr = ResourceManager.getInstance().getProjectResources(project);
                IContainer parent = file.getParent();
                if (parent instanceof IFolder) {
                    ResourceFolder resFolder = pr.getResourceFolder((IFolder) parent);
                    if (resFolder != null) {
                        return resFolder.getConfiguration();
                    }
                }
            }

            // Might be editing a Java file, where there is no configuration context.
            // Instead look at surrounding files in the workspace and obtain one valid
            // configuration.
            for (IEditorReference reference : editor.getSite().getPage().getEditorReferences()) {
                IEditorPart part = reference.getEditor(false /*restore*/);

                LayoutEditorDelegate refDelegate = LayoutEditorDelegate.fromEditor(part);
                if (refDelegate != null) {
                    IProject refProject = refDelegate.getEditor().getProject();
                    if (project == null || project == refProject) {
                        GraphicalEditorPart refGraphicalEditor = refDelegate.getGraphicalEditor();
                        if (refGraphicalEditor != null) {
                            return refGraphicalEditor.getConfiguration();
                        }
                    }
                }
            }
        }

        return null;
    }

    /** Returns the {@link IAndroidTarget} to be used for looking up system resources */
    private static IAndroidTarget getTarget(IProject project) {
        IEditorPart editor = getEditor();
        LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(editor);
        if (delegate != null) {
            GraphicalEditorPart graphicalEditor = delegate.getGraphicalEditor();
            if (graphicalEditor != null) {
                return graphicalEditor.getRenderingTarget();
            }
        }

        Sdk currentSdk = Sdk.getCurrent();
        if (currentSdk == null) {
            return null;
        }

        return currentSdk.getTarget(project);
    }

    /** Return either the project resources or the framework resources (or null) */
    private static ResourceRepository getResources(IProject project, boolean framework) {
        if (framework) {
            IAndroidTarget target = getTarget(project);

            if (target == null && project == null && framework) {
                // No current project: probably jumped into some of the framework XML resource
                // files and attempting to jump around. Attempt to figure out which target
                // we're dealing with and continue looking within the same framework.
                IEditorPart editor = getEditor();
                Sdk sdk = Sdk.getCurrent();
                if (sdk != null && editor instanceof AndroidXmlEditor) {
                    AndroidTargetData data = ((AndroidXmlEditor) editor).getTargetData();
                    if (data != null) {
                        return data.getFrameworkResources();
                    }
                }
            }

            if (target == null) {
                return null;
            }
            AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
            if (data == null) {
                return null;
            }
            return data.getFrameworkResources();
        } else {
            return ResourceManager.getInstance().getProjectResources(project);
        }
    }

    /**
     * Finds a definition of an id attribute in layouts. (Ids can also be defined as
     * resources; use {@link #findValueInXml} or {@link #findValueInDocument} to locate it there.)
     */
    private static Pair<IFile, IRegion> findIdDefinition(IProject project, String id) {
        // FIRST look in the same file as the originating request, that's where you usually
        // want to jump
        IFile self = AdtUtils.getActiveFile();
        if (self != null && EXT_XML.equals(self.getFileExtension())) {
            Pair<IFile, IRegion> target = findIdInXml(id, self);
            if (target != null) {
                return target;
            }
        }

        // Look in the configuration folder: Search compatible configurations
        ResourceRepository resources = getResources(project, false /* isFramework */);
        FolderConfiguration configuration = getConfiguration();
        if (configuration != null) { // Not the case when searching from Java files for example
            List<ResourceFolder> folders = resources.getFolders(ResourceFolderType.LAYOUT);
            if (folders != null) {
                for (ResourceFolder folder : folders) {
                    if (folder.getConfiguration().isMatchFor(configuration)) {
                        IAbstractFolder wrapper = folder.getFolder();
                        if (wrapper instanceof IFolderWrapper) {
                            IFolder iFolder = ((IFolderWrapper) wrapper).getIFolder();
                            Pair<IFile, IRegion> target = findIdInFolder(iFolder, id);
                            if (target != null) {
                                return target;
                            }
                        }
                    }
                }
                return null;
            }
        }

        // Ugh. Search ALL layout files in the project!
        List<ResourceFolder> folders = resources.getFolders(ResourceFolderType.LAYOUT);
        if (folders != null) {
            for (ResourceFolder folder : folders) {
                IAbstractFolder wrapper = folder.getFolder();
                if (wrapper instanceof IFolderWrapper) {
                    IFolder iFolder = ((IFolderWrapper) wrapper).getIFolder();
                    Pair<IFile, IRegion> target = findIdInFolder(iFolder, id);
                    if (target != null) {
                        return target;
                    }
                }
            }
        }

        return null;
    }

    /**
     * Finds a definition of an id attribute in a particular layout folder.
     */
    private static Pair<IFile, IRegion> findIdInFolder(IContainer f, String id) {
        try {
            // Check XML files in values/
            for (IResource resource : f.members()) {
                if (resource.exists() && !resource.isDerived() && resource instanceof IFile) {
                    IFile file = (IFile) resource;
                    // Must have an XML extension
                    if (EXT_XML.equals(file.getFileExtension())) {
                        Pair<IFile, IRegion> target = findIdInXml(id, file);
                        if (target != null) {
                            return target;
                        }
                    }
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, ""); //$NON-NLS-1$
        }

        return null;
    }

    /** Parses the given file and locates a definition of the given resource */
    private static Pair<IFile, IRegion> findValueInXml(
            ResourceType type, String name, IFile file) {
        IStructuredModel model = null;
        try {
            model = StructuredModelManager.getModelManager().getExistingModelForRead(file);
            if (model == null) {
                // There is no open or cached model for the file; see if the file looks
                // like it's interesting (content contains the String name we are looking for)
                if (AdtPlugin.fileContains(file, name)) {
                    // Yes, so parse content
                    model = StructuredModelManager.getModelManager().getModelForRead(file);
                }
            }
            if (model instanceof IDOMModel) {
                IDOMModel domModel = (IDOMModel) model;
                Document document = domModel.getDocument();
                return findValueInDocument(type, name, file, document);
            }
        } catch (IOException e) {
            AdtPlugin.log(e, "Can't parse %1$s", file); //$NON-NLS-1$
        } catch (CoreException e) {
            AdtPlugin.log(e, "Can't parse %1$s", file); //$NON-NLS-1$
        } finally {
            if (model != null) {
                model.releaseFromRead();
            }
        }

        return null;
    }

    /** Looks within an XML DOM document for the given resource name and returns it */
    private static Pair<IFile, IRegion> findValueInDocument(
            ResourceType type, String name, IFile file, Document document) {
        String targetTag = getTagName(type);
        Element root = document.getDocumentElement();
        if (root.getTagName().equals(TAG_RESOURCES)) {
            NodeList topLevel = root.getChildNodes();
            Pair<IFile, IRegion> value = findValueInChildren(name, file, targetTag, topLevel);
            if (value == null && type == ResourceType.ATTR) {
                for (int i = 0, n = topLevel.getLength(); i < n; i++) {
                    Node child = topLevel.item(i);
                    if (child.getNodeType() == Node.ELEMENT_NODE) {
                        Element element = (Element)child;
                        String tagName = element.getTagName();
                        if (tagName.equals("declare-styleable")) {
                            NodeList children = element.getChildNodes();
                            value = findValueInChildren(name, file, targetTag, children);
                            if (value != null) {
                                return value;
                            }
                        }
                    }
                }
            }

            return value;
        }

        return null;
    }

    private static Pair<IFile, IRegion> findValueInChildren(String name, IFile file,
            String targetTag, NodeList children) {
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element)child;
                String tagName = element.getTagName();
                if (tagName.equals(targetTag)) {
                    String elementName = element.getAttribute(ATTR_NAME);
                    if (elementName.equals(name)) {
                        IRegion region = null;
                        if (element instanceof IndexedRegion) {
                            IndexedRegion r = (IndexedRegion) element;
                            // IndexedRegion.getLength() returns bogus values
                            int length = r.getEndOffset() - r.getStartOffset();
                            region = new Region(r.getStartOffset(), length);
                        }

                        return Pair.of(file, region);
                    }
                }
            }
        }

        return null;
    }

    /** Parses the given file and locates a definition of the given resource */
    private static Pair<IFile, IRegion> findIdInXml(String id, IFile file) {
        IStructuredModel model = null;
        try {
            model = StructuredModelManager.getModelManager().getExistingModelForRead(file);
            if (model == null) {
                // There is no open or cached model for the file; see if the file looks
                // like it's interesting (content contains the String name we are looking for)
                if (AdtPlugin.fileContains(file, id)) {
                    // Yes, so parse content
                    model = StructuredModelManager.getModelManager().getModelForRead(file);
                }
            }
            if (model instanceof IDOMModel) {
                IDOMModel domModel = (IDOMModel) model;
                Document document = domModel.getDocument();
                return findIdInDocument(id, file, document);
            }
        } catch (IOException e) {
            AdtPlugin.log(e, "Can't parse %1$s", file); //$NON-NLS-1$
        } catch (CoreException e) {
            AdtPlugin.log(e, "Can't parse %1$s", file); //$NON-NLS-1$
        } finally {
            if (model != null) {
                model.releaseFromRead();
            }
        }

        return null;
    }

    /** Looks within an XML DOM document for the given resource name and returns it */
    private static Pair<IFile, IRegion> findIdInDocument(String id, IFile file,
            Document document) {
        String targetAttribute = NEW_ID_PREFIX + id;
        Element root = document.getDocumentElement();
        Pair<IFile, IRegion> result = findIdInElement(root, file, targetAttribute,
                true /*requireId*/);
        if (result == null) {
            result = findIdInElement(root, file, targetAttribute, false /*requireId*/);
        }
        return result;
    }

    private static Pair<IFile, IRegion> findIdInElement(
            Element root, IFile file, String targetAttribute, boolean requireIdAttribute) {
        NamedNodeMap attributes = root.getAttributes();
        for (int i = 0, n = attributes.getLength(); i < n; i++) {
            Node item = attributes.item(i);
            if (item instanceof Attr) {
                Attr attribute = (Attr) item;
                if (requireIdAttribute && !ATTR_ID.equals(attribute.getLocalName())) {
                    continue;
                }
                String value = attribute.getValue();
                if (value.equals(targetAttribute)) {
                    // Select the element -containing- the id rather than the attribute itself
                    IRegion region = null;
                    Node element = attribute.getOwnerElement();
                    //if (attribute instanceof IndexedRegion) {
                    if (element instanceof IndexedRegion) {
                        IndexedRegion r = (IndexedRegion) element;
                        int length = r.getEndOffset() - r.getStartOffset();
                        region = new Region(r.getStartOffset(), length);
                    }

                    return Pair.of(file, region);
                }
            }
        }

        NodeList children = root.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element)child;
                Pair<IFile, IRegion> result = findIdInElement(element, file, targetAttribute,
                        requireIdAttribute);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    /** Parses the given file and locates a definition of the given resource */
    private static Pair<File, Integer> findValueInXml(ResourceType type, String name, File file) {
        // We can't use the StructureModelManager on files outside projects
        // There is no open or cached model for the file; see if the file looks
        // like it's interesting (content contains the String name we are looking for)
        if (AdtPlugin.fileContains(file, name)) {
            try {
                InputSource is = new InputSource(new FileInputStream(file));
                OffsetTrackingParser parser = new OffsetTrackingParser();
                parser.parse(is);
                Document document = parser.getDocument();

                return findValueInDocument(type, name, file, parser, document);
            } catch (SAXException e) {
                // pass -- ignore files we can't parse
            } catch (IOException e) {
                // pass -- ignore files we can't parse
            }
        }

        return null;
    }

    /** Looks within an XML DOM document for the given resource name and returns it */
    private static Pair<File, Integer> findValueInDocument(ResourceType type, String name,
            File file, OffsetTrackingParser parser, Document document) {
        String targetTag = type.getName();
        if (type == ResourceType.ID) {
            // Ids are recorded in <item> tags instead of <id> tags
            targetTag = "item"; //$NON-NLS-1$
        }

        Pair<File, Integer> result = findTag(name, file, parser, document, targetTag);
        if (result == null && type == ResourceType.ATTR) {
            // Attributes seem to be defined in <public> tags
            targetTag = "public"; //$NON-NLS-1$
            result = findTag(name, file, parser, document, targetTag);
        }
        return result;
    }

    private static Pair<File, Integer> findTag(String name, File file, OffsetTrackingParser parser,
            Document document, String targetTag) {
        NodeList children = document.getElementsByTagName(targetTag);
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) child;
                if (element.getTagName().equals(targetTag)) {
                    String elementName = element.getAttribute(ATTR_NAME);
                    if (elementName.equals(name)) {
                        return Pair.of(file, parser.getOffset(element));
                    }
                }
            }
        }

        return null;
    }

    private static IHyperlink[] getStyleLinks(XmlContext context, IRegion range, String url) {
        Attr attribute = context.getAttribute();
        if (attribute != null) {
            // Split up theme resource urls to the nearest dot forwards, such that you
            // can point to "Theme.Light" by placing the caret anywhere after the dot,
            // and point to just "Theme" by pointing before it.
            int caret = context.getInnerRegionCaretOffset();
            String value = attribute.getValue();
            int index = value.indexOf('.', caret);
            if (index != -1) {
                url = url.substring(0, index);
                range = new Region(range.getOffset(),
                        range.getLength() - (value.length() - index));
            }
        }

        ResourceUrl resource = ResourceUrl.parse(url);
        if (resource == null) {
            String androidStyle = ANDROID_STYLE_RESOURCE_PREFIX;
            if (url.startsWith(ANDROID_PREFIX)) {
                url = androidStyle + url.substring(ANDROID_PREFIX.length());
            } else if (url.startsWith(ANDROID_THEME_PREFIX)) {
                url = androidStyle + url.substring(ANDROID_THEME_PREFIX.length());
            } else if (url.startsWith(ANDROID_PKG + ':')) {
                url = androidStyle + url.substring(ANDROID_PKG.length() + 1);
            } else {
                url = STYLE_RESOURCE_PREFIX + url;
            }
        }
        return getResourceLinks(range, url);
    }

    private static IHyperlink[] getResourceLinks(@Nullable IRegion range, @NonNull String url) {
        IProject project = Hyperlinks.getProject();
        FolderConfiguration configuration = getConfiguration();
        return getResourceLinks(range, url, project, configuration);
    }

    /**
     * Computes hyperlinks to resource definitions for resource urls (e.g.
     * {@code @android:string/ok} or {@code @layout/foo}. May create multiple links.
     * @param range TBD
     * @param url the resource url
     * @param project the relevant project
     * @param configuration the applicable configuration
     * @return an array of hyperlinks, or null
     */
    @Nullable
    public static IHyperlink[] getResourceLinks(@Nullable IRegion range, @NonNull String url,
            @Nullable IProject project,  @Nullable FolderConfiguration configuration) {
        List<IHyperlink> links = new ArrayList<IHyperlink>();

        ResourceUrl resource = ResourceUrl.parse(url);
        if (resource == null) {
            return null;
        }
        ResourceType type = resource.type;
        String name = resource.name;
        boolean isFramework = resource.framework;
        if (project == null) {
            // Local reference *within* a framework
            isFramework = true;
        }

        ResourceRepository resources = getResources(project, isFramework);
        if (resources == null) {
            return null;
        }
        List<ResourceFile> sourceFiles = resources.getSourceFiles(type, name,
                null /*configuration*/);
        if (sourceFiles == null) {
            ProjectState projectState = Sdk.getProjectState(project);
            if (projectState != null) {
                List<IProject> libraries = projectState.getFullLibraryProjects();
                if (libraries != null && !libraries.isEmpty()) {
                    for (IProject library : libraries) {
                        resources = ResourceManager.getInstance().getProjectResources(library);
                        sourceFiles = resources.getSourceFiles(type, name, null /*configuration*/);
                        if (sourceFiles != null && !sourceFiles.isEmpty()) {
                            break;
                        }
                    }
                }
            }
        }

        ResourceFile best = null;
        if (configuration != null && sourceFiles != null && sourceFiles.size() > 0) {
            List<ResourceFile> bestFiles = resources.getSourceFiles(type, name, configuration);
            if (bestFiles != null && bestFiles.size() > 0) {
                best = bestFiles.get(0);
            }
        }
        if (sourceFiles != null) {
            List<ResourceFile> matches = new ArrayList<ResourceFile>();
            for (ResourceFile resourceFile : sourceFiles) {
                matches.add(resourceFile);
            }

            if (matches.size() > 0) {
                final ResourceFile fBest = best;
                Collections.sort(matches, new Comparator<ResourceFile>() {
                    @Override
                    public int compare(ResourceFile rf1, ResourceFile rf2) {
                        // Sort best item to the front
                        if (rf1 == fBest) {
                            return -1;
                        } else if (rf2 == fBest) {
                            return 1;
                        } else {
                            return getFileName(rf1).compareTo(getFileName(rf2));
                        }
                    }
                });

                // Is this something found in a values/ folder?
                boolean valueResource = ResourceHelper.isValueBasedResourceType(type);

                for (ResourceFile file : matches) {
                    String folderName = file.getFolder().getFolder().getName();
                    String label = String.format("Open Declaration in %1$s/%2$s",
                            folderName, getFileName(file));

                    // Only search for resource type within the file if it's an
                    // XML file and it is a value resource
                    ResourceLink link = new ResourceLink(label, range, file,
                            valueResource ? type : null, name);
                    links.add(link);
                }
            }
        }

        // Id's are handled specially because they are typically defined
        // inline (though they -can- be defined in the values folder above as
        // well, in which case we will prefer that definition)
        if (!isFramework && type == ResourceType.ID && links.size() == 0) {
            // Must compute these lazily...
            links.add(new ResourceLink("Open XML Declaration", range, null, type, name));
        }

        if (links.size() > 0) {
            return links.toArray(new IHyperlink[links.size()]);
        } else {
            return null;
        }
    }

    private static String getFileName(ResourceFile file) {
        return file.getFile().getName();
    }

    /** Detector for finding Android references in XML files */
   public static class XmlResolver extends AbstractHyperlinkDetector {

        @Override
        public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region,
                boolean canShowMultipleHyperlinks) {

            if (region == null || textViewer == null) {
                return null;
            }

            IDocument document = textViewer.getDocument();

            XmlContext context = XmlContext.find(document, region.getOffset());
            if (context == null) {
                return null;
            }

            IRegion range = context.getInnerRange(document);
            boolean isLinkable = false;
            String type = context.getInnerRegion().getType();
            if (type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
                if (isAttributeValueLink(context)) {
                    isLinkable = true;
                    // Strip out quotes
                    range = new Region(range.getOffset() + 1, range.getLength() - 2);

                    Attr attribute = context.getAttribute();
                    if (isStyleAttribute(context)) {
                        return getStyleLinks(context, range, attribute.getValue());
                    }
                    if (attribute != null
                            && (attribute.getValue().startsWith(PREFIX_RESOURCE_REF)
                                    || attribute.getValue().startsWith(PREFIX_THEME_REF))) {
                        // Instantly create links for resources since we can use the existing
                        // resolved maps for this and offer multiple choices for the user
                        String url = attribute.getValue();
                        return getResourceLinks(range, url);
                    }
                }
            } else if (type == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
                if (isAttributeNameLink(context)) {
                    isLinkable = true;
                }
            } else if (type == DOMRegionContext.XML_TAG_NAME) {
                if (isElementNameLink(context)) {
                    isLinkable = true;
                }
            } else if (type == DOMRegionContext.XML_CONTENT) {
                Node parentNode = context.getNode().getParentNode();
                if (parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE) {
                    // Try to complete resources defined inline as text, such as
                    // style definitions
                    ITextRegion outer = context.getElementRegion();
                    ITextRegion inner = context.getInnerRegion();
                    int innerOffset = outer.getStart() + inner.getStart();
                    int caretOffset = innerOffset + context.getInnerRegionCaretOffset();
                    try {
                        IRegion lineInfo = document.getLineInformationOfOffset(caretOffset);
                        int lineStart = lineInfo.getOffset();
                        int lineEnd = Math.min(lineStart + lineInfo.getLength(),
                                innerOffset + inner.getLength());

                        // Compute the resource URL
                        int urlStart = -1;
                        int offset = caretOffset;
                        while (offset > lineStart) {
                            char c = document.getChar(offset);
                            if (c == '@' || c == '?') {
                                urlStart = offset;
                                break;
                            } else if (!isValidResourceUrlChar(c)) {
                                break;
                            }
                            offset--;
                        }

                        if (urlStart != -1) {
                            offset = caretOffset;
                            while (offset < lineEnd) {
                                if (!isValidResourceUrlChar(document.getChar(offset))) {
                                    break;
                                }
                                offset++;
                            }

                            int length = offset - urlStart;
                            String url = document.get(urlStart, length);
                            range = new Region(urlStart, length);
                            return getResourceLinks(range, url);
                        }
                    } catch (BadLocationException e) {
                        AdtPlugin.log(e, null);
                    }
                }
            }

            if (isLinkable) {
                IHyperlink hyperlink = new DeferredResolutionLink(context, range);
                if (hyperlink != null) {
                    return new IHyperlink[] {
                        hyperlink
                    };
                }
            }

            return null;
        }
    }

    private static boolean isValidResourceUrlChar(char c) {
        return Character.isJavaIdentifierPart(c) || c == ':' || c == '/' || c == '.' || c == '+';

    }

    /** Detector for finding Android references in Java files */
    public static class JavaResolver extends AbstractHyperlinkDetector {

        @Override
        public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region,
                boolean canShowMultipleHyperlinks) {
            // Most of this is identical to the builtin JavaElementHyperlinkDetector --
            // everything down to the Android R filtering below

            ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);
            if (region == null || !(textEditor instanceof JavaEditor))
                return null;

            IAction openAction = textEditor.getAction("OpenEditor"); //$NON-NLS-1$
            if (!(openAction instanceof SelectionDispatchAction))
                return null;

            int offset = region.getOffset();

            IJavaElement input = EditorUtility.getEditorInputJavaElement(textEditor, false);
            if (input == null)
                return null;

            try {
                IDocument document = textEditor.getDocumentProvider().getDocument(
                        textEditor.getEditorInput());
                IRegion wordRegion = JavaWordFinder.findWord(document, offset);
                if (wordRegion == null || wordRegion.getLength() == 0)
                    return null;

                IJavaElement[] elements = null;
                elements = ((ICodeAssist) input).codeSelect(wordRegion.getOffset(), wordRegion
                        .getLength());

                // Specific Android R class filtering:
                if (elements.length > 0) {
                    IJavaElement element = elements[0];
                    if (element.getElementType() == IJavaElement.FIELD) {
                        IJavaElement unit = element.getAncestor(IJavaElement.COMPILATION_UNIT);
                        if (unit == null) {
                            // Probably in a binary; see if this is an android.R resource
                            IJavaElement type = element.getAncestor(IJavaElement.TYPE);
                            if (type != null && type.getParent() != null) {
                                IJavaElement parentType = type.getParent();
                                if (parentType.getElementType() == IJavaElement.CLASS_FILE) {
                                    String pn = parentType.getElementName();
                                    String prefix = FN_RESOURCE_BASE + "$"; //$NON-NLS-1$
                                    if (pn.startsWith(prefix)) {
                                        return createTypeLink(element, type, wordRegion, true);
                                    }
                                }
                            }
                        } else if (FN_RESOURCE_CLASS.equals(unit.getElementName())) {
                            // Yes, we're referencing the project R class.
                            // Offer hyperlink navigation to XML resource files for
                            // the various definitions
                            IJavaElement type = element.getAncestor(IJavaElement.TYPE);
                            if (type != null) {
                                return createTypeLink(element, type, wordRegion, false);
                            }
                        }
                    }

                }
                return null;
            } catch (JavaModelException e) {
                return null;
            }
        }

        private IHyperlink[] createTypeLink(IJavaElement element, IJavaElement type,
                IRegion wordRegion, boolean isFrameworkResource) {
            String typeName = type.getElementName();
            // typeName will be "id", "layout", "string", etc
            if (isFrameworkResource) {
                typeName = ANDROID_PKG + ':' + typeName;
            }
            String elementName = element.getElementName();
            String url = '@' + typeName + '/' + elementName;
            return getResourceLinks(wordRegion, url);
        }
    }

    /** Returns the editor applicable to this hyperlink detection */
    private static IEditorPart getEditor() {
        // I would like to be able to find this via getAdapter(TextEditor.class) but
        // couldn't find a way to initialize the editor context from
        // AndroidSourceViewerConfig#getHyperlinkDetectorTargets (which only has
        // a TextViewer, not a TextEditor, instance).
        //
        // Therefore, for now, use a hack. This hack is reasonable because hyperlink
        // resolvers are only run for the front-most visible window in the active
        // workbench.
        return AdtUtils.getActiveEditor();
    }

    /** Returns the project applicable to this hyperlink detection */
    @Nullable
    private static IProject getProject() {
        IFile file = AdtUtils.getActiveFile();
        if (file != null) {
            return file.getProject();
        }

        return null;
    }

    /**
     * Hyperlink implementation which delays computing the actual file and offset target
     * until it is asked to open the hyperlink
     */
    private static class DeferredResolutionLink implements IHyperlink {
        private XmlContext mXmlContext;
        private IRegion mRegion;

        public DeferredResolutionLink(XmlContext xmlContext, IRegion mRegion) {
            super();
            this.mXmlContext = xmlContext;
            this.mRegion = mRegion;
        }

        @Override
        public IRegion getHyperlinkRegion() {
            return mRegion;
        }

        @Override
        public String getHyperlinkText() {
            return "Open XML Declaration";
        }

        @Override
        public String getTypeLabel() {
            return null;
        }

        @Override
        public void open() {
            // Lazily compute the location to open
            if (mXmlContext != null && !Hyperlinks.open(mXmlContext)) {
                // Failed: display message to the user
                displayError("Could not open link");
            }
        }
    }

    /**
     * Hyperlink implementation which provides a link for a resource; the actual file name
     * is known, but the value location within XML files is deferred until the link is
     * actually opened.
     */
    static class ResourceLink implements IHyperlink {
        private final String mLinkText;
        private final IRegion mLinkRegion;
        private final ResourceType mType;
        private final String mName;
        private final ResourceFile mFile;

        /**
         * Constructs a new {@link ResourceLink}.
         *
         * @param linkText the description of the link to be shown in a popup when there
         *            is more than one match
         * @param linkRegion the region corresponding to the link source highlight
         * @param file the target resource file containing the link definition
         * @param type the type of resource being linked to
         * @param name the name of the resource being linked to
         */
        public ResourceLink(String linkText, IRegion linkRegion, ResourceFile file,
                ResourceType type, String name) {
            super();
            mLinkText = linkText;
            mLinkRegion = linkRegion;
            mType = type;
            mName = name;
            mFile = file;
        }

        @Override
        public IRegion getHyperlinkRegion() {
            return mLinkRegion;
        }

        @Override
        public String getHyperlinkText() {
            // return "Open XML Declaration";
            return mLinkText;
        }

        @Override
        public String getTypeLabel() {
            return null;
        }

        @Override
        public void open() {
            // We have to defer computation of ids until the link is clicked since we
            // don't have a fast map lookup for these
            if (mFile == null && mType == ResourceType.ID) {
                // Id's are handled specially because they are typically defined
                // inline (though they -can- be defined in the values folder above as well,
                // in which case we will prefer that definition)
                IProject project = getProject();
                Pair<IFile,IRegion> def = findIdDefinition(project, mName);
                if (def != null) {
                    try {
                        AdtPlugin.openFile(def.getFirst(), def.getSecond());
                    } catch (PartInitException e) {
                        AdtPlugin.log(e, null);
                    }
                    return;
                }

                displayError(String.format("Could not find id %1$s", mName));
                return;
            }

            IAbstractFile wrappedFile = mFile != null ? mFile.getFile() : null;
            if (wrappedFile instanceof IFileWrapper) {
                IFile file = ((IFileWrapper) wrappedFile).getIFile();
                try {
                    // Lazily search for the target?
                    IRegion region = null;
                    String extension = file.getFileExtension();
                    if (mType != null && mName != null && EXT_XML.equals(extension)) {
                        Pair<IFile, IRegion> target;
                        if (mType == ResourceType.ID) {
                            target = findIdInXml(mName, file);
                        } else {
                            target = findValueInXml(mType, mName, file);
                        }
                        if (target != null) {
                            region = target.getSecond();
                        }
                    }
                    AdtPlugin.openFile(file, region);
                } catch (PartInitException e) {
                    AdtPlugin.log(e, null);
                }
            } else if (wrappedFile instanceof FileWrapper) {
                File file = ((FileWrapper) wrappedFile);
                IPath path = new Path(file.getAbsolutePath());
                int offset = 0;
                // Lazily search for the target?
                if (mType != null && mName != null && EXT_XML.equals(path.getFileExtension())) {
                    if (file.exists()) {
                        Pair<File, Integer> target = findValueInXml(mType, mName, file);
                        if (target != null && target.getSecond() != null) {
                            offset = target.getSecond();
                        }
                    }
                }
                openPath(path, null, offset);
            } else {
                throw new IllegalArgumentException("Invalid link parameters");
            }
        }

        ResourceFile getFile() {
            return mFile;
        }
    }

    /**
     * XML context containing node, potentially attribute, and text regions surrounding a
     * particular caret offset
     */
    private static class XmlContext {
        private final Node mNode;
        private final Element mElement;
        private final Attr mAttribute;
        private final IStructuredDocumentRegion mOuterRegion;
        private final ITextRegion mInnerRegion;
        private final int mInnerRegionOffset;

        public XmlContext(Node node, Element element, Attr attribute,
                IStructuredDocumentRegion outerRegion,
                ITextRegion innerRegion, int innerRegionOffset) {
            super();
            mNode = node;
            mElement = element;
            mAttribute = attribute;
            mOuterRegion = outerRegion;
            mInnerRegion = innerRegion;
            mInnerRegionOffset = innerRegionOffset;
        }

        /**
         * Gets the current node, never null
         *
         * @return the surrounding node
         */
        public Node getNode() {
            return mNode;
        }


        /**
         * Gets the current node, may be null
         *
         * @return the surrounding node
         */
        public Element getElement() {
            return mElement;
        }

        /**
         * Returns the current attribute, or null if we are not over an attribute
         *
         * @return the attribute, or null
         */
        public Attr getAttribute() {
            return mAttribute;
        }

        /**
         * Gets the region of the element
         *
         * @return the region of the surrounding element, never null
         */
        public ITextRegion getElementRegion() {
            return mOuterRegion;
        }

        /**
         * Gets the inner region, which can be the tag name, an attribute name, an
         * attribute value, or some other portion of an XML element
         * @return the inner region, never null
         */
        public ITextRegion getInnerRegion() {
            return mInnerRegion;
        }

        /**
         * Gets the caret offset relative to the inner region
         *
         * @return the offset relative to the inner region
         */
        public int getInnerRegionCaretOffset() {
            return mInnerRegionOffset;
        }

        /**
         * Returns a range with suffix whitespace stripped out
         *
         * @param document the document containing the regions
         * @return the range of the inner region, minus any whitespace at the end
         */
        public IRegion getInnerRange(IDocument document) {
            int start = mOuterRegion.getStart() + mInnerRegion.getStart();
            int length = mInnerRegion.getLength();
            try {
                String s = document.get(start, length);
                for (int i = s.length() - 1; i >= 0; i--) {
                    if (Character.isWhitespace(s.charAt(i))) {
                        length--;
                    }
                }
            } catch (BadLocationException e) {
                AdtPlugin.log(e, ""); //$NON-NLS-1$
            }
            return new Region(start, length);
        }

        /**
         * Returns the node the cursor is currently on in the document. null if no node is
         * selected
         */
        private static XmlContext find(IDocument document, int offset) {
            // Loosely based on getCurrentNode and getCurrentAttr in the WST's
            // XMLHyperlinkDetector.
            IndexedRegion inode = null;
            IStructuredModel model = null;
            try {
                model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
                if (model != null) {
                    inode = model.getIndexedRegion(offset);
                    if (inode == null) {
                        inode = model.getIndexedRegion(offset - 1);
                    }

                    if (inode instanceof Element) {
                        Element element = (Element) inode;
                        Attr attribute = null;
                        if (element.hasAttributes()) {
                            NamedNodeMap attrs = element.getAttributes();
                            // go through each attribute in node and if attribute contains
                            // offset, return that attribute
                            for (int i = 0; i < attrs.getLength(); ++i) {
                                // assumption that if parent node is of type IndexedRegion,
                                // then its attributes will also be of type IndexedRegion
                                IndexedRegion attRegion = (IndexedRegion) attrs.item(i);
                                if (attRegion.contains(offset)) {
                                    attribute = (Attr) attrs.item(i);
                                    break;
                                }
                            }
                        }

                        IStructuredDocument doc = model.getStructuredDocument();
                        IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(offset);
                        if (region != null
                                && DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
                            ITextRegion subRegion = region.getRegionAtCharacterOffset(offset);
                            if (subRegion == null) {
                                return null;
                            }
                            int regionStart = region.getStartOffset();
                            int subregionStart = subRegion.getStart();
                            int relativeOffset = offset - (regionStart + subregionStart);
                            return new XmlContext(element, element, attribute, region, subRegion,
                                    relativeOffset);
                        }
                    } else if (inode instanceof Node) {
                        IStructuredDocument doc = model.getStructuredDocument();
                        IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(offset);
                        if (region != null
                                && DOMRegionContext.XML_CONTENT.equals(region.getType())) {
                            ITextRegion subRegion = region.getRegionAtCharacterOffset(offset);
                            int regionStart = region.getStartOffset();
                            int subregionStart = subRegion.getStart();
                            int relativeOffset = offset - (regionStart + subregionStart);
                            return new XmlContext((Node) inode, null, null, region, subRegion,
                                    relativeOffset);
                        }

                    }
                }
            } finally {
                if (model != null) {
                    model.releaseFromRead();
                }
            }

            return null;
        }
    }

    /**
     * DOM parser which records offsets in the element nodes such that it can return
     * offsets for elements later
     */
    private static final class OffsetTrackingParser extends DOMParser {

        private static final String KEY_OFFSET = "offset"; //$NON-NLS-1$

        private static final String KEY_NODE =
            "http://apache.org/xml/properties/dom/current-element-node"; //$NON-NLS-1$

        private XMLLocator mLocator;

        public OffsetTrackingParser() throws SAXException {
            this.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",//$NON-NLS-1$
                    false);
        }

        public int getOffset(Node node) {
            Integer offset = (Integer) node.getUserData(KEY_OFFSET);
            if (offset != null) {
                return offset;
            }

            return -1;
        }

        @Override
        public void startElement(QName elementQName, XMLAttributes attrList, Augmentations augs)
                throws XNIException {
            int offset = mLocator.getCharacterOffset();
            super.startElement(elementQName, attrList, augs);

            try {
                Node node = (Node) this.getProperty(KEY_NODE);
                if (node != null) {
                    node.setUserData(KEY_OFFSET, offset, null);
                }
            } catch (org.xml.sax.SAXException ex) {
                AdtPlugin.log(ex, ""); //$NON-NLS-1$
            }
        }

        @Override
        public void startDocument(XMLLocator locator, String encoding,
                NamespaceContext namespaceContext, Augmentations augs) throws XNIException {
            super.startDocument(locator, encoding, namespaceContext, augs);
            mLocator = locator;
        }
    }
}
