/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.tools.lint.checks;

import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_DISCARD;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_KEEP;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_PARENT;
import static com.android.SdkConstants.ATTR_SHRINK_MODE;
import static com.android.SdkConstants.ATTR_TYPE;
import static com.android.SdkConstants.PREFIX_ANDROID;
import static com.android.SdkConstants.PREFIX_BINDING_EXPR;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.SdkConstants.PREFIX_TWOWAY_BINDING_EXPR;
import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.TAG_ITEM;
import static com.android.SdkConstants.TAG_LAYOUT;
import static com.android.SdkConstants.TAG_STYLE;
import static com.android.SdkConstants.TOOLS_URI;
import static com.android.SdkConstants.VALUE_SAFE;
import static com.android.SdkConstants.VALUE_STRICT;
import static com.android.utils.SdkUtils.endsWithIgnoreCase;
import static com.google.common.base.Charsets.UTF_8;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.resources.ResourceUrl;
import com.android.resources.FolderTypeRelationship;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.tools.lint.client.api.DefaultConfiguration;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.tools.lint.detector.api.Location;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;

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 java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * A model for Android resource declarations and usages
 */
public class ResourceUsageModel {
    private static final int TYPICAL_RESOURCE_COUNT = 200;

    /** List of all known resources (parsed from R.java) */
    private final List<Resource> mResources = Lists.newArrayListWithExpectedSize(TYPICAL_RESOURCE_COUNT);
    /** Map from resource type to map from resource name to resource object */
    private final Map<ResourceType, Map<String, Resource>> mTypeToName =
            Maps.newEnumMap(ResourceType.class);
    /** Map from R field value to corresponding resource */
    private final Map<Integer, Resource> mValueToResource =
            Maps.newHashMapWithExpectedSize(TYPICAL_RESOURCE_COUNT);

    public static String getFieldName(Element element) {
        return LintUtils.getFieldName(element.getAttribute(ATTR_NAME));
    }

    public static ResourceType getResourceType(Element element) {
        String tagName = element.getTagName();
        if (tagName.equals(TAG_ITEM)) {
            String typeName = element.getAttribute(ATTR_TYPE);
            if (!typeName.isEmpty()) {
                return ResourceType.getEnum(typeName);
            }
        } else if ("string-array".equals(tagName) || "integer-array".equals(tagName)) {
            return ResourceType.ARRAY;
        } else {
            return ResourceType.getEnum(tagName);
        }
        return null;
    }

    @Nullable
    public Resource getResource(Element element) {
        return getResource(element, false);
    }

    public Resource getResource(Element element, boolean declare) {
        ResourceType type = getResourceType(element);
        if (type != null) {
            String name = getFieldName(element);
            Resource resource = getResource(type, name);
            if (resource == null && declare) {
                resource = addResource(type, name, null);
                resource.setDeclared(true);
            }
            return resource;
        }

        return null;
    }

    @SuppressWarnings("unused") // Used by (temporary) copy in Gradle resource shrinker
    @Nullable
    public Resource getResource(@NonNull Integer value) {
        return mValueToResource.get(value);
    }

    @Nullable
    public Resource getResource(@NonNull ResourceType type, @NonNull String name) {
        Map<String, Resource> nameMap = mTypeToName.get(type);
        if (nameMap != null) {
            return nameMap.get(LintUtils.getFieldName(name));
        }
        return null;
    }

    @Nullable
    Resource getResourceFromUrl(@NonNull String possibleUrlReference) {
        ResourceUrl url = ResourceUrl.parse(possibleUrlReference);
        if (url != null && !url.framework) {
            return addResource(url.type, LintUtils.getFieldName(url.name), null);
        }

        return null;
    }

    private static final String ANDROID_RES = "android_res/";

    @Nullable
    public Resource getResourceFromFilePath(@NonNull String url) {
        int nameSlash = url.lastIndexOf('/');
        if (nameSlash == -1) {
            return null;
        }

        // Look for
        //   (1) a full resource URL: /android_res/type/name.ext
        //   (2) a partial URL that uniquely identifies a given resource: drawable/name.ext
        // e.g. file:///android_res/drawable/bar.png
        int androidRes = url.indexOf(ANDROID_RES);
        if (androidRes != -1) {
            androidRes += ANDROID_RES.length();
            int slash = url.indexOf('/', androidRes);
            if (slash != -1) {
                String folderName = url.substring(androidRes, slash);
                ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
                if (folderType != null) {
                    List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(
                            folderType);
                    if (!types.isEmpty()) {
                        ResourceType type = types.get(0);
                        int nameBegin = slash + 1;
                        int dot = url.indexOf('.', nameBegin);
                        String name = url.substring(nameBegin, dot != -1 ? dot : url.length());
                        return getResource(type, name);
                    }
                }
            }
        }

        // Some other relative path. Just look from the end:
        int typeSlash = url.lastIndexOf('/', nameSlash - 1);
        ResourceType type = ResourceType.getEnum(url.substring(typeSlash + 1, nameSlash));
        if (type != null) {
            int nameBegin = nameSlash + 1;
            int dot = url.indexOf('.', nameBegin);
            String name = url.substring(nameBegin, dot != -1 ? dot : url.length());
            return getResource(type, name);
        }

        return null;
    }

    /**
     * Marks the given resource (if non-null) as reachable, and returns true if
     * this is the first time the resource is marked reachable
     */
    public static boolean markReachable(@Nullable Resource resource) {
        if (resource != null) {
            boolean wasReachable = resource.isReachable();
            resource.setReachable(true);
            return !wasReachable;
        }

        return false;
    }

    private static void markUnreachable(@Nullable Resource resource) {
        if (resource != null) {
            resource.setReachable(false);
        }
    }


    public void recordManifestUsages(Node node) {
        short nodeType = node.getNodeType();
        if (nodeType == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            NamedNodeMap attributes = element.getAttributes();
            for (int i = 0, n = attributes.getLength(); i < n; i++) {
                Attr attr = (Attr) attributes.item(i);
                markReachable(getResourceFromUrl(attr.getValue()));
            }
        } else if (nodeType == Node.TEXT_NODE) {
            // Does this apply to any manifests??
            String text = node.getNodeValue().trim();
            markReachable(getResourceFromUrl(text));
        }

        NodeList children = node.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            recordManifestUsages(child);
        }
    }

    private static final int RESOURCE_DECLARED =    1 << 1;
    private static final int RESOURCE_PUBLIC =      1 << 2;
    private static final int RESOURCE_KEEP =        1 << 3;
    private static final int RESOURCE_DISCARD =     1 << 4;
    private static final int RESOURCE_REACHABLE =   1 << 5;

    public static class Resource implements Comparable<Resource> {
        private int mFlags;

        /** Type of resource */
        public final ResourceType type;
        /** Name of resource */
        public final String name;
        /** Integer id location */
        public int value;

        /** Resources this resource references. For example, a layout can reference another via
         * an include; a style reference in a layout references that layout style, and so on. */
        public List<Resource> references;

        /** Chained list of declaration locations */
        public Location locations;
        public List<File> declarations;

        /** Whether we found a declaration for this resource (otherwise we might have seen
         * a reference to this before we came across its potential declaration, so we added it
         * to the map, but we don't want to report unused resources for invalid resource
         * references */
        public boolean isDeclared() {
            return (mFlags & RESOURCE_DECLARED) != 0;
        }

        /** Whether we found a declaration for this resource (otherwise we might have seen
         * a reference to this before we came across its potential declaration, so we added it
         * to the map, but we don't want to report unused resources for invalid resource
         * references */
        public void setDeclared(boolean on) {
            mFlags = on ? (mFlags | RESOURCE_DECLARED) : (mFlags & ~RESOURCE_DECLARED);
        }

        /** This resource is marked as public */
        public boolean isPublic() {
            return (mFlags & RESOURCE_PUBLIC) != 0;
        }

        /** This resource is marked as public */
        public void setPublic(boolean on) {
            mFlags = on ? (mFlags | RESOURCE_PUBLIC) : (mFlags & ~RESOURCE_PUBLIC);
        }

        /** This resource is marked as to be ignored for usage analysis, regardless of
         * references */
        public boolean isKeep() {
            return (mFlags & RESOURCE_KEEP) != 0;
        }

        /** This resource is marked as to be ignored for usage analysis, regardless of
         * references */
        public void setKeep(boolean on) {
            mFlags = on ? (mFlags | RESOURCE_KEEP) : (mFlags & ~RESOURCE_KEEP);
        }

        /** This resource is marked as to be ignored for usage analysis, regardless of lack of
         * references */
        public boolean isDiscard() {
            return (mFlags & RESOURCE_DISCARD) != 0;
        }

        /** This resource is marked as to be ignored for usage analysis, regardless of lack of
         * references */
        public void setDiscard(boolean on) {
            mFlags = on ? (mFlags | RESOURCE_DISCARD) : (mFlags & ~RESOURCE_DISCARD);
        }

        public boolean isReachable() {
            return (mFlags & RESOURCE_REACHABLE) != 0;
        }

        public void setReachable(boolean on) {
            mFlags = on ? (mFlags | RESOURCE_REACHABLE) : (mFlags & ~RESOURCE_REACHABLE);
        }

        public Resource(ResourceType type, String name, int value) {
            this.type = type;
            this.name = name;
            this.value = value;
        }

        @Override
        public String toString() {
            return type + ":" + name + ":" + value;
        }

        @SuppressWarnings("RedundantIfStatement") // Generated by IDE
        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            Resource resource = (Resource) o;

            if (name != null ? !name.equals(resource.name) : resource.name != null) {
                return false;
            }
            if (type != resource.type) {
                return false;
            }

            return true;
        }

        @Override
        public int hashCode() {
            int result = type != null ? type.hashCode() : 0;
            result = 31 * result + (name != null ? name.hashCode() : 0);
            return result;
        }

        public void addLocation(@NonNull File file) {
            if (declarations == null) {
                declarations = Lists.newArrayList();
            }
            declarations.add(file);
        }

        public void recordLocation(@NonNull Location location) {
            Location oldLocation = this.locations;
            if (oldLocation != null) {
                location.setSecondary(oldLocation);
            }
            this.locations = location;
        }

        public void addReference(@Nullable Resource resource) {
            if (resource != null) {
                if (references == null) {
                    references = Lists.newArrayList();
                } else if (references.contains(resource)) {
                    return;
                }
                references.add(resource);
            }
        }

        public String getUrl() {
            return '@' + type.getName() + '/' + name;
        }

        public String getField() {
            return "R." + type.getName() + '.' + name;
        }

        @Override
        public int compareTo(@NonNull Resource other) {
            if (type != other.type) {
                return type.compareTo(other.type);
            }

            return name.compareTo(other.name);
        }
    }

    public List<Resource> findUnused() {
        return findUnused(mResources);
    }

    public String dumpReferences() {
        StringBuilder sb = new StringBuilder(1000);
        sb.append("Resource Reference Graph:\n");
        for (Resource resource : mResources) {
            if (resource.references != null) {
                sb.append(resource).append(" => ").append(resource.references).append('\n');
            }
        }
        return sb.toString();
    }


    public String dumpResourceModel() {
        StringBuilder sb = new StringBuilder(1000);
        Collections.sort(mResources, new Comparator<Resource>() {
            @Override
            public int compare(Resource resource1,
                    Resource resource2) {
                int delta = resource1.type.compareTo(resource2.type);
                if (delta != 0) {
                    return delta;
                }
                return resource1.name.compareTo(resource2.name);
            }
        });

        for (Resource resource : mResources) {
            sb.append(resource.getUrl()).append(" : reachable=").append(resource.isReachable());
            sb.append("\n");
            if (resource.references != null) {
                for (Resource referenced : resource.references) {
                    sb.append("    ");
                    sb.append(referenced.getUrl());
                    sb.append("\n");
                }
            }
        }

        return sb.toString();
    }

    public List<Resource> findUnused(List<Resource> resources) {
        List<Resource> roots = findRoots(resources);

        Map<Resource,Boolean> seen = new IdentityHashMap<Resource,Boolean>(resources.size());
        for (Resource root : roots) {
            visit(root, seen);
        }

        List<Resource> unused = Lists.newArrayListWithExpectedSize(resources.size());
        for (Resource resource : resources) {
            if (!resource.isReachable()
                    // Styles not yet handled correctly: don't mark as unused
                    && resource.type != ResourceType.ATTR
                    && resource.type != ResourceType.DECLARE_STYLEABLE
                    // Don't flag known service keys read by library
                    && !TranslationDetector.isServiceKey(resource.name)) {
                unused.add(resource);
            }
        }

        return unused;
    }

    @SuppressWarnings("MethodMayBeStatic")
    @NonNull
    protected List<Resource> findRoots(@NonNull List<Resource> resources) {
        List<Resource> roots = Lists.newArrayList();

        for (Resource resource : resources) {
            if (resource.isReachable() || resource.isKeep()) {
                roots.add(resource);
            }
        }
        return roots;
    }

    private static void visit(Resource root, Map<Resource, Boolean> seen) {
        if (seen.containsKey(root)) {
            return;
        }
        seen.put(root, Boolean.TRUE);
        root.setReachable(true);
        if (root.references != null) {
            for (Resource referenced : root.references) {
                visit(referenced, seen);
            }
        }
    }

    @NonNull
    public Resource addDeclaredResource(@NonNull ResourceType type, @NonNull String name,
            @Nullable String value, boolean declared) {
        Resource resource = addResource(type, name, value);
        if (declared) {
            resource.setDeclared(true);
        }
        return resource;
    }

    @NonNull
    public Resource addResource(@NonNull ResourceType type, @NonNull String name,
            @Nullable String value) {
        int realValue = value != null ? Integer.decode(value) : -1;
        Resource resource = getResource(type, name);
        if (resource != null) {
            //noinspection VariableNotUsedInsideIf
            if (value != null) {
                if (resource.value == -1) {
                    resource.value = realValue;
                } else {
                    assert realValue == resource.value;
                }
            }
            return resource;
        }

        resource = new Resource(type, name, realValue);
        mResources.add(resource);
        if (realValue != -1) {
            mValueToResource.put(realValue, resource);
        }
        Map<String, Resource> nameMap = mTypeToName.get(type);
        if (nameMap == null) {
            nameMap = Maps.newHashMapWithExpectedSize(30);
            mTypeToName.put(type, nameMap);
        }
        nameMap.put(name, resource);

        // TODO: Assert that we don't set the same resource multiple times to different values.
        // Could happen if you pass in stale data!

        return resource;
    }

    /**
     * Called for a tools:keep attribute containing a resource URL where that resource name
     * is not referencing a known resource
     *
     * @param value The keep value
     */
    private void processKeepAttributes(@NonNull String value) {
        // TODO: When nothing matches one of these attributes, mark it as unused too!
        // Handle comma separated lists of URLs and globs
        if (value.indexOf(',') != -1) {
            for (String portion : Splitter.on(',').omitEmptyStrings().trimResults().split(value)) {
                processKeepAttributes(portion);
            }
            return;
        }

        ResourceUrl url = ResourceUrl.parse(value);
        if (url == null || url.framework) {
            return;
        }

        Resource resource = getResource(url.type, url.name);
        if (resource != null) {
            markReachable(resource);
        } else if (url.name.contains("*") || url.name.contains("?")) {
            // Look for globbing patterns
            String regexp = DefaultConfiguration.globToRegexp(LintUtils.getFieldName(url.name));
            try {
                Pattern pattern = Pattern.compile(regexp);
                Map<String, Resource> nameMap = mTypeToName.get(url.type);
                if (nameMap != null) {
                    for (Resource r : nameMap.values()) {
                        if (pattern.matcher(r.name).matches()) {
                            markReachable(r);
                        }
                    }
                }
            } catch (PatternSyntaxException ignored) {
            }
        }
    }

    private void processDiscardAttributes(@NonNull String value) {
        // Handle comma separated lists of URLs and globs
        if (value.indexOf(',') != -1) {
            for (String portion : Splitter.on(',').omitEmptyStrings().trimResults().split(value)) {
                processDiscardAttributes(portion);
            }
            return;
        }

        ResourceUrl url = ResourceUrl.parse(value);
        if (url == null || url.framework) {
            return;
        }

        Resource resource = getResource(url.type, url.name);
        if (resource != null) {
            markUnreachable(resource);
        } else if (url.name.contains("*") || url.name.contains("?")) {
            // Look for globbing patterns
            String regexp = DefaultConfiguration.globToRegexp(LintUtils.getFieldName(url.name));
            try {
                Pattern pattern = Pattern.compile(regexp);
                Map<String, Resource> nameMap = mTypeToName.get(url.type);
                if (nameMap != null) {
                    for (Resource r : nameMap.values()) {
                        if (pattern.matcher(r.name).matches()) {
                            markUnreachable(r);
                        }
                    }
                }
            } catch (PatternSyntaxException ignored) {
            }
        }
    }

    /**
     * Recorded list of keep attributes: these can contain wildcards,
     * so they can't be applied immediately; we have to apply them after
     * scanning through all resources (done by {@link #processToolsAttributes()}
     */
    private List<String> mKeepAttributes;

    /**
     * Recorded list of discard attributes: these can contain wildcards,
     * so they can't be applied immediately; we have to apply them after
     * scanning through all resources (done by {@link #processToolsAttributes()}
     */
    private List<String> mDiscardAttributes;

    private boolean mSafeMode = true;

    /**
     * Whether we should attempt to guess resources that should be kept based on looking
     * at the string pool and assuming some of the strings can be used to dynamically construct
     * the resource names. Can be turned off via {@code tools:shrinkMode="strict"}.
     */
    public boolean isSafeMode() {
        return mSafeMode;
    }

    public void processToolsAttributes() {
        if (mKeepAttributes != null) {
            for (String keep : mKeepAttributes) {
                processKeepAttributes(keep);
            }
        }
        if (mDiscardAttributes != null) {
            for (String discard : mDiscardAttributes) {
                processDiscardAttributes(discard);
            }
        }
    }

    public void recordToolsAttributes(@Nullable Attr attr) {
        if (attr == null) {
            return;
        }
        String localName = attr.getLocalName();
        String value = attr.getValue();
        if (ATTR_KEEP.equals(localName)) {
            if (mKeepAttributes == null) {
                mKeepAttributes = Lists.newArrayList();
            }
            mKeepAttributes.add(value);
        } else if (ATTR_DISCARD.equals(localName)) {
            if (mDiscardAttributes == null) {
                mDiscardAttributes = Lists.newArrayList();
            }
            mDiscardAttributes.add(value);
        } else if (ATTR_SHRINK_MODE.equals(localName)) {
            if (VALUE_STRICT.equals(value)) {
                mSafeMode = false;
            } else if (VALUE_SAFE.equals(value)) {
                mSafeMode = true;
            }
        }
    }

    protected Resource declareResource(ResourceType type, String name, Node node) {
        return addDeclaredResource(type, name, null, true);
    }

    @NonNull
    protected String readText(@NonNull File file) {
        try {
            return Files.toString(file, UTF_8);
        } catch (IOException ignore) {
            return "";
        }
    }

    public void visitBinaryResource(
            @Nullable ResourceFolderType folderType,
            @NonNull File file) {
        Resource from = null;
        if (folderType != ResourceFolderType.VALUES) {
            // Record resource for the whole file
            List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(
                    folderType);
            ResourceType type = types.get(0);
            assert type != ResourceType.ID : folderType;
            String name = LintUtils.getBaseName(file.getName());
            from = declareResource(type, name, null);
        }

        if (folderType == ResourceFolderType.RAW) {
            // Is this an HTML, CSS or JavaScript document bundled with the app?
            // If so tokenize and look for resource references.
            String path = file.getPath();
            if (endsWithIgnoreCase(path, ".html") || endsWithIgnoreCase(path, ".htm")) {
                tokenizeHtml(from, readText(file));
            } else if (endsWithIgnoreCase(path, ".css")) {
                tokenizeCss(from, readText(file));
            } else if (endsWithIgnoreCase(path, ".js")) {
                tokenizeJs(from, readText(file));
            } else if (file.isFile() && !LintUtils.isBitmapFile(file)) {
                tokenizeUnknownBinary(from, file);
            }
        }
    }

    public void visitXmlDocument(
            @NonNull File file,
            @Nullable ResourceFolderType folderType,
            @NonNull Document document) {
        if (folderType == null) {
            // Manifest file
            recordManifestUsages(document.getDocumentElement());
            return;
        }
        Resource from = null;
        if (folderType != ResourceFolderType.VALUES) {
            // Record resource for the whole file
            List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(
                    folderType);
            ResourceType type = types.get(0);
            assert type != ResourceType.ID : folderType;
            String name = LintUtils.getBaseName(file.getName());

            from = declareResource(type, name, document.getDocumentElement());
        } else if (isAnalyticsFile(file)) {
            return;
        }

        // For value files, and drawables and colors etc also pull in resource
        // references inside the context.file
        recordResourceReferences(folderType, document.getDocumentElement(), from);

        if (folderType == ResourceFolderType.XML) {
            tokenizeUnknownText(readText(file));
        }
    }

    private static final String ANALYTICS_FILE = "analytics.xml"; //$NON-NLS-1$

    /**
     * Returns true if this XML file corresponds to an Analytics configuration file;
     * these contain some attributes read by the library which won't be flagged as
     * used by the application
     *
     * @param file the file in question
     * @return true if the file represents an analytics file
     */
    public static boolean isAnalyticsFile(File file) {
        return file.getPath().endsWith(ANALYTICS_FILE) && file.getName().equals(ANALYTICS_FILE);
    }

    /**
     * Records resource declarations and usages within an XML resource file
     * @param folderType the type of resource file
     * @param node the root node to start the recursive search from
     * @param from a referencing context, if any.
     */
    public void recordResourceReferences(
            @NonNull ResourceFolderType folderType,
            @NonNull Node node,
            @Nullable Resource from) {
        short nodeType = node.getNodeType();
        if (nodeType == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            if (from != null) {
                NamedNodeMap attributes = element.getAttributes();
                for (int i = 0, n = attributes.getLength(); i < n; i++) {
                    Attr attr = (Attr) attributes.item(i);

                    // Ignore tools: namespace attributes, unless it's
                    // a keep attribute
                    if (TOOLS_URI.equals(attr.getNamespaceURI())) {
                        recordToolsAttributes(attr);
                        // Skip all other tools: attributes
                        continue;
                    }

                    String value = attr.getValue();
                    if (!(value.startsWith(PREFIX_RESOURCE_REF)
                            || value.startsWith(PREFIX_THEME_REF))) {
                        continue;
                    }
                    ResourceUrl url = ResourceUrl.parse(value);
                    if (url != null && !url.framework) {
                        Resource resource;
                        if (url.create) {
                            boolean isId = ATTR_ID.equals(attr.getLocalName());
                            if (isId && TAG_LAYOUT.equals(
                                   element.getOwnerDocument().getDocumentElement().getTagName())) {
                                // When using data binding (root <layout> tag) the id's will be
                                // automatically bound (the binder will look through the layout
                                // and find all the id's.)  Therefore, treat these as read for
                                // now; longer term, it would be cool if we could track uses of
                                // the binding field instead.
                                markReachable(addResource(url.type, url.name, null));
                            } else {
                                resource = declareResource(url.type, url.name, attr);
                                if (!isId || !ANDROID_URI.equals(attr.getNamespaceURI())) {
                                    // Declaring an id is not a reference to that id
                                    from.addReference(resource);
                                }
                            }
                        } else {
                            resource = addResource(url.type, url.name, null);
                            from.addReference(resource);
                        }
                    } else if (value.startsWith(PREFIX_BINDING_EXPR) ||
                            value.startsWith(PREFIX_TWOWAY_BINDING_EXPR)) {
                        // Data binding expression: there could be multiple references here
                        int length = value.length();
                        int index = value.startsWith(PREFIX_TWOWAY_BINDING_EXPR)
                                ? PREFIX_TWOWAY_BINDING_EXPR.length()
                                : PREFIX_BINDING_EXPR.length();
                        while (true) {
                            index = value.indexOf('@', index);
                            if (index == -1) {
                                break;
                            }
                            // Find end of (potential) resource URL: first non resource URL character
                            int end = index + 1;
                            while (end < length) {
                                char c = value.charAt(end);
                                if (!(Character.isJavaIdentifierPart(c) ||
                                        c == '_' ||
                                        c == '.' ||
                                        c == '/' ||
                                        c == '+')) {
                                    break;
                                }
                                end++;
                            }
                            url = ResourceUrl.parse(value.substring(index, end));
                            if (url != null && !url.framework) {
                                Resource resource;
                                if (url.create) {
                                    resource = declareResource(url.type, url.name, attr);
                                } else {
                                    resource = addResource(url.type, url.name, null);
                                }
                                from.addReference(resource);
                            }

                            index = end;
                        }
                    }
                }

                // Android Wear. We *could* limit ourselves to only doing this in files
                // referenced from a manifest meta-data element, e.g.
                // <meta-data android:name="com.google.android.wearable.beta.app"
                //    android:resource="@xml/wearable_app_desc"/>
                // but given that that property has "beta" in the name, it seems likely
                // to change and therefore hardcoding it for that key risks breakage
                // in the future.
                if ("rawPathResId".equals(element.getTagName())) {
                    StringBuilder sb = new StringBuilder();
                    NodeList children = node.getChildNodes();
                    for (int i = 0, n = children.getLength(); i < n; i++) {
                        Node child = children.item(i);
                        if (child.getNodeType() == Node.TEXT_NODE
                                || child.getNodeType() == Node.CDATA_SECTION_NODE) {
                            sb.append(child.getNodeValue());
                        }
                    }
                    if (sb.length() > 0) {
                        Resource resource = getResource(ResourceType.RAW, sb.toString().trim());
                        from.addReference(resource);
                    }
                }
            } else {
                // Look for keep attributes everywhere else since they don't require a source
                recordToolsAttributes(element.getAttributeNodeNS(TOOLS_URI, ATTR_KEEP));
                recordToolsAttributes(element.getAttributeNodeNS(TOOLS_URI, ATTR_DISCARD));
                recordToolsAttributes(element.getAttributeNodeNS(TOOLS_URI, ATTR_SHRINK_MODE));
            }

            if (folderType == ResourceFolderType.VALUES) {

                Resource definition = null;
                ResourceType type = getResourceType(element);
                if (type != null) {
                    String name = getFieldName(element);
                    if (type == ResourceType.PUBLIC) {
                        String typeName = element.getAttribute(ATTR_TYPE);
                        if (!typeName.isEmpty()) {
                            type = ResourceType.getEnum(typeName);
                            if (type != null) {
                                definition = declareResource(type, name, element);
                                definition.setPublic(true);
                            }
                        }
                    } else {
                        definition = declareResource(type, name, element);
                    }
                }
                if (definition != null) {
                    from = definition;
                }

                String tagName = element.getTagName();
                if (TAG_STYLE.equals(tagName)) {
                    if (element.hasAttribute(ATTR_PARENT)) {
                        String parent = element.getAttribute(ATTR_PARENT);
                        if (!parent.isEmpty() && !parent.startsWith(ANDROID_STYLE_RESOURCE_PREFIX)
                                && !parent.startsWith(PREFIX_ANDROID)) {
                            String parentStyle = parent;
                            if (!parentStyle.startsWith(STYLE_RESOURCE_PREFIX)) {
                                parentStyle = STYLE_RESOURCE_PREFIX + parentStyle;
                            }
                            Resource ps = getResourceFromUrl(
                                    LintUtils.getFieldName(parentStyle));
                            if (ps != null && definition != null) {
                                ps.addReference(definition);
                                definition.addReference(ps);
                            }
                        } else if (definition != null) {
                            // Extending a builtin theme: treat these as used
                            markReachable(definition);
                        }
                    } else {
                        // Implicit parent styles by name
                        String name = getFieldName(element);
                        while (true) {
                            int index = name.lastIndexOf('_');
                            if (index != -1) {
                                name = name.substring(0, index);
                                Resource ps = getResourceFromUrl(
                                        STYLE_RESOURCE_PREFIX + LintUtils.getFieldName(name));
                                if (ps != null && definition != null) {
                                    ps.addReference(definition);
                                    definition.addReference(ps);
                                }
                            } else {
                                break;
                            }
                        }
                    }
                }

                if (TAG_ITEM.equals(tagName)) {
                    // In style? If so the name: attribute can be a reference
                    if (element.getParentNode() != null
                            && element.getParentNode().getNodeName().equals(TAG_STYLE)) {
                        String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
                        if (!name.isEmpty() && !name.startsWith("android:")) {
                            Resource resource = getResource(ResourceType.ATTR, name);
                            if (definition == null) {
                                Element style = (Element) element.getParentNode();
                                definition = getResource(style);
                                if (definition != null) {
                                    from = definition;
                                    definition.addReference(resource);
                                }
                            }
                        }
                    }
                }
            }
        } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
            String text = node.getNodeValue().trim();
            // Why are we calling getFieldName here? That doesn't make sense! for styles I guess
            Resource textResource = getResourceFromUrl(
                    LintUtils.getFieldName(text));
            if (textResource != null && from != null) {
                from.addReference(textResource);
            }
        }

        NodeList children = node.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            recordResourceReferences(folderType, child, from);
        }
    }

    public void tokenizeHtml(@Nullable Resource from, @NonNull String html) {
        // Look for
        //    (1) URLs of the form /android_res/drawable/foo.ext
        //        which we will use to keep R.drawable.foo
        // and
        //    (2) Filenames. If the web content is loaded with something like
        //        WebView.loadDataWithBaseURL("file:///android_res/drawable/", ...)
        //        this is similar to Resources#getIdentifier handling where all
        //        *potentially* aliased filenames are kept to play it safe.

        // Simple HTML tokenizer
        int length = html.length();
        final int STATE_TEXT = 1;
        final int STATE_SLASH = 2;
        final int STATE_ATTRIBUTE_NAME = 3;
        final int STATE_BEFORE_TAG = 4;
        final int STATE_IN_TAG = 5;
        final int STATE_BEFORE_ATTRIBUTE = 6;
        final int STATE_ATTRIBUTE_BEFORE_EQUALS = 7;
        final int STATE_ATTRIBUTE_AFTER_EQUALS = 8;
        final int STATE_ATTRIBUTE_VALUE_NONE = 9;
        final int STATE_ATTRIBUTE_VALUE_SINGLE = 10;
        final int STATE_ATTRIBUTE_VALUE_DOUBLE = 11;
        final int STATE_CLOSE_TAG = 12;

        int state = STATE_TEXT;
        int offset = 0;
        int valueStart = 0;
        int tagStart = 0;
        String tag = null;
        String attribute = null;
        int attributeStart = 0;
        int prev = -1;
        while (offset < length) {
            if (offset == prev) {
                // Purely here to prevent potential bugs in the state machine from looping
                // infinitely
                offset++;
            }
            prev = offset;


            char c = html.charAt(offset);

            // MAke sure I handle doctypes properly.
            // Make sure I handle cdata properly.
            // Oh and what about <style> tags? tokenize everything inside as CSS!
            // ANd <script> tag content as js!
            switch (state) {
                case STATE_TEXT: {
                    if (c == '<') {
                        state = STATE_SLASH;
                        offset++;
                        continue;
                    }

                    // Other text is just ignored
                    offset++;
                    break;
                }

                case STATE_SLASH: {
                    if (c == '!') {
                        if (html.startsWith("!--", offset)) {
                            // Comment
                            int end = html.indexOf("-->", offset + 3);
                            if (end == -1) {
                                offset = length;
                                break;
                            }
                            offset = end + 3;
                            continue;
                        } else if (html.startsWith("![CDATA[", offset)) {
                            // Skip CDATA text content; HTML text is irrelevant to this tokenizer
                            // anyway
                            int end = html.indexOf("]]>", offset + 8);
                            if (end == -1) {
                                offset = length;
                                break;
                            }
                            offset = end + 3;
                            continue;
                        }
                    } else if (c == '/') {
                        state = STATE_CLOSE_TAG;
                        offset++;
                        continue;
                    } else if (c == '?') {
                        // XML Prologue
                        int end = html.indexOf('>', offset + 2);
                        if (end == -1) {
                            offset = length;
                            break;
                        }
                        offset = end + 1;
                        continue;
                    }
                    state = STATE_IN_TAG;
                    tagStart = offset;
                    break;
                }

                case STATE_CLOSE_TAG: {
                    if (c == '>') {
                        state = STATE_TEXT;
                    }
                    offset++;
                    break;
                }

                case STATE_BEFORE_TAG: {
                    if (!Character.isWhitespace(c)) {
                        state = STATE_IN_TAG;
                        tagStart = offset;
                    }
                    // (For an end tag we'll include / in the tag name here)
                    offset++;
                    break;
                }
                case STATE_IN_TAG: {
                    if (Character.isWhitespace(c)) {
                        state = STATE_BEFORE_ATTRIBUTE;
                        tag = html.substring(tagStart, offset).trim();
                    } else if (c == '>') {
                        tag = html.substring(tagStart, offset).trim();
                        endHtmlTag(from, html, offset, tag);
                        state = STATE_TEXT;
                    }
                    offset++;
                    break;
                }
                case STATE_BEFORE_ATTRIBUTE: {
                    if (c == '>') {
                        endHtmlTag(from, html, offset, tag);
                        state = STATE_TEXT;
                    } else //noinspection StatementWithEmptyBody
                        if (c == '/') {
                            // we expect an '>' next to close the tag
                        } else if (!Character.isWhitespace(c)) {
                            state = STATE_ATTRIBUTE_NAME;
                            attributeStart = offset;
                        }
                    offset++;
                    break;
                }
                case STATE_ATTRIBUTE_NAME: {
                    if (c == '>') {
                        endHtmlTag(from, html, offset, tag);
                        state = STATE_TEXT;
                    } else if (c == '=') {
                        attribute = html.substring(attributeStart, offset);
                        state = STATE_ATTRIBUTE_AFTER_EQUALS;
                    } else if (Character.isWhitespace(c)) {
                        attribute = html.substring(attributeStart, offset);
                        state = STATE_ATTRIBUTE_BEFORE_EQUALS;
                    }
                    offset++;
                    break;
                }
                case STATE_ATTRIBUTE_BEFORE_EQUALS: {
                    if (c == '=') {
                        state = STATE_ATTRIBUTE_AFTER_EQUALS;
                    } else if (c == '>') {
                        endHtmlTag(from, html, offset, tag);
                        state = STATE_TEXT;
                    } else if (!Character.isWhitespace(c)) {
                        // Attribute value not specified (used for some boolean attributes)
                        state = STATE_ATTRIBUTE_NAME;
                        attributeStart = offset;
                    }
                    offset++;
                    break;
                }

                case STATE_ATTRIBUTE_AFTER_EQUALS: {
                    if (c == '\'') {
                        // a='b'
                        state = STATE_ATTRIBUTE_VALUE_SINGLE;
                        valueStart = offset + 1;
                    } else if (c == '"') {
                        // a="b"
                        state = STATE_ATTRIBUTE_VALUE_DOUBLE;
                        valueStart = offset + 1;
                    } else if (!Character.isWhitespace(c)) {
                        // a=b
                        state = STATE_ATTRIBUTE_VALUE_NONE;
                        valueStart = offset + 1;
                    }
                    offset++;
                    break;
                }

                case STATE_ATTRIBUTE_VALUE_SINGLE: {
                    if (c == '\'') {
                        state = STATE_BEFORE_ATTRIBUTE;
                        recordHtmlAttributeValue(from, tag, attribute,
                                html.substring(valueStart, offset));
                    }
                    offset++;
                    break;
                }
                case STATE_ATTRIBUTE_VALUE_DOUBLE: {
                    if (c == '"') {
                        state = STATE_BEFORE_ATTRIBUTE;
                        recordHtmlAttributeValue(from, tag, attribute,
                                html.substring(valueStart, offset));
                    }
                    offset++;
                    break;
                }
                case STATE_ATTRIBUTE_VALUE_NONE: {
                    if (c == '>') {
                        recordHtmlAttributeValue(from, tag, attribute,
                                html.substring(valueStart, offset));
                        endHtmlTag(from, html, offset, tag);
                        state = STATE_TEXT;
                    } else if (Character.isWhitespace(c)) {
                        state = STATE_BEFORE_ATTRIBUTE;
                        recordHtmlAttributeValue(from, tag, attribute,
                                html.substring(valueStart, offset));
                    }
                    offset++;
                    break;
                }
                default:
                    assert false : state;
            }
        }
    }

    private void endHtmlTag(@Nullable Resource from, @NonNull String html, int offset,
            @Nullable String tag) {
        if ("script".equals(tag)) {
            int end = html.indexOf("</script>", offset + 1);
            if (end != -1) {
                // Attempt to tokenize the text as JavaScript
                String js = html.substring(offset + 1, end);
                tokenizeJs(from, js);
            }
        } else if ("style".equals(tag)) {
            int end = html.indexOf("</style>", offset + 1);
            if (end != -1) {
                // Attempt to tokenize the text as CSS
                String css = html.substring(offset + 1, end);
                tokenizeCss(from, css);
            }
        }
    }

    public void tokenizeJs(@Nullable Resource from, @NonNull String js) {
        // Simple JavaScript tokenizer: only looks for literal strings,
        // and records those as string references
        int length = js.length();
        final int STATE_INIT = 1;
        final int STATE_SLASH = 2;
        final int STATE_STRING_DOUBLE = 3;
        final int STATE_STRING_DOUBLE_QUOTED = 4;
        final int STATE_STRING_SINGLE = 5;
        final int STATE_STRING_SINGLE_QUOTED = 6;

        int state = STATE_INIT;
        int offset = 0;
        int stringStart = 0;
        int prev = -1;
        while (offset < length) {
            if (offset == prev) {
                // Purely here to prevent potential bugs in the state machine from looping
                // infinitely
                offset++;
            }
            prev = offset;

            char c = js.charAt(offset);
            switch (state) {
                case STATE_INIT: {
                    if (c == '/') {
                        state = STATE_SLASH;
                    } else if (c == '"') {
                        stringStart = offset + 1;
                        state = STATE_STRING_DOUBLE;
                    } else if (c == '\'') {
                        stringStart = offset + 1;
                        state = STATE_STRING_SINGLE;
                    }
                    offset++;
                    break;
                }
                case STATE_SLASH: {
                    if (c == '*') {
                        // Comment block
                        state = STATE_INIT;
                        int end = js.indexOf("*/", offset + 1);
                        if (end == -1) {
                            offset = length; // unterminated
                            break;
                        }
                        offset = end + 2;
                        continue;
                    } else if (c == '/') {
                        // Line comment
                        state = STATE_INIT;
                        int end = js.indexOf('\n', offset + 1);
                        if (end == -1) {
                            offset = length;
                            break;
                        }
                        offset = end + 1;
                        continue;
                    } else {
                        // division - just continue
                        state = STATE_INIT;
                        offset++;
                        break;
                    }
                }
                case STATE_STRING_DOUBLE: {
                    if (c == '"') {
                        recordJsString(js.substring(stringStart, offset));
                        state = STATE_INIT;
                    } else if (c == '\\') {
                        state = STATE_STRING_DOUBLE_QUOTED;
                    }
                    offset++;
                    break;
                }
                case STATE_STRING_DOUBLE_QUOTED: {
                    state = STATE_STRING_DOUBLE;
                    offset++;
                    break;
                }
                case STATE_STRING_SINGLE: {
                    if (c == '\'') {
                        recordJsString(js.substring(stringStart, offset));
                        state = STATE_INIT;
                    } else if (c == '\\') {
                        state = STATE_STRING_SINGLE_QUOTED;
                    }
                    offset++;
                    break;
                }
                case STATE_STRING_SINGLE_QUOTED: {
                    state = STATE_STRING_SINGLE;
                    offset++;
                    break;
                }
                default:
                    assert false : state;
            }
        }
    }

    public void tokenizeCss(@Nullable Resource from, @NonNull String css) {
        // Simple CSS tokenizer: Only looks for URL references, and records those
        // filenames. Skips everything else (unrelated to images).
        int length = css.length();
        final int STATE_INIT = 1;
        final int STATE_SLASH = 2;
        int state = STATE_INIT;
        int offset = 0;
        int prev = -1;
        while (offset < length) {
            if (offset == prev) {
                // Purely here to prevent potential bugs in the state machine from looping
                // infinitely
                offset++;
            }
            prev = offset;

            char c = css.charAt(offset);
            switch (state) {
                case STATE_INIT: {
                    if (c == '/') {
                        state = STATE_SLASH;
                    } else if (c == 'u' && css.startsWith("url(", offset) && offset > 0) {
                        char prevChar = css.charAt(offset-1);
                        if (Character.isWhitespace(prevChar) || prevChar == ':') {
                            int end = css.indexOf(')', offset);
                            offset += 4; // skip url(
                            while (offset < length && Character.isWhitespace(css.charAt(offset))) {
                                offset++;
                            }
                            if (end != -1 && end > offset + 1) {
                                while (end > offset
                                        && Character.isWhitespace(css.charAt(end - 1))) {
                                    end--;
                                }
                                if ((css.charAt(offset) == '"'
                                        && css.charAt(end - 1) == '"')
                                        || (css.charAt(offset) == '\''
                                        && css.charAt(end - 1) == '\'')) {
                                    // Strip " or '
                                    offset++;
                                    end--;
                                }
                                recordCssUrl(from, css.substring(offset, end).trim());
                            }
                            offset = end + 1;
                            continue;
                        }

                    }
                    offset++;
                    break;
                }
                case STATE_SLASH: {
                    if (c == '*') {
                        // CSS comment? Skip the whole block rather than staying within the
                        // character tokenizer.
                        int end = css.indexOf("*/", offset + 1);
                        if (end == -1) {
                            offset = length;
                            break;
                        }
                        offset = end + 2;
                        continue;
                    }
                    state = STATE_INIT;
                    offset++;
                    break;
                }
                default:
                    assert false : state;
            }
        }
    }

    private static byte[] sAndroidResBytes;

    /** Look through binary/unknown files looking for resource URLs */
    public void tokenizeUnknownBinary(@Nullable Resource from, @NonNull File file) {
        try {
            if (sAndroidResBytes == null) {
                sAndroidResBytes = ANDROID_RES.getBytes(SdkConstants.UTF_8);
            }
            byte[] bytes = Files.toByteArray(file);
            int index = 0;
            while (index != -1) {
                index = indexOf(bytes, sAndroidResBytes, index);
                if (index != -1) {
                    index += sAndroidResBytes.length;

                    // Find the end of the URL
                    int begin = index;
                    int end = begin;
                    for (; end < bytes.length; end++) {
                        byte c = bytes[end];
                        if (c != '/' && !Character.isJavaIdentifierPart((char)c)) {
                            // android_res/raw/my_drawable.png => @raw/my_drawable
                            String url = "@" + new String(bytes, begin, end - begin, UTF_8);
                            Resource resource = getResourceFromUrl(url);
                            if (resource != null) {
                                if (from != null) {
                                    from.addReference(resource);
                                } else {
                                    markReachable(resource);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        } catch (IOException e) {
            // Ignore
        }
    }

    /**
     * Returns the index of the given target array in the first array, looking from the given
     * index
     */
    private static int indexOf(byte[] array, byte[] target, int fromIndex) {
        outer:
        for (int i = fromIndex; i < array.length - target.length + 1; i++) {
            for (int j = 0; j < target.length; j++) {
                if (array[i + j] != target[j]) {
                    continue outer;
                }
            }
            return i;
        }
        return -1;
    }

    /** Look through text files of unknown structure looking for resource URLs */
    private void tokenizeUnknownText(@NonNull String text) {
        int index = 0;
        while (index != -1) {
            index = text.indexOf(ANDROID_RES, index);
            if (index != -1) {
                index += ANDROID_RES.length();

                // Find the end of the URL
                int begin = index;
                int end = begin;
                int length = text.length();
                for (; end < length; end++) {
                    char c = text.charAt(end);
                    if (c != '/' && !Character.isJavaIdentifierPart(c)) {
                        // android_res/raw/my_drawable.png => @raw/my_drawable
                        markReachable(getResourceFromUrl("@" + text.substring(begin, end)));
                        break;
                    }
                }
            }
        }
    }

    /** Adds the resource identifiers found in the given Java source code into the reference map */
    public void tokenizeJavaCode(@NonNull String s) {
        if (s.length() <= 2) {
            return;
        }

        // Scan looking for R.{type}.name identifiers
        // Extremely simple state machine which just avoids comments, line comments
        // and strings, and outside of that records any R. identifiers it finds
        int index = 0;
        int length = s.length();

        char c;
        char next;
        for (; index < length; index++) {
            c = s.charAt(index);
            if (index == length - 1) {
                break;
            }
            next = s.charAt(index + 1);
            if (Character.isWhitespace(c)) {
                continue;
            }
            if (c == '/') {
                if (next == '*') {
                    // Block comment
                    while (index < length - 2) {
                        if (s.charAt(index) == '*' && s.charAt(index + 1) == '/') {
                            break;
                        }
                        index++;
                    }
                    index++;
                } else if (next == '/') {
                    // Line comment
                    while (index < length && s.charAt(index) != '\n') {
                        index++;
                    }
                }
            } else if (c == '\'') {
                // Character
                if (next == '\\') {
                    // Skip '\c'
                    index += 2;
                } else {
                    // Skip 'c'
                    index++;
                }
            } else if (c == '\"') {
                // String: Skip to end
                index++;
                while (index < length - 1) {
                    char t = s.charAt(index);
                    if (t == '\\') {
                        index++;
                    } else if (t == '"') {
                        break;
                    }
                    index++;
                }
            } else if (c == 'R' && next == '.') {
                // This might be a pattern
                int begin = index;
                index += 2;
                while (index < length) {
                    char t = s.charAt(index);
                    if (t == '.') {
                        String typeName = s.substring(begin + 2, index);
                        ResourceType type = ResourceType.getEnum(typeName);
                        if (type != null) {
                            index++;
                            begin = index;
                            while (index < length &&
                                    Character.isJavaIdentifierPart(s.charAt(index))) {
                                index++;
                            }
                            if (index > begin) {
                                String name = s.substring(begin, index);
                                Resource resource = addResource(type, name, null);
                                markReachable(resource);
                            }
                        }
                        index--;
                        break;
                    } else if (!Character.isJavaIdentifierStart(t)) {
                        break;
                    }
                    index++;
                }
            } else if (Character.isJavaIdentifierPart(c)) {
                // Skip to the end of the identifier
                while (index < length && Character.isJavaIdentifierPart(s.charAt(index))) {
                    index++;
                }
                // Back up so the next character can be checked to see if it's a " etc
                index--;
            } // else just punctuation/operators ( ) ;  etc
        }
    }

    protected void referencedString(@NonNull String string) {
    }

    private void recordCssUrl(@Nullable Resource from, @NonNull String value) {
        if (!referencedUrl(from, value)) {
            referencedString(value);
        }
    }

    /**
     * See if the given URL is a URL that we can resolve to a specific resource; if so,
     * record it and return true, otherwise returns false.
     */
    private boolean referencedUrl(@Nullable Resource from, @NonNull String url) {
        Resource resource = getResourceFromFilePath(url);
        if (resource == null && url.indexOf('/') == -1) {
            // URLs are often within the raw folder
            resource = getResource(ResourceType.RAW,
                    LintUtils.getFieldName(LintUtils.getBaseName(url)));
        }
        if (resource != null) {
            if (from != null) {
                from.addReference(resource);
            } else {
                // We don't have an inclusion context, so just assume this resource is reachable
                markReachable(resource);
            }
            return true;
        }

        return false;
    }

    private void recordHtmlAttributeValue(@Nullable Resource from, @Nullable String tagName,
            @Nullable String attribute, @NonNull String value) {
        if ("href".equals(attribute) || "src".equals(attribute)) {
            // In general we'd need to unescape the HTML here (e.g. remove entities) but
            // those wouldn't be valid characters in the resource name anyway
            if (!referencedUrl(from, value)) {
                referencedString(value);
            }

            // If this document includes another, record the reachability of that script/resource
            if (from != null) {
                from.addReference(getResourceFromFilePath(attribute));
            }
        }
    }

    private void recordJsString(@NonNull String string) {
        referencedString(string);
    }

    public List<Resource> getResources() {
        return mResources;
    }

    @NonNull
    public Collection<Map<String, Resource>> getResourceMaps() {
        return mTypeToName.values();
    }
}
