Drop custom Kotlin Android lint, register quickfixes with extension point
diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
index 46a00cf..60606fc 100755
--- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
+++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
@@ -27,7 +27,6 @@
 import org.jetbrains.kotlin.android.folding.AbstractAndroidResourceFoldingTest
 import org.jetbrains.kotlin.android.intention.AbstractAndroidIntentionTest
 import org.jetbrains.kotlin.android.intention.AbstractAndroidResourceIntentionTest
-import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest
 import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
 import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTest
 import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest
@@ -1216,10 +1215,6 @@
             model("android/quickfix", pattern = """^(\w+)\.((before\.Main\.\w+)|(test))$""", testMethod = "doTestWithExtraFile")
         }
 
-        testClass<AbstractKotlinLintTest> {
-            model("android/lint", excludeParentDirs = true)
-        }
-
         testClass<AbstractAndroidLintQuickfixTest> {
             model("android/lintQuickfix", pattern = "^([\\w\\-_]+)\\.kt$")
         }
diff --git a/idea/idea-android/idea-android.iml b/idea/idea-android/idea-android.iml
index e656260..fa123b9 100644
--- a/idea/idea-android/idea-android.iml
+++ b/idea/idea-android/idea-android.iml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
@@ -20,7 +20,6 @@
     <orderEntry type="module" module-name="frontend.java" />
     <orderEntry type="module" module-name="tests-common" scope="TEST" />
     <orderEntry type="module" module-name="idea-core" />
-    <orderEntry type="module" module-name="lint-idea" scope="TEST" />
     <orderEntry type="library" name="uast-java" level="project" />
     <orderEntry type="library" name="junit-plugin" level="project" />
     <orderEntry type="library" name="kotlin-reflect" level="project" />
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetApiQuickFix.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetApiQuickFix.kt
similarity index 88%
rename from plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetApiQuickFix.kt
rename to idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetApiQuickFix.kt
index 16618a4..4b462b7 100644
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetApiQuickFix.kt
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetApiQuickFix.kt
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-package org.jetbrains.android.inspections.klint
+package org.jetbrains.kotlin.android.quickfix
 
 import com.android.SdkConstants
-import com.android.tools.klint.checks.ApiDetector.REQUIRES_API_ANNOTATION
+import com.android.tools.lint.checks.ApiDetector.REQUIRES_API_ANNOTATION
 import com.intellij.codeInsight.FileModificationService
 import com.intellij.psi.PsiElement
 import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
+import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
 import org.jetbrains.android.util.AndroidBundle
 import org.jetbrains.kotlin.idea.util.addAnnotation
 import org.jetbrains.kotlin.name.FqName
@@ -58,9 +60,9 @@
 
         if (annotationContainer is KtModifierListOwner) {
              annotationContainer.addAnnotation(
-                    if (useRequiresApi) FQNAME_REQUIRES_API else FQNAME_TARGET_API,
-                    getAnnotationValue(true),
-                    whiteSpaceText = "\n")
+                     if (useRequiresApi) FQNAME_REQUIRES_API else FQNAME_TARGET_API,
+                     getAnnotationValue(true),
+                     whiteSpaceText = "\n")
         }
     }
 
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetVersionCheckQuickFix.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetVersionCheckQuickFix.kt
similarity index 94%
rename from plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetVersionCheckQuickFix.kt
rename to idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetVersionCheckQuickFix.kt
index e38cfcb..9710636 100644
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AddTargetVersionCheckQuickFix.kt
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/AddTargetVersionCheckQuickFix.kt
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-package org.jetbrains.android.inspections.klint
+package org.jetbrains.kotlin.android.quickfix
 
 import com.intellij.codeInsight.FileModificationService
 import com.intellij.psi.PsiDocumentManager
 import com.intellij.psi.PsiElement
 import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
+import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
 import org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinIfSurrounder
 import org.jetbrains.kotlin.idea.core.ShortenReferences
 import org.jetbrains.kotlin.idea.inspections.findExistingEditor
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ApiUtils.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ApiUtils.kt
similarity index 84%
rename from plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ApiUtils.kt
rename to idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ApiUtils.kt
index e3509d2..3a52671 100644
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ApiUtils.kt
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ApiUtils.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package org.jetbrains.android.inspections.klint
+package org.jetbrains.kotlin.android.quickfix
 
-import com.android.sdklib.SdkVersionInfo
+import com.android.sdklib.SdkVersionInfo.*
 
 
-fun getVersionField(api: Int, fullyQualified: Boolean): String = SdkVersionInfo.getBuildCode(api)?.let {
+fun getVersionField(api: Int, fullyQualified: Boolean): String = getBuildCode(api)?.let {
     if (fullyQualified) "android.os.Build.VERSION_CODES.$it" else it
 } ?: api.toString()
\ No newline at end of file
diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/KotlinAndroidQuickFixProvider.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/KotlinAndroidQuickFixProvider.kt
new file mode 100644
index 0000000..050b103
--- /dev/null
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/KotlinAndroidQuickFixProvider.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * 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 org.jetbrains.kotlin.android.quickfix
+
+import com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX
+import com.android.tools.lint.checks.ApiDetector
+import com.android.tools.lint.checks.CommentDetector
+import com.android.tools.lint.checks.ParcelDetector
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.TextFormat
+import com.intellij.psi.JavaPsiFacade
+import com.intellij.psi.PsiElement
+import com.intellij.psi.search.GlobalSearchScope
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFixProvider
+
+
+class KotlinAndroidQuickFixProvider : AndroidLintQuickFixProvider {
+    override fun getQuickFixes(
+            issue: Issue,
+            startElement: PsiElement,
+            endElement: PsiElement,
+            message: String,
+            data: Any?
+    ): Array<AndroidLintQuickFix> {
+        val fixes: Array<AndroidLintQuickFix> = when (issue) {
+            ApiDetector.UNSUPPORTED, ApiDetector.INLINED -> getApiQuickFixes(issue, startElement, message)
+            ParcelDetector.ISSUE -> arrayOf(ParcelableQuickFix())
+            else -> emptyArray()
+        }
+
+        if (issue != CommentDetector.STOP_SHIP) {
+            return fixes + SuppressLintQuickFix(issue.id)
+        }
+
+        return fixes
+    }
+
+    fun getApiQuickFixes(issue: Issue, element: PsiElement, message: String): Array<AndroidLintQuickFix> {
+        val api = ApiDetector.getRequiredVersion(issue, message, TextFormat.RAW)
+        if (api == -1) {
+            return AndroidLintQuickFix.EMPTY_ARRAY
+        }
+
+        val project = element.project
+        if (JavaPsiFacade.getInstance(project).findClass(REQUIRES_API_ANNOTATION, GlobalSearchScope.allScope(project)) != null) {
+            return arrayOf(AddTargetApiQuickFix(api, true), AddTargetApiQuickFix(api, false), AddTargetVersionCheckQuickFix(api))
+        }
+
+        return arrayOf(AddTargetApiQuickFix(api, false), AddTargetVersionCheckQuickFix(api))
+    }
+
+    companion object {
+        val REQUIRES_API_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "RequiresApi"
+    }
+}
\ No newline at end of file
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ParcelableQuickFix.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ParcelableQuickFix.kt
similarity index 89%
rename from plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ParcelableQuickFix.kt
rename to idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ParcelableQuickFix.kt
index 527bf64..dc93707 100644
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ParcelableQuickFix.kt
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/ParcelableQuickFix.kt
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package org.jetbrains.android.inspections.klint
+package org.jetbrains.kotlin.android.quickfix
 
 import com.intellij.psi.PsiElement
 import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
+import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
 import org.jetbrains.android.util.AndroidBundle
 import org.jetbrains.kotlin.android.canAddParcelable
 import org.jetbrains.kotlin.android.implementParcelable
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/SuppressLintIntentionAction.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/SuppressLintQuickFix.kt
similarity index 61%
rename from plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/SuppressLintIntentionAction.kt
rename to idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/SuppressLintQuickFix.kt
index e3ef7e9..d12b286 100644
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/SuppressLintIntentionAction.kt
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/quickfix/SuppressLintQuickFix.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2016 JetBrains s.r.o.
+ * Copyright 2010-2017 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,51 +14,25 @@
  * limitations under the License.
  */
 
-package org.jetbrains.android.inspections.klint
+package org.jetbrains.kotlin.android.quickfix
 
-import com.android.SdkConstants.FQCN_SUPPRESS_LINT
+import com.android.SdkConstants
 import com.intellij.codeInsight.FileModificationService
-import com.intellij.codeInsight.intention.IntentionAction
-import com.intellij.icons.AllIcons
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.Iconable
 import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiFile
 import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
+import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
 import org.jetbrains.android.util.AndroidBundle
 import org.jetbrains.kotlin.idea.util.addAnnotation
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.psi.*
-import javax.swing.Icon
 
 
-class SuppressLintIntentionAction(val id: String, val element: PsiElement) : IntentionAction, Iconable {
-
-    private companion object {
-        val INTENTION_NAME_PREFIX = "AndroidKLint"
-        val SUPPRESS_LINT_MESSAGE = "android.lint.fix.suppress.lint.api.annotation"
-        val FQNAME_SUPPRESS_LINT = FqName(FQCN_SUPPRESS_LINT)
-    }
-
+class SuppressLintQuickFix(id: String) : AndroidLintQuickFix {
     private val lintId = getLintId(id)
 
-    override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?) = true
-
-    override fun getText(): String = AndroidBundle.message(SUPPRESS_LINT_MESSAGE, lintId)
-
-    override fun getFamilyName() = text
-
-    override fun getIcon(flags: Int): Icon? = AllIcons.Actions.Cancel
-
-    override fun startInWriteAction() = true
-
-    override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
-        if (file !is KtFile) {
-            return
-        }
-
-        val annotationContainer = PsiTreeUtil.findFirstParent(element, true) { it.isSuppressLintTarget() } ?: return
+    override fun apply(startElement: PsiElement, endElement: PsiElement, context: AndroidQuickfixContexts.Context) {
+        val annotationContainer = PsiTreeUtil.findFirstParent(startElement, true) { it.isSuppressLintTarget() } ?: return
         if (!FileModificationService.getInstance().preparePsiElementForWrite(annotationContainer)) {
             return
         }
@@ -66,14 +40,24 @@
         val argument = "\"$lintId\""
 
         when (annotationContainer) {
-            is KtModifierListOwner -> annotationContainer.addAnnotation(
-                    FQNAME_SUPPRESS_LINT,
-                    argument,
-                    whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ",
-                    addToExistingAnnotation = { entry -> addArgumentToAnnotation(entry, argument) })
+            is KtModifierListOwner -> {
+                annotationContainer.addAnnotation(
+                        FQNAME_SUPPRESS_LINT,
+                        argument,
+                        whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ",
+                        addToExistingAnnotation = { entry -> addArgumentToAnnotation(entry, argument) })
+            }
         }
     }
 
+    override fun getName(): String = AndroidBundle.message(SUPPRESS_LINT_MESSAGE, lintId)
+
+    override fun isApplicable(
+            startElement: PsiElement,
+            endElement: PsiElement,
+            contextType: AndroidQuickfixContexts.ContextType
+    ): Boolean = true
+
     private fun addArgumentToAnnotation(entry: KtAnnotationEntry, argument: String): Boolean {
         // add new arguments to an existing entry
         val args = entry.valueArgumentList
@@ -102,4 +86,9 @@
     private fun PsiElement.isSuppressLintTarget() = this is KtDeclaration &&
                                                     this !is KtDestructuringDeclaration &&
                                                     this !is KtFunctionLiteral
+    private companion object {
+        val INTENTION_NAME_PREFIX = "AndroidLint"
+        val SUPPRESS_LINT_MESSAGE = "android.lint.fix.suppress.lint.api.annotation"
+        val FQNAME_SUPPRESS_LINT = FqName(SdkConstants.FQCN_SUPPRESS_LINT)
+    }
 }
\ No newline at end of file
diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt
deleted file mode 100644
index 5bc5668..0000000
--- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * 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 org.jetbrains.kotlin.android.lint
-
-import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase
-import org.jetbrains.kotlin.android.KotlinAndroidTestCase
-import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
-import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
-import java.io.File
-
-abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
-
-    override fun setUp() {
-        super.setUp()
-        ConfigLibraryUtil.configureKotlinRuntime(myModule)
-        AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap()
-        // needs access to .class files in kotlin runtime jar
-        myFixture.allowTreeAccessForAllFiles()
-    }
-
-    override fun tearDown() {
-        ConfigLibraryUtil.unConfigureKotlinRuntime(myModule)
-        super.tearDown()
-    }
-
-    fun doTest(filename: String) {
-        val ktFile = File(filename)
-        val mainInspectionClassName = findStringWithPrefixes(ktFile.readText(), "// INSPECTION_CLASS: ") ?: error("Empty class name")
-
-        val inspectionClassNames = mutableListOf(mainInspectionClassName)
-        for (i in 2..100) {
-            val className = findStringWithPrefixes(ktFile.readText(), "// INSPECTION_CLASS$i: ") ?: break
-            inspectionClassNames += className
-        }
-
-        myFixture.enableInspections(*inspectionClassNames.map { className ->
-            val inspectionClass = Class.forName(className)
-            inspectionClass.newInstance() as AndroidLintInspectionBase
-        }.toTypedArray())
-
-        val additionalResourcesDir = File(ktFile.parentFile, getTestName(true))
-        if (additionalResourcesDir.exists()) {
-            for (file in additionalResourcesDir.listFiles()) {
-                if (file.isFile) {
-                    myFixture.copyFileToProject(file.absolutePath, file.name)
-                }
-                else if (file.isDirectory) {
-                    myFixture.copyDirectoryToProject(file.absolutePath, file.name)
-                }
-            }
-        }
-
-        val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt")
-        myFixture.configureFromExistingVirtualFile(virtualFile)
-
-        myFixture.checkHighlighting(true, false, false)
-    }
-}
\ No newline at end of file
diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java
deleted file mode 100644
index e1c0526..0000000
--- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2010-2017 JetBrains s.r.o.
- *
- * 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 org.jetbrains.kotlin.android.lint;
-
-import com.intellij.testFramework.TestDataPath;
-import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
-import org.jetbrains.kotlin.test.KotlinTestUtils;
-import org.jetbrains.kotlin.test.TargetBackend;
-import org.jetbrains.kotlin.test.TestMetadata;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.regex.Pattern;
-
-/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
-@SuppressWarnings("all")
-@TestMetadata("idea/testData/android/lint")
-@TestDataPath("$PROJECT_ROOT")
-@RunWith(JUnit3RunnerWithInners.class)
-public class KotlinLintTestGenerated extends AbstractKotlinLintTest {
-    @TestMetadata("alarm.kt")
-    public void testAlarm() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/alarm.kt");
-        doTest(fileName);
-    }
-
-    public void testAllFilesPresentInLint() throws Exception {
-        KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/android/lint"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
-    }
-
-    @TestMetadata("apiCheck.kt")
-    public void testApiCheck() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/apiCheck.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("callSuper.kt")
-    public void testCallSuper() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/callSuper.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("closeCursor.kt")
-    public void testCloseCursor() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/closeCursor.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("commitFragment.kt")
-    public void testCommitFragment() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/commitFragment.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("javaPerformance.kt")
-    public void testJavaPerformance() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/javaPerformance.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("javaScriptInterface.kt")
-    public void testJavaScriptInterface() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/javaScriptInterface.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("layoutInflation.kt")
-    public void testLayoutInflation() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/layoutInflation.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("log.kt")
-    public void testLog() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/log.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("noInternationalSms.kt")
-    public void testNoInternationalSms() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/noInternationalSms.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("overrideConcrete.kt")
-    public void testOverrideConcrete() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/overrideConcrete.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("parcel.kt")
-    public void testParcel() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/parcel.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("sdCardTest.kt")
-    public void testSdCardTest() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/sdCardTest.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("setJavaScriptEnabled.kt")
-    public void testSetJavaScriptEnabled() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/setJavaScriptEnabled.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("sharedPrefs.kt")
-    public void testSharedPrefs() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/sharedPrefs.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("showDiagnosticsWhenFileIsRed.kt")
-    public void testShowDiagnosticsWhenFileIsRed() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/showDiagnosticsWhenFileIsRed.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("sqlite.kt")
-    public void testSqlite() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/sqlite.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("systemServices.kt")
-    public void testSystemServices() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/systemServices.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("toast.kt")
-    public void testToast() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/toast.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("valueOf.kt")
-    public void testValueOf() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/valueOf.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("velocityTrackerRecycle.kt")
-    public void testVelocityTrackerRecycle() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/velocityTrackerRecycle.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("viewConstructor.kt")
-    public void testViewConstructor() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/viewConstructor.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("viewHolder.kt")
-    public void testViewHolder() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/viewHolder.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("wrongAnnotation.kt")
-    public void testWrongAnnotation() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/wrongAnnotation.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("wrongImport.kt")
-    public void testWrongImport() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/wrongImport.kt");
-        doTest(fileName);
-    }
-
-    @TestMetadata("wrongViewCall.kt")
-    public void testWrongViewCall() throws Exception {
-        String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/wrongViewCall.kt");
-        doTest(fileName);
-    }
-}
diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt
index b46f1d7..c2f6989 100644
--- a/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt
+++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/quickfix/AbstractAndroidLintQuickfixTest.kt
@@ -19,7 +19,7 @@
 import com.intellij.codeInspection.InspectionProfileEntry
 import com.intellij.openapi.util.io.FileUtil
 import com.intellij.util.PathUtil
-import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase
+import org.jetbrains.android.inspections.lint.AndroidLintInspectionBase
 import org.jetbrains.kotlin.android.KotlinAndroidTestCase
 import org.jetbrains.kotlin.test.InTextDirectivesUtils
 import java.io.File
diff --git a/idea/src/META-INF/android-lint.xml b/idea/src/META-INF/android-lint.xml
index c930aff..eb81b66 100644
--- a/idea/src/META-INF/android-lint.xml
+++ b/idea/src/META-INF/android-lint.xml
@@ -1,122 +1,9 @@
 <idea-plugin>
     <extensions defaultExtensionNs="com.intellij">
-        <externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintExternalAnnotator"/>
+        <externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.lint.AndroidLintExternalAnnotator"/>
         
         <projectService serviceInterface="org.jetbrains.uast.kotlin.KotlinUastBindingContextProviderService"
                         serviceImplementation="org.jetbrains.uast.kotlin.internal.IdeaKotlinUastBindingContextProviderService"/>
-
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAddJavascriptInterface" displayName="addJavascriptInterface Called" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAddJavascriptInterfaceInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAllowAllHostnameVerifier" displayName="Insecure HostnameVerifier" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAllowAllHostnameVerifierInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAlwaysShowAction" displayName="Usage of showAsAction=always" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAlwaysShowActionInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAppCompatMethod" displayName="Using Wrong AppCompat Method" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAppCompatMethodInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAuthLeak" displayName="Code contains url auth" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAuthLeakInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintBadHostnameVerifier" displayName="Insecure HostnameVerifier" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintBadHostnameVerifierInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintBatteryLife" displayName="Battery Life Issues" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintBatteryLifeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintCommitPrefEdits" displayName="Missing commit() on SharedPreference editor" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCommitPrefEditsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintCommitTransaction" displayName="Missing commit() calls" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCommitTransactionInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintCustomViewStyleable" displayName="Mismatched Styleable/Custom View Name" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCustomViewStyleableInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintCutPasteId" displayName="Likely cut &amp; paste mistakes" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCutPasteIdInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintDefaultLocale" displayName="Implied default locale in case conversion" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintDefaultLocaleInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintDrawAllocation" displayName="Memory allocations within drawing code" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintDrawAllocationInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintEasterEgg" displayName="Code contains easter egg" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="false" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintEasterEggInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintExportedContentProvider" displayName="Content provider does not require permission" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintExportedContentProviderInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintExportedPreferenceActivity" displayName="PreferenceActivity should not be exported" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintExportedPreferenceActivityInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintExportedReceiver" displayName="Receiver does not require permission" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintExportedReceiverInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintExportedService" displayName="Exported service does not require permission" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintExportedServiceInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintFloatMath" displayName="Using FloatMath instead of Math" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintFloatMathInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGetInstance" displayName="Cipher.getInstance with ECB" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGetInstanceInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGifUsage" displayName="Using .gif format for bitmaps is discouraged" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGifUsageInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGoogleAppIndexingApiWarning" displayName="Missing support for Google App Indexing Api" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="false" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGoogleAppIndexingApiWarningInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGoogleAppIndexingUrlError" displayName="URL not supported by app for Google App Indexing" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGoogleAppIndexingUrlErrorInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGoogleAppIndexingWarning" displayName="Missing support for Google App Indexing" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGoogleAppIndexingWarningInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintGrantAllUris" displayName="Content provider shares everything" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintGrantAllUrisInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintHandlerLeak" displayName="Handler reference leaks" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintHandlerLeakInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconColors" displayName="Icon colors do not follow the recommended visual style" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconColorsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconDensities" displayName="Icon densities validation" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconDensitiesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconDipSize" displayName="Icon density-independent size validation" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconDipSizeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconDuplicates" displayName="Duplicated icons under different names" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconDuplicatesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconDuplicatesConfig" displayName="Identical bitmaps across various configurations" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconDuplicatesConfigInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconExpectedSize" displayName="Icon has incorrect size" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="false" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconExpectedSizeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconExtension" displayName="Icon format does not match the file extension" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconExtensionInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconLauncherShape" displayName="The launcher icon shape should use a distinct silhouette" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconLauncherShapeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconLocation" displayName="Image defined in density-independent drawable folder" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconLocationInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconMissingDensityFolder" displayName="Missing density folder" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconMissingDensityFolderInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconMixedNinePatch" displayName="Clashing PNG and 9-PNG files" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconMixedNinePatchInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconNoDpi" displayName="Icon appears in both -nodpi and dpi folders" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconNoDpiInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintIconXmlAndPng" displayName="Icon is specified both as .xml file and as a bitmap" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintIconXmlAndPngInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintInconsistentLayout" displayName="Inconsistent Layouts" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInconsistentLayoutInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintInflateParams" displayName="Layout Inflation without a Parent" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInflateParamsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintInlinedApi" displayName="Using inlined constants on older versions" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintInvalidUsesTagAttribute" displayName="Invalid name attribute for uses element." groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInvalidUsesTagAttributeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintJavascriptInterface" displayName="Missing @JavascriptInterface on methods" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintJavascriptInterfaceInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintLocalSuppress" displayName="@SuppressLint on invalid element" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLocalSuppressInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintLogConditional" displayName="Unconditional Logging Calls" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="false" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLogConditionalInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintLogTagMismatch" displayName="Mismatched Log Tags" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLogTagMismatchInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintLongLogTag" displayName="Too Long Log Tags" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLongLogTagInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintMergeRootFrame" displayName="FrameLayout can be replaced with &lt;merge> tag" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMergeRootFrameInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintMissingIntentFilterForMediaSearch" displayName="Missing intent-filter with action android.media.action.MEDIA_PLAY_FROM_SEARCH" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMissingIntentFilterForMediaSearchInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintMissingMediaBrowserServiceIntentFilter" displayName="Missing intent-filter with action android.media.browse.MediaBrowserService." groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMissingMediaBrowserServiceIntentFilterInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintMissingOnPlayFromSearch" displayName="Missing onPlayFromSearch." groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMissingOnPlayFromSearchInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintMissingSuperCall" displayName="Missing Super Call" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMissingSuperCallInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintNewApi" displayName="Calling new methods on older versions" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintOverdraw" displayName="Overdraw: Painting regions more than once" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverdrawInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintOverride" displayName="Method conflicts with new inherited method" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintOverrideAbstract" displayName="Not overriding abstract methods on older platforms" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideAbstractInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintPackageManagerGetSignatures" displayName="Potential Multiple Certificate Exploit" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintPackageManagerGetSignaturesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintParcelClassLoader" displayName="Default Parcel Class Loader" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintParcelClassLoaderInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintParcelCreator" displayName="Missing Parcelable CREATOR field" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintParcelCreatorInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintPendingBindings" displayName="Missing Pending Bindings" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintPendingBindingsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintPluralsCandidate" displayName="Potential Plurals" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintPluralsCandidateInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintPrivateResource" displayName="Using private resources" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintPrivateResourceInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRecycle" displayName="Missing recycle() calls" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRecycleInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRecyclerView" displayName="RecyclerView Problems" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRecyclerViewInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRegistered" displayName="Class is not registered in the manifest" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRegisteredInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRequiredSize" displayName="Missing layout_width or layout_height attributes" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRequiredSizeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRtlCompat" displayName="Right-to-left text compatibility issues" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRtlCompatInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRtlEnabled" displayName="Using RTL attributes without enabling RTL support" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRtlEnabledInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRtlHardcoded" displayName="Using left/right instead of start/end attributes" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRtlHardcodedInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintRtlSymmetry" displayName="Padding and margin symmetry" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRtlSymmetryInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSdCardPath" displayName="Hardcoded reference to /sdcard" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSecureRandom" displayName="Using a fixed seed with SecureRandom" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSecureRandomInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintServiceCast" displayName="Wrong system service casts" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintServiceCastInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSetJavaScriptEnabled" displayName="Using setJavaScriptEnabled" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSetJavaScriptEnabledInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSetTextI18n" displayName="TextView Internationalization" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSetTextI18nInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSetWorldReadable" displayName="File.setReadable() used to make file world-readable" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSetWorldReadableInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSetWorldWritable" displayName="File.setWritable() used to make file world-writable" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSetWorldWritableInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintShiftFlags" displayName="Dangerous Flag Constant Declaration" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintShiftFlagsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintShortAlarm" displayName="Short or Frequent Alarm" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintShortAlarmInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintShowToast" displayName="Toast created but not shown" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintShowToastInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSimpleDateFormat" displayName="Implied locale in date format" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSimpleDateFormatInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSQLiteString" displayName="Using STRING instead of TEXT" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSQLiteStringInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSSLCertificateSocketFactoryCreateSocket" displayName="Insecure call to SSLCertificateSocketFactory.createSocket()" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSSLCertificateSocketFactoryCreateSocketInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSSLCertificateSocketFactoryGetInsecure" displayName="Call to SSLCertificateSocketFactory.getInsecure()" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSSLCertificateSocketFactoryGetInsecureInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintStopShip" displayName="Code contains STOPSHIP marker" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="false" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintStopShipInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintStringFormatCount" displayName="Formatting argument types incomplete or inconsistent" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintStringFormatCountInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintStringFormatInvalid" displayName="Invalid format string" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintStringFormatInvalidInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintStringFormatMatches" displayName="String.format string doesn&apos;t match the XML format string" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintStringFormatMatchesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSupportAnnotationUsage" displayName="Incorrect support annotation usage" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSupportAnnotationUsageInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSuspiciousImport" displayName="&apos;import android.R&apos; statement" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSuspiciousImportInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintSwitchIntDef" displayName="Missing @IntDef in Switch" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSwitchIntDefInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintTrustAllX509TrustManager" displayName="Insecure TLS/SSL trust manager" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintTrustAllX509TrustManagerInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUniqueConstants" displayName="Overlapping Enumeration Constants" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUniqueConstantsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnlocalizedSms" displayName="SMS phone number missing country code" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnlocalizedSmsInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnprotectedSMSBroadcastReceiver" displayName="Unprotected SMS BroadcastReceiver" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnprotectedSMSBroadcastReceiverInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnsafeDynamicallyLoadedCode" displayName="load used to dynamically load code" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnsafeDynamicallyLoadedCodeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnsafeNativeCodeLocation" displayName="Native code outside library directory" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnsafeNativeCodeLocationInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnsafeProtectedBroadcastReceiver" displayName="Unsafe Protected BroadcastReceiver" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnsafeProtectedBroadcastReceiverInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUnusedAttribute" displayName="Attribute unused on older versions" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnusedAttributeInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUseSparseArrays" displayName="HashMap can be replaced with SparseArray" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUseSparseArraysInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintUseValueOf" displayName="Should use valueOf instead of new" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUseValueOfInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintValidFragment" displayName="Fragment not instantiatable" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintValidFragmentInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintViewConstructor" displayName="Missing View constructors for XML inflation" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintViewConstructorInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintViewHolder" displayName="View Holder Candidates" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintViewHolderInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintViewTag" displayName="Tagged object leaks" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintViewTagInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintWorldReadableFiles" displayName="openFileOutput() or similar call passing MODE_WORLD_READABLE" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintWorldReadableFilesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintWorldWriteableFiles" displayName="openFileOutput() or similar call passing MODE_WORLD_WRITEABLE" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintWorldWriteableFilesInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintWrongCall" displayName="Using wrong draw/layout method" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintWrongCallInspection"/>
-        <globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintWrongViewCast" displayName="Mismatched view type" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintWrongViewCastInspection"/>
-
-        <codeInspection.InspectionExtension implementation="org.jetbrains.android.inspections.klint.AndroidInspectionExtensionsFactory"/>
     </extensions>
 
     <extensions defaultExtensionNs="org.jetbrains.uast">
diff --git a/idea/src/META-INF/android.xml b/idea/src/META-INF/android.xml
index 976bbf1..9437800 100644
--- a/idea/src/META-INF/android.xml
+++ b/idea/src/META-INF/android.xml
@@ -76,6 +76,10 @@
         <projectConfigurator implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidGradleModuleConfigurator"/>
     </extensions>
 
+    <extensions defaultExtensionNs="org.jetbrains.android">
+        <androidLintQuickFixProvider implementation="org.jetbrains.kotlin.android.quickfix.KotlinAndroidQuickFixProvider" />
+    </extensions>
+
     <project-components>
         <component>
             <interface-class>org.jetbrains.kotlin.android.facet.KotlinAndroidStartupManager</interface-class>
diff --git a/idea/testData/android/lint/alarm.kt b/idea/testData/android/lint/alarm.kt
deleted file mode 100644
index eaa7dfb1..0000000
--- a/idea/testData/android/lint/alarm.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintShortAlarmInspection
-
-import android.app.AlarmManager
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class TestAlarm {
-    fun test(alarmManager: AlarmManager) {
-        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK
-        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK
-        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, <warning descr="Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact">50</warning>, <warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">10</warning>, null); // ERROR
-
-        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000,  // ERROR
-                                  <warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">OtherClass.MY_INTERVAL</warning>, null);                          // ERROR
-
-        val interval = 10;
-        val interval2 = 2L * interval;
-        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, <warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">interval2</warning>, null); // ERROR
-    }
-
-    private object OtherClass {
-        val MY_INTERVAL = 1000L;
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/apiCheck.kt b/idea/testData/android/lint/apiCheck.kt
deleted file mode 100644
index e6f3d75..0000000
--- a/idea/testData/android/lint/apiCheck.kt
+++ /dev/null
@@ -1,479 +0,0 @@
-
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
-// INSPECTION_CLASS2: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection
-// INSPECTION_CLASS3: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideInspection
-
-import android.animation.RectEvaluator
-import android.annotation.SuppressLint
-import android.annotation.TargetApi
-import org.w3c.dom.DOMError
-import org.w3c.dom.DOMErrorHandler
-import org.w3c.dom.DOMLocator
-
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams
-import android.app.Activity
-import android.app.ApplicationErrorReport
-import android.graphics.drawable.VectorDrawable
-import android.graphics.Path
-import android.graphics.PorterDuff
-import android.graphics.Rect
-import android.os.Build
-import android.widget.*
-import dalvik.bytecode.OpcodeInfo
-
-import android.os.Build.VERSION
-import <warning descr="Field requires API level 4 (current min is 1): `android.os.Build.VERSION#SDK_INT`">android.os.Build.VERSION.SDK_INT</warning>
-import android.os.Build.VERSION_CODES
-import android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH
-import android.os.Build.VERSION_CODES.JELLY_BEAN
-import android.os.Bundle
-import android.os.Parcelable
-import android.system.ErrnoException
-import android.widget.TextView
-
-@Suppress("SENSELESS_COMPARISON", "UNUSED_EXPRESSION", "UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION", "USELESS_CAST")
-class ApiCallTest: Activity() {
-
-    fun method(chronometer: Chronometer, locator: DOMLocator) {
-        chronometer.<error descr="Call requires API level 16 (current min is 1): android.view.View#setBackground">setBackground</error>(null)
-
-        // Ok
-        Bundle().getInt("")
-
-        View.<warning descr="Field requires API level 16 (current min is 1): `android.view.View#SYSTEM_UI_FLAG_FULLSCREEN`">SYSTEM_UI_FLAG_FULLSCREEN</warning>
-
-        // Virtual call
-        <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() // API 11
-        <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">actionBar</error> // API 11
-
-        // Class references (no call or field access)
-        val error: DOMError? = null // API 8
-        val clz = <error descr="Class requires API level 8 (current min is 1): org.w3c.dom.DOMErrorHandler">DOMErrorHandler::class</error> // API 8
-
-        // Method call
-        chronometer.<error descr="Call requires API level 3 (current min is 1): android.widget.Chronometer#getOnChronometerTickListener">onChronometerTickListener</error> // API 3
-
-        // Inherited method call (from TextView
-        chronometer.<error descr="Call requires API level 11 (current min is 1): android.widget.TextView#setTextIsSelectable">setTextIsSelectable</error>(true) // API 11
-
-        <error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout::class</error>
-
-        // Field access
-        val field = OpcodeInfo.<warning descr="Field requires API level 11 (current min is 1): `dalvik.bytecode.OpcodeInfo#MAXIMUM_VALUE`">MAXIMUM_VALUE</warning> // API 11
-
-
-        val fillParent = LayoutParams.FILL_PARENT // API 1
-        // This is a final int, which means it gets inlined
-        val matchParent = LayoutParams.MATCH_PARENT // API 8
-        // Field access: non final
-        val batteryInfo = report!!.<error descr="Field requires API level 14 (current min is 1): `android.app.ApplicationErrorReport#batteryInfo`">batteryInfo</error>
-
-        // Enum access
-        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
-            val mode = PorterDuff.Mode.<error descr="Field requires API level 11 (current min is 1): `android.graphics.PorterDuff.Mode#OVERLAY`">OVERLAY</error> // API 11
-        }
-    }
-
-    fun test(rect: Rect) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            RectEvaluator(rect); // OK
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            if (rect != null) {
-                RectEvaluator(rect); // OK
-            }
-        }
-    }
-
-    fun test2(rect: Rect) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            RectEvaluator(rect); // OK
-        }
-    }
-
-    fun test3(rect: Rect) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
-            <error descr="Call requires API level 18 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(); // ERROR
-        }
-    }
-
-    fun test4(rect: Rect) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            System.out.println("Something");
-            RectEvaluator(rect); // OK
-        } else {
-            <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
-        }
-    }
-
-    fun test5(rect: Rect) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
-            <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
-        } else {
-            <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
-        }
-    }
-
-    fun test(priority: Boolean, layout: ViewGroup) {
-        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        if (SDK_INT >= ICE_CREAM_SANDWICH) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        } else {
-            GridLayout(null).getOrientation(); // Not flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= 14) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        // Nested conditionals
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-            if (priority) {
-                <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-            } else {
-                <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-            }
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        }
-
-        // Nested conditionals 2
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            if (priority) {
-                GridLayout(null).getOrientation(); // Not flagged
-            } else {
-                GridLayout(null).getOrientation(); // Not flagged
-            }
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-    }
-
-    fun test2(priority: Boolean) {
-        if (android.os.Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (android.os.Build.VERSION.SDK_INT >= 16) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (android.os.Build.VERSION.SDK_INT >= 13) {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (SDK_INT >= JELLY_BEAN) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        } else {
-            GridLayout(null).getOrientation(); // Not flagged
-        }
-
-        if (Build.VERSION.SDK_INT >= 16) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-
-        if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
-            GridLayout(null).getOrientation(); // Not flagged
-        } else {
-            <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
-        }
-    }
-
-    fun test(textView: TextView) {
-        if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
-            //ERROR
-        }
-        if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
-            //ERROR
-        }
-
-        if (SDK_INT >= JELLY_BEAN && textView.isSuggestionsEnabled()) {
-            //NO ERROR
-        }
-
-        if (SDK_INT >= JELLY_BEAN && textView.isSuggestionsEnabled) {
-            //NO ERROR
-        }
-
-        if (SDK_INT >= JELLY_BEAN && (textView.text != "" || textView.isSuggestionsEnabled)) {
-            //NO ERROR
-        }
-
-        if (SDK_INT < JELLY_BEAN && (textView.text != "" || textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>)) {
-            //ERROR
-        }
-
-        if (SDK_INT < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
-            //ERROR
-        }
-
-        if (SDK_INT < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
-            //ERROR
-        }
-
-        if (SDK_INT < JELLY_BEAN || textView.isSuggestionsEnabled) {
-            //NO ERROR
-        }
-
-        if (SDK_INT > JELLY_BEAN || textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
-            //ERROR
-        }
-
-
-        // getActionBar() API 11
-        if (SDK_INT <= 10 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT < 10 || <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() == null) {
-            //ERROR
-        }
-
-        if (SDK_INT < 11 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT != 11 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT != 12 || <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() == null) {
-            //ERROR
-        }
-
-        if (SDK_INT <= 11 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT < 12 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT <= 12 || getActionBar() == null) {
-            //NO ERROR
-        }
-
-        if (SDK_INT < 9 || <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() == null) {
-            //ERROR
-        }
-
-        if (SDK_INT <= 9 || <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() == null) {
-            //ERROR
-        }
-    }
-
-    fun testReturn() {
-        if (SDK_INT < 11) {
-            return
-        }
-
-        // No Error
-        val actionBar = getActionBar()
-    }
-
-    fun testThrow() {
-        if (SDK_INT < 11) {
-            throw IllegalStateException()
-        }
-
-        // No Error
-        val actionBar = getActionBar()
-    }
-
-    fun testError() {
-        if (SDK_INT < 11) {
-            error("Api")
-        }
-
-        // No Error
-        val actionBar = getActionBar()
-    }
-
-    fun testWithoutAnnotation(textView: TextView) {
-        if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
-
-        }
-
-        if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
-
-        }
-    }
-
-    @TargetApi(JELLY_BEAN)
-    fun testWithTargetApiAnnotation(textView: TextView) {
-        if (textView.isSuggestionsEnabled()) {
-            //NO ERROR, annotation
-        }
-
-        if (textView.isSuggestionsEnabled) {
-            //NO ERROR, annotation
-        }
-    }
-
-    @SuppressLint("NewApi")
-    fun testWithSuppressLintAnnotation(textView: TextView) {
-        if (textView.isSuggestionsEnabled()) {
-            //NO ERROR, annotation
-        }
-
-        if (textView.isSuggestionsEnabled) {
-            //NO ERROR, annotation
-        }
-    }
-
-    fun testCatch() {
-        try {
-
-        } catch (e: <error descr="Class requires API level 21 (current min is 1): android.system.ErrnoException">ErrnoException</error>) {
-
-        }
-    }
-
-    fun testOverload() {
-        // this overloaded addOval available only on API Level 21
-        Path().<error descr="Call requires API level 21 (current min is 1): android.graphics.Path#addOval">addOval</error>(0f, 0f, 0f, 0f, Path.Direction.CW)
-    }
-
-    // KT-14737 False error with short-circuit evaluation
-    fun testShortCircuitEvaluation() {
-        <error descr="Call requires API level 21 (current min is 1): android.content.Context#getDrawable">getDrawable</error>(0) // error here as expected
-        if(Build.VERSION.SDK_INT >= 23
-           && null == getDrawable(0)) // error here should not occur
-        {
-            getDrawable(0) // no error here as expected
-        }
-    }
-
-    // KT-1482 Kotlin Lint: "Calling new methods on older versions" does not report call on receiver in extension function
-    private fun Bundle.caseE1a() { <error descr="Call requires API level 18 (current min is 1): android.os.Bundle#getBinder">getBinder</error>("") }
-
-    private fun Bundle.caseE1c() { this.<error descr="Call requires API level 18 (current min is 1): android.os.Bundle#getBinder">getBinder</error>("") }
-
-    private fun caseE1b(bundle: Bundle) { bundle.<error descr="Call requires API level 18 (current min is 1): android.os.Bundle#getBinder">getBinder</error>("") }
-
-    // KT-12023 Kotlin Lint: Cast doesn't trigger minSdk error
-    fun testCast(layout: ViewGroup) {
-        if (layout is LinearLayout) {}  // OK API 1
-        layout as? LinearLayout         // OK API 1
-        layout as LinearLayout          // OK API 1
-
-        if (layout !is <error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout</error>) {}
-        layout as? <error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout</error>
-        layout as <error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout</error>
-
-        val grid = layout as? <error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout</error>
-        val linear = layout as LinearLayout // OK API 1
-    }
-
-    abstract class ErrorVectorDravable : <error descr="Class requires API level 21 (current min is 1): android.graphics.drawable.VectorDrawable">VectorDrawable</error>(), Parcelable
-
-    @TargetApi(21)
-    class MyVectorDravable : VectorDrawable()
-
-    fun testTypes() {
-        <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(this)
-        val c = <error descr="Class requires API level 21 (current min is 1): android.graphics.drawable.VectorDrawable">VectorDrawable::class</error>.java
-    }
-
-    fun testCallWithApiAnnotation(textView: TextView) {
-        <error descr="Call requires API level 21 (current min is 1): ApiCallTest.MyVectorDravable#MyVectorDravable">MyVectorDravable</error>()
-        <error descr="Call requires API level 16 (current min is 1): ApiCallTest#testWithTargetApiAnnotation">testWithTargetApiAnnotation</error>(textView)
-    }
-
-    companion object : Activity() {
-        fun test() {
-            <error descr="Call requires API level 21 (current min is 1): android.content.Context#getDrawable">getDrawable</error>(0)
-        }
-    }
-
-    // Return type
-    internal // API 14
-    val gridLayout: GridLayout?
-        get() = null
-
-    private val report: ApplicationErrorReport?
-        get() = null
-}
-
-object O: Activity() {
-    fun test() {
-        <error descr="Call requires API level 21 (current min is 1): android.content.Context#getDrawable">getDrawable</error>(0)
-    }
-}
-
-fun testJava8() {
-    // Error, Api 24, Java8
-    mutableListOf(1, 2, 3).<error descr="Call requires API level 24 (current min is 1): java.util.Collection#removeIf">removeIf</error> {
-        true
-    }
-
-    // Ok, Kotlin
-    mutableListOf(1, 2, 3).removeAll {
-        true
-    }
-
-    // Error, Api 24, Java8
-    mapOf(1 to 2).<error descr="Call requires API level 24 (current min is 1): java.util.Map#forEach">forEach</error> { key, value -> key + value }
-
-    // Ok, Kotlin
-    mapOf(1 to 2).forEach { (key, value) -> key + value }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/callSuper.kt b/idea/testData/android/lint/callSuper.kt
deleted file mode 100644
index df30cfe..0000000
--- a/idea/testData/android/lint/callSuper.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintMissingSuperCallInspection
-
-package android.support.annotation
-
-@Retention(AnnotationRetention.BINARY)
-@Target(AnnotationTarget.FUNCTION)
-annotation class CallSuper
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class CallSuperTest {
-    private class Child : Parent() {
-        override fun <error descr="Overriding method should call `super.test1`">test1</error>() {
-            // ERROR
-        }
-
-        override fun <error descr="Overriding method should call `super.test2`">test2</error>() {
-            // ERROR
-        }
-
-        override fun <error descr="Overriding method should call `super.test3`">test3</error>() {
-            // ERROR
-        }
-
-        override fun <error descr="Overriding method should call `super.test4`">test4</error>(arg: Int) {
-            // ERROR
-        }
-
-        override fun test4(arg: String) {
-            // OK
-        }
-
-
-        override fun <error descr="Overriding method should call `super.test5`">test5</error>(arg1: Int, arg2: Boolean, arg3: Map<List<String>, *>, // ERROR
-                           arg4: Array<IntArray>, vararg arg5: Int) {
-        }
-
-        override fun <error descr="Overriding method should call `super.test5`">test5</error>() {
-            // ERROR
-            super.test6() // (wrong super)
-        }
-
-        override fun test6() {
-            // OK
-            val x = 5
-            super.test6()
-            System.out.println(x)
-        }
-    }
-
-    private open class Parent : ParentParent() {
-        @CallSuper
-        protected open fun test1() {
-        }
-
-        override fun test3() {
-            super.test3()
-        }
-
-        @CallSuper
-        protected open fun test4(arg: Int) {
-        }
-
-        protected open fun test4(arg: String) {
-        }
-
-        @CallSuper
-        protected open fun test5() {
-        }
-
-        @CallSuper
-        protected open fun test5(arg1: Int, arg2: Boolean, arg3: Map<List<String>, *>,
-                                 arg4: Array<IntArray>, vararg arg5: Int) {
-        }
-    }
-
-    private open class ParentParent : ParentParentParent() {
-        @CallSuper
-        protected open fun test2() {
-        }
-
-        @CallSuper
-        protected open fun test3() {
-        }
-
-        @CallSuper
-        protected open fun test6() {
-        }
-
-        @CallSuper
-        protected fun test7() {
-        }
-
-
-    }
-
-    private open class ParentParentParent
-}
diff --git a/idea/testData/android/lint/closeCursor.kt b/idea/testData/android/lint/closeCursor.kt
deleted file mode 100644
index ca26201..0000000
--- a/idea/testData/android/lint/closeCursor.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRecycleInspection
-
-@file:Suppress("UNUSED_VARIABLE")
-
-import android.app.Activity
-import android.os.Bundle
-
-class MainActivity : Activity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        val cursor = contentResolver.<warning descr="This `Cursor` should be freed up after use with `#close()`">query</warning>(null, null, null, null, null)
-
-        // WARNING
-        contentResolver.<warning descr="This `Cursor` should be freed up after use with `#close()`">query</warning>(null, null, null, null, null)
-
-        // OK, closed in chained call
-        contentResolver.query(null, null, null, null, null).close()
-
-        // KT-14677: Kotlin Lint: "Missing recycle() calls" report cursor with `use()` call
-        val cursorUsed = contentResolver.query(null, null, null, null, null)
-        cursorUsed.use {  }
-
-        // OK, used in chained call
-        contentResolver.query(null, null, null, null, null).use {
-
-        }
-
-        // KT-13372: Android Lint for Kotlin: false positive "Cursor should be freed" inside 'if' expression
-        if (true) {
-            val c = contentResolver.query(null, null, null, null, null)
-            c.close()
-        }
-    }
-}
diff --git a/idea/testData/android/lint/commitFragment.kt b/idea/testData/android/lint/commitFragment.kt
deleted file mode 100644
index fc6f333..0000000
--- a/idea/testData/android/lint/commitFragment.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCommitTransactionInspection
-
-@file:Suppress("UNUSED_VARIABLE")
-
-import android.app.Activity
-import android.app.FragmentTransaction
-import android.app.FragmentManager
-import android.os.Bundle
-
-class MainActivity : Activity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        //OK
-        val transaction = fragmentManager.beginTransaction()
-        val transaction2: FragmentTransaction
-        transaction2 = fragmentManager.beginTransaction()
-        transaction.commit()
-        transaction2.commit()
-
-        //WARNING
-        val transaction3 = fragmentManager.<warning descr="This transaction should be completed with a `commit()` call">beginTransaction</warning>()
-
-        //OK
-        fragmentManager.beginTransaction().commit()
-        fragmentManager.beginTransaction().add(null, "A").commit()
-
-        //OK KT-14470
-        Runnable {
-            val a = fragmentManager.beginTransaction()
-            a.commit()
-        }
-    }
-
-    // KT-14780: Kotlin Lint: "Missing commit() calls" false positive when the result of `commit()` is assigned or used as receiver
-    fun testResultOfCommit(fm: FragmentManager) {
-        val r1 = fm.beginTransaction().hide(fm.findFragmentByTag("aTag")).commit()
-        val r2 = fm.beginTransaction().hide(fm.findFragmentByTag("aTag")).commit().toString()
-    }
-}
diff --git a/idea/testData/android/lint/javaPerformance.kt b/idea/testData/android/lint/javaPerformance.kt
deleted file mode 100644
index 02491db..0000000
--- a/idea/testData/android/lint/javaPerformance.kt
+++ /dev/null
@@ -1,193 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintDrawAllocationInspection
-// INSPECTION_CLASS2: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUseSparseArraysInspection
-// INSPECTION_CLASS3: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUseValueOfInspection
-
-import android.annotation.SuppressLint
-import java.util.HashMap
-import android.content.Context
-import android.graphics.*
-import android.util.AttributeSet
-import android.util.SparseArray
-import android.widget.Button
-
-@SuppressWarnings("unused")
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int) : Button(context, attrs, defStyle) {
-
-    private var cachedRect: Rect? = null
-    private var shader: LinearGradient? = null
-    private var lastHeight: Int = 0
-    private var lastWidth: Int = 0
-
-    override fun onDraw(canvas: android.graphics.Canvas) {
-        super.onDraw(canvas)
-
-        // Various allocations:
-        java.lang.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">String("foo")</warning>
-        val s = java.lang.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">String("bar")</warning>
-
-        // This one should not be reported:
-        @SuppressLint("DrawAllocation")
-        val i = 5
-
-        // Cached object initialized lazily: should not complain about these
-        if (cachedRect == null) {
-            cachedRect = Rect(0, 0, 100, 100)
-        }
-        if (cachedRect == null || cachedRect!!.width() != 50) {
-            cachedRect = Rect(0, 0, 50, 100)
-        }
-
-        val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
-        dummy(1, 2)
-
-        // Non-allocations
-        super.animate()
-        dummy2(1, 2)
-
-        // This will involve allocations, but we don't track
-        // inter-procedural stuff here
-        someOtherMethod()
-    }
-
-    internal fun dummy(foo: Int?, bar: Int) {
-        dummy2(foo!!, bar)
-    }
-
-    internal fun dummy2(foo: Int, bar: Int) {
-    }
-
-    internal fun someOtherMethod() {
-        // Allocations are okay here
-        java.lang.String("foo")
-        val s = java.lang.String("bar")
-        val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
-
-
-        // Sparse array candidates
-        val myMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Int, String>()</warning>
-        // Should use SparseBooleanArray
-        val myBoolMap = <warning descr="Use `new SparseBooleanArray(...)` instead for better performance">HashMap<Int, Boolean>()</warning>
-        // Should use SparseIntArray
-        val myIntMap = java.util.<warning descr="Use new `SparseIntArray(...)` instead for better performance">HashMap<Int, Int>()</warning>
-
-        // This one should not be reported:
-        @SuppressLint("UseSparseArrays")
-        val myOtherMap = <warning descr="Use `new SparseArray<Object>(...)` instead for better performance">HashMap<Int, Any>()</warning>
-    }
-
-    protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int,
-                            x: Boolean) {
-        // wrong signature
-        java.lang.String("not an error")
-    }
-
-    protected fun onMeasure(widthMeasureSpec: Int) {
-        // wrong signature
-        java.lang.String("not an error")
-    }
-
-    protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
-                           bottom: Int, wrong: Int) {
-        // wrong signature
-        java.lang.String("not an error")
-    }
-
-    protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int) {
-        // wrong signature
-        java.lang.String("not an error")
-    }
-
-    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
-                          bottom: Int) {
-        java.lang.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">String("flag me")</warning>
-    }
-
-    @SuppressWarnings("null") // not real code
-    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
-        java.lang.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">String("flag me")</warning>
-
-        // Forbidden factory methods:
-        Bitmap.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">createBitmap(100, 100, null)</warning>
-        android.graphics.Bitmap.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">createScaledBitmap(null, 100, 100, false)</warning>
-        BitmapFactory.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">decodeFile(null)</warning>
-        val canvas: Canvas? = null
-        canvas!!.<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">getClipBounds()</warning> // allocates on your behalf
-        canvas.<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">clipBounds</warning> // allocates on your behalf
-        canvas.getClipBounds(null) // NOT an error
-
-        val layoutWidth = width
-        val layoutHeight = height
-        if (mAllowCrop && (mOverlay == null || mOverlay!!.width != layoutWidth ||
-                           mOverlay!!.height != layoutHeight)) {
-            mOverlay = Bitmap.createBitmap(layoutWidth, layoutHeight, Bitmap.Config.ARGB_8888)
-            mOverlayCanvas = Canvas(mOverlay!!)
-        }
-
-        if (widthMeasureSpec == 42) {
-            throw IllegalStateException("Test") // NOT an allocation
-        }
-
-        // More lazy init tests
-        var initialized = false
-        if (!initialized) {
-            java.lang.String("foo")
-            initialized = true
-        }
-
-        // NOT lazy initialization
-        if (!initialized || mOverlay == null) {
-            java.lang.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">String("foo")</warning>
-        }
-    }
-
-    internal fun factories() {
-        val i1 = 42
-        val l1 = 42L
-        val b1 = true
-        val c1 = 'c'
-        val f1 = 1.0f
-        val d1 = 1.0
-
-        // The following should not generate errors:
-        val i3 = Integer.valueOf(42)
-    }
-
-    private val mAllowCrop: Boolean = false
-    private var mOverlayCanvas: Canvas? = null
-    private var mOverlay: Bitmap? = null
-
-    override fun layout(l: Int, t: Int, r: Int, b: Int) {
-        // Using "this." to reference fields
-        if (this.shader == null)
-            this.shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null,
-                                         Shader.TileMode.REPEAT)
-
-        val width = width
-        val height = height
-
-        if (shader == null || lastWidth != width || lastHeight != height) {
-            lastWidth = width
-            lastHeight = height
-
-            shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null, Shader.TileMode.REPEAT)
-        }
-    }
-
-    fun inefficientSparseArray() {
-        <warning descr="Use `new SparseIntArray(...)` instead for better performance">SparseArray<Int>()</warning> // Use SparseIntArray instead
-        SparseArray<Long>()    // Use SparseLongArray instead
-        <warning descr="Use `new SparseBooleanArray(...)` instead for better performance">SparseArray<Boolean>()</warning> // Use SparseBooleanArray instead
-        SparseArray<Any>()  // OK
-    }
-
-    fun longSparseArray() {
-        // but only minSdkVersion >= 17 or if has v4 support lib
-        val myStringMap = HashMap<Long, String>()
-    }
-
-    fun byteSparseArray() {
-        // bytes easily apply to ints
-        val myByteMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Byte, String>()</warning>
-    }
-}
diff --git a/idea/testData/android/lint/javaScriptInterface.kt b/idea/testData/android/lint/javaScriptInterface.kt
deleted file mode 100644
index 8d42559..0000000
--- a/idea/testData/android/lint/javaScriptInterface.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintJavascriptInterfaceInspection
-
-import android.annotation.SuppressLint
-import android.webkit.JavascriptInterface
-import android.webkit.WebView
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "UNUSED_VALUE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class JavaScriptTestK {
-    fun test(webview: WebView) {
-        webview.addJavascriptInterface(AnnotatedObject(), "myobj")
-
-        webview.addJavascriptInterface(InheritsFromAnnotated(), "myobj")
-        webview.addJavascriptInterface(NonAnnotatedObject(), "myobj")
-
-        webview.addJavascriptInterface(null, "nothing")
-        webview.addJavascriptInterface(object : Any() { @JavascriptInterface fun method() {} }, "nothing")
-        webview.addJavascriptInterface(JavascriptFace(), "nothing")
-
-        var o: Any = NonAnnotatedObject()
-        webview.addJavascriptInterface(o, "myobj")
-        o = InheritsFromAnnotated()
-        webview.addJavascriptInterface(o, "myobj")
-    }
-
-    fun test(webview: WebView, object1: AnnotatedObject, object2: NonAnnotatedObject) {
-        webview.addJavascriptInterface(object1, "myobj")
-        webview.addJavascriptInterface(object2, "myobj")
-    }
-
-    @SuppressLint("JavascriptInterface")
-    fun testSuppressed(webview: WebView) {
-        webview.addJavascriptInterface(NonAnnotatedObject(), "myobj")
-    }
-
-    fun testLaterReassignment(webview: WebView) {
-        var o: Any = NonAnnotatedObject()
-        val t = o
-        webview.addJavascriptInterface(t, "myobj")
-        o = AnnotatedObject()
-    }
-
-    class NonAnnotatedObject() {
-        fun test1() {}
-        fun test2() {}
-    }
-
-    open class AnnotatedObject {
-        @JavascriptInterface
-        open fun test1() {}
-
-        open fun test2() {}
-
-        @JavascriptInterface
-        fun test3() {}
-    }
-
-    class InheritsFromAnnotated : AnnotatedObject() {
-        override fun test1() {}
-        override fun test2() {}
-    }
-
-}
-
-class JavascriptFace {
-    fun method() {}
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/layoutInflation.kt b/idea/testData/android/lint/layoutInflation.kt
deleted file mode 100644
index 65bd1e7..0000000
--- a/idea/testData/android/lint/layoutInflation.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInflateParamsInspection
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.BaseAdapter
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-abstract class LayoutInflationTest : BaseAdapter() {
-    lateinit var mInflater: LayoutInflater
-
-    override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
-        var view = <warning descr="[VARIABLE_WITH_REDUNDANT_INITIALIZER] Variable 'view' initializer is redundant">convertView</warning>
-        <warning descr="[UNUSED_VALUE] The value 'mInflater.inflate(R.layout.your_layout, null)' assigned to 'var view: View defined in LayoutInflationTest.getView' is never used">view =</warning> mInflater.inflate(R.layout.your_layout, null)
-        <warning descr="[UNUSED_VALUE] The value 'mInflater.inflate(R.layout.your_layout, null, true)' assigned to 'var view: View defined in LayoutInflationTest.getView' is never used">view =</warning> mInflater.inflate(R.layout.your_layout, null, true)
-        view = mInflater.inflate(R.layout.your_layout, parent)
-        view = WeirdInflater.inflate(view, null)
-
-        return view
-    }
-
-    object WeirdInflater {
-        fun inflate(view: View, parent: View?) = view
-    }
-
-    object R {
-        object layout {
-            val your_layout = 1
-        }
-    }
-}
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-abstract class LayoutInflationTest2 : BaseAdapter() {
-    lateinit var mInflater: LayoutInflater
-
-    override fun getView(position: Int, convertView: View, parent: ViewGroup): View? {
-        return if (true) {
-            mInflater.inflate(R.layout.your_layout, parent)
-        } else {
-            null
-        }
-    }
-
-    object R {
-        object layout {
-            val your_layout = 1
-        }
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/log.kt b/idea/testData/android/lint/log.kt
deleted file mode 100644
index ebf4d97..0000000
--- a/idea/testData/android/lint/log.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLogConditionalInspection
-// INSPECTION_CLASS2: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLogTagMismatchInspection
-// INSPECTION_CLASS3: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLongLogTagInspection
-
-import android.annotation.SuppressLint
-import android.util.Log
-import android.util.Log.DEBUG
-
-@SuppressWarnings("UnusedDeclaration")
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class LogTest {
-
-    fun checkConditional(m: String) {
-        Log.d(TAG1, "message") // ok: unconditional, but not performing computation
-        Log.d(TAG1, m) // ok: unconditional, but not performing computation
-        Log.d(TAG1, "a" + "b") // ok: unconditional, but not performing non-constant computation
-        Log.d(TAG1, Constants.MY_MESSAGE) // ok: unconditional, but constant string
-        Log.<warning descr="The log call Log.i(...) should be conditional: surround with `if (Log.isLoggable(...))` or `if (BuildConfig.DEBUG) { ... }`">i(TAG1, "message" + m)</warning> // error: unconditional w/ computation
-        Log.<warning descr="The log call Log.i(...) should be conditional: surround with `if (Log.isLoggable(...))` or `if (BuildConfig.DEBUG) { ... }`">i(TAG1, toString())</warning> // error: unconditional w/ computation
-        Log.e(TAG1, toString()) // ok: only flagging debug/info messages
-        Log.w(TAG1, toString()) // ok: only flagging debug/info messages
-        Log.wtf(TAG1, toString()) // ok: only flagging debug/info messages
-        if (Log.isLoggable(TAG1, 0)) {
-            Log.d(TAG1, toString()) // ok: conditional
-        }
-    }
-
-    fun checkWrongTag(tag: String) {
-        if (Log.isLoggable(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `getTAG1` versus `getTAG2` (Conflicting tag)">TAG1</error>, Log.DEBUG)) {
-            Log.d(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `getTAG1` versus `getTAG2`">TAG2</error>, "message") // warn: mismatched tags!
-        }
-        if (Log.isLoggable("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `\"my_tag\"` versus `\"other_tag\"` (Conflicting tag)">my_tag</error>", Log.DEBUG)) {
-            Log.d("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `\"my_tag\"` versus `\"other_tag\"`">other_tag</error>", "message") // warn: mismatched tags!
-        }
-        if (Log.isLoggable("my_tag", Log.DEBUG)) {
-            Log.d("my_tag", "message") // ok: strings equal
-        }
-        if (Log.isLoggable(tag, Log.DEBUG)) {
-            Log.d(tag, "message") // ok: same variable
-        }
-    }
-
-    fun checkLongTag(shouldLog: Boolean) {
-        if (shouldLog) {
-            // String literal tags
-            Log.d("short_tag", "message") // ok: short
-            Log.<error descr="The logging tag can be at most 23 characters, was 43 (really_really_really_really_really_long_tag)">d("really_really_really_really_really_long_tag", "message")</error> // error: too long
-
-            // Resolved field tags
-            Log.d(TAG1, "message") // ok: short
-            Log.d(TAG22, "message") // ok: short
-            Log.d(TAG23, "message") // ok: threshold
-            Log.<error descr="The logging tag can be at most 23 characters, was 24 (123456789012345678901234)">d(TAG24, "message")</error> // error: too long
-            Log.<error descr="The logging tag can be at most 23 characters, was 39 (MyReallyReallyReallyReallyReallyLongTag)">d(LONG_TAG, "message")</error> // error: way too long
-
-            // Locally defined variable tags
-            val LOCAL_TAG = "MyReallyReallyReallyReallyReallyLongTag"
-            Log.<error descr="The logging tag can be at most 23 characters, was 39 (MyReallyReallyReallyReallyReallyLongTag)">d(LOCAL_TAG, "message")</error> // error: too long
-
-            // Concatenated tags
-            Log.<error descr="The logging tag can be at most 23 characters, was 28 (1234567890123456789012MyTag1)">d(TAG22 + TAG1, "message")</error> // error: too long
-            Log.<error descr="The logging tag can be at most 23 characters, was 27 (1234567890123456789012MyTag)">d(TAG22 + "MyTag", "message")</error> // error: too long
-        }
-    }
-
-    fun checkWrongLevel(tag: String) {
-        if (Log.isLoggable(TAG1, Log.DEBUG)) {
-            Log.d(TAG1, "message") // ok: right level
-        }
-        if (Log.isLoggable(TAG1, Log.INFO)) {
-            Log.i(TAG1, "message") // ok: right level
-        }
-        if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v` (Conflicting tag)">Log.DEBUG</error>)) {
-            Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v`">v</error>(TAG1, "message") // warn: wrong level
-        }
-        if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v` (Conflicting tag)">DEBUG</error>)) {
-            // static import of level
-            Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v`">v</error>(TAG1, "message") // warn: wrong level
-        }
-        if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d` (Conflicting tag)">Log.VERBOSE</error>)) {
-            Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d`">d</error>(TAG1, "message") // warn? verbose is a lower logging level, which includes debug
-        }
-        if (Log.isLoggable(TAG1, Constants.MY_LEVEL)) {
-            Log.d(TAG1, "message") // ok: unknown level alias
-        }
-    }
-
-    @SuppressLint("all")
-    fun suppressed1() {
-        Log.d(TAG1, "message") // ok: suppressed
-    }
-
-    @SuppressLint("LogConditional")
-    fun suppressed2() {
-        Log.d(TAG1, "message") // ok: suppressed
-    }
-
-    private object Constants {
-        val MY_MESSAGE = "My Message"
-        val MY_LEVEL = 5
-    }
-
-    companion object {
-        private val TAG1 = "MyTag1"
-        private val TAG2 = "MyTag2"
-        private val TAG22 = "1234567890123456789012"
-        private val TAG23 = "12345678901234567890123"
-        private val TAG24 = "123456789012345678901234"
-        private val LONG_TAG = "MyReallyReallyReallyReallyReallyLongTag"
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/noInternationalSms.kt b/idea/testData/android/lint/noInternationalSms.kt
deleted file mode 100644
index 31fecc2..0000000
--- a/idea/testData/android/lint/noInternationalSms.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUnlocalizedSmsInspection
-
-import android.content.Context
-import android.telephony.SmsManager
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class NonInternationalizedSmsDetectorTest {
-    private fun sendLocalizedMessage(context: Context) {
-        // Don't warn here
-        val sms = SmsManager.getDefault()
-        sms.sendTextMessage("+1234567890", null, null, null, null)
-    }
-
-    private fun sendAlternativeCountryPrefix(context: Context) {
-        // Do warn here
-        val sms = SmsManager.getDefault()
-        sms.sendMultipartTextMessage("<warning descr="To make sure the SMS can be sent by all users, please start the SMS number with a + and a country code or restrict the code invocation to people in the country you are targeting.">001234567890</warning>", null, null, null, null)
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/overrideConcrete.kt b/idea/testData/android/lint/overrideConcrete.kt
deleted file mode 100644
index 55a5bb3..0000000
--- a/idea/testData/android/lint/overrideConcrete.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideAbstractInspection
-
-import android.annotation.SuppressLint
-import android.annotation.TargetApi
-import android.os.Build
-import android.service.notification.NotificationListenerService
-import android.service.notification.StatusBarNotification
-
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class OverrideConcreteTest2 {
-    // OK: This one specifies both methods
-    private open class MyNotificationListenerService1 : NotificationListenerService() {
-        override fun onNotificationPosted(statusBarNotification: StatusBarNotification) {
-        }
-
-        override fun onNotificationRemoved(statusBarNotification: StatusBarNotification) {
-        }
-    }
-
-    // Error: Misses onNotificationPosted
-    private class <error descr="Must override `android.service.notification.NotificationListenerService.onNotificationPosted(android.service.notification.StatusBarNotification)`: Method was abstract until 21, and your `minSdkVersion` is 18">MyNotificationListenerService2</error> : NotificationListenerService() {
-        override fun onNotificationRemoved(statusBarNotification: StatusBarNotification) {
-        }
-    }
-
-    // Error: Misses onNotificationRemoved
-    private open class <error descr="Must override `android.service.notification.NotificationListenerService.onNotificationRemoved(android.service.notification.StatusBarNotification)`: Method was abstract until 21, and your `minSdkVersion` is 18">MyNotificationListenerService3</error> : NotificationListenerService() {
-        override fun onNotificationPosted(statusBarNotification: StatusBarNotification) {
-        }
-    }
-
-    // Error: Missing both; wrong signatures (first has wrong arg count, second has wrong type)
-    private class <error descr="Must override `android.service.notification.NotificationListenerService.onNotificationPosted(android.service.notification.StatusBarNotification)`: Method was abstract until 21, and your `minSdkVersion` is 18">MyNotificationListenerService4</error> : NotificationListenerService() {
-        fun onNotificationPosted(statusBarNotification: StatusBarNotification, flags: Int) {
-        }
-
-        fun onNotificationRemoved(statusBarNotification: Int) {
-        }
-    }
-
-    // OK: Inherits from a class which define both
-    private class MyNotificationListenerService5 : MyNotificationListenerService1()
-
-    // OK: Inherits from a class which defines only one, but the other one is defined here
-    private class MyNotificationListenerService6 : MyNotificationListenerService3() {
-        override fun onNotificationRemoved(statusBarNotification: StatusBarNotification) {
-        }
-    }
-
-    // Error: Inheriting from a class which only defines one
-    private class <error descr="Must override `android.service.notification.NotificationListenerService.onNotificationRemoved(android.service.notification.StatusBarNotification)`: Method was abstract until 21, and your `minSdkVersion` is 18">MyNotificationListenerService7</error> : MyNotificationListenerService3()
-
-    // OK: Has target api setting a local version that is high enough
-    @TargetApi(21)
-    private class MyNotificationListenerService8 : NotificationListenerService()
-
-    // OK: Suppressed
-    @SuppressLint("OverrideAbstract")
-    private class MyNotificationListenerService9 : MyNotificationListenerService1()
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/parcel.kt b/idea/testData/android/lint/parcel.kt
deleted file mode 100644
index 600130a..0000000
--- a/idea/testData/android/lint/parcel.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintParcelCreatorInspection
-
-@file:Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-import android.os.Parcel
-import android.os.Parcelable
-
-class <error descr="This class implements `Parcelable` but does not provide a `CREATOR` field">MyParcelable1</error> : Parcelable {
-    override fun describeContents() = 0
-    override fun writeToParcel(arg0: Parcel, arg1: Int) {}
-}
-
-internal class MyParcelable2 : Parcelable {
-    override fun describeContents() = 0
-
-    override fun writeToParcel(arg0: Parcel, arg1: Int) {}
-
-    companion object {
-        @JvmField
-        val CREATOR: Parcelable.Creator<String> = object : Parcelable.Creator<String> {
-            override fun newArray(size: Int) = null!!
-            override fun createFromParcel(source: Parcel?) = null!!
-        }
-    }
-}
-
-internal class MyParcelable3 : Parcelable {
-    override fun describeContents() = 0
-    override fun writeToParcel(arg0: Parcel, arg1: Int) {}
-
-    companion object {
-        @JvmField
-        val CREATOR = 0 // Wrong type
-    }
-}
-
-class RecyclerViewScrollPosition(val position: Int, val topOffset: Int): Parcelable {
-    override fun describeContents(): Int = 0
-    override fun writeToParcel(dest: Parcel, flags: Int) {
-        dest.writeInt(position)
-        dest.writeInt(topOffset)
-    }
-
-    companion object {
-        @JvmField
-        val CREATOR = object : Parcelable.Creator<RecyclerViewScrollPosition> {
-            override fun createFromParcel(parcel: Parcel): RecyclerViewScrollPosition {
-                val position = parcel.readInt()
-                val topOffset = parcel.readInt()
-                return RecyclerViewScrollPosition(position, topOffset)
-            }
-
-            override fun newArray(size: Int): Array<RecyclerViewScrollPosition?> = arrayOfNulls(size)
-        }
-
-    }
-}
-
-class RecyclerViewScrollPositionWithoutJvmF(val position: Int, val topOffset: Int): Parcelable {
-    override fun describeContents(): Int = 0
-    override fun writeToParcel(dest: Parcel, flags: Int) {
-        dest.writeInt(position)
-        dest.writeInt(topOffset)
-    }
-
-    companion object {
-        val CREATOR = object : Parcelable.Creator<RecyclerViewScrollPosition> {
-            override fun createFromParcel(parcel: Parcel): RecyclerViewScrollPosition {
-                val position = parcel.readInt()
-                val topOffset = parcel.readInt()
-                return RecyclerViewScrollPosition(position, topOffset)
-            }
-
-            override fun newArray(size: Int): Array<RecyclerViewScrollPosition?> = arrayOfNulls(size)
-        }
-
-    }
-}
-
-class RecyclerViewScrollPosition2(val position: Int, val topOffset: Int): Parcelable {
-    override fun describeContents(): Int = 0
-    override fun writeToParcel(dest: Parcel, flags: Int) {
-        dest.writeInt(position)
-        dest.writeInt(topOffset)
-    }
-
-    companion object CREATOR: Parcelable.Creator<RecyclerViewScrollPosition> {
-        override fun createFromParcel(parcel: Parcel): RecyclerViewScrollPosition {
-            val position = parcel.readInt()
-            val topOffset = parcel.readInt()
-            return RecyclerViewScrollPosition(position, topOffset)
-        }
-
-        override fun newArray(size: Int): Array<RecyclerViewScrollPosition?> = arrayOfNulls(size)
-    }
-}
-
-internal abstract class MyParcelable4 : Parcelable {
-    override fun describeContents() = 0
-    override fun writeToParcel(arg0: Parcel, arg1: Int) {}
-}
diff --git a/idea/testData/android/lint/sdCardTest.kt b/idea/testData/android/lint/sdCardTest.kt
deleted file mode 100644
index 41c48d4..0000000
--- a/idea/testData/android/lint/sdCardTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
-
-import java.io.File
-import android.content.Intent
-import android.net.Uri
-
-/**
- * Ignore comments - create("/sdcard/foo")
- */
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class SdCardTest {
-    internal var deviceDir = File("<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard/vr</warning>")
-
-    init {
-        if (PROFILE_STARTUP) {
-            android.os.Debug.startMethodTracing("<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard/launcher</warning></warning>")
-        }
-
-        if (File("<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard</warning></warning>").exists()) {
-    }
-    val FilePath = "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard/</warning></warning>" + File("test")
-    System.setProperty("foo.bar", "file://sdcard")
-
-
-    val intent = Intent(Intent.ACTION_PICK)
-    intent.setDataAndType(Uri.parse("<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">file://sdcard/foo.json</warning></warning>"), "application/bar-json")
-    intent.putExtra("path-filter", "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard(/.+)*</warning></warning>")
-    intent.putExtra("start-dir", "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard</warning></warning>")
-    val mypath = "<warning descr="Do not hardcode \"`/data/`\"; use `Context.getFilesDir().getPath()` instead"><warning descr="Do not hardcode \"`/data/`\"; use `Context.getFilesDir().getPath()` instead">/data/data/foo</warning></warning>"
-    val base = "<warning descr="Do not hardcode \"`/data/`\"; use `Context.getFilesDir().getPath()` instead"><warning descr="Do not hardcode \"`/data/`\"; use `Context.getFilesDir().getPath()` instead">/data/data/foo.bar/test-profiling</warning></warning>"
-    val s = "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead"><warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">file://sdcard/foo</warning></warning>"
-}
-
-companion object {
-    private val PROFILE_STARTUP = true
-    private val SDCARD_TEST_HTML = "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard/test.html</warning>"
-    val SDCARD_ROOT = "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard</warning>"
-    val PACKAGES_PATH = "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard/o/packages/</warning>"
-}
-}
diff --git a/idea/testData/android/lint/setJavaScriptEnabled.kt b/idea/testData/android/lint/setJavaScriptEnabled.kt
deleted file mode 100644
index 2c11557..0000000
--- a/idea/testData/android/lint/setJavaScriptEnabled.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSetJavaScriptEnabledInspection
-
-import android.annotation.SuppressLint
-import android.app.Activity
-import android.webkit.WebView
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-public class HelloWebApp : Activity() {
-
-    fun test(webView: WebView) {
-        webView.settings.<warning descr="Using `setJavaScriptEnabled` can introduce XSS vulnerabilities into you application, review carefully.">javaScriptEnabled</warning> = true // bad
-        webView.getSettings().<warning descr="Using `setJavaScriptEnabled` can introduce XSS vulnerabilities into you application, review carefully.">setJavaScriptEnabled(true)</warning> // bad
-        webView.getSettings().setJavaScriptEnabled(false) // good
-        webView.loadUrl("file:///android_asset/www/index.html")
-    }
-
-    @SuppressLint("SetJavaScriptEnabled")
-    fun suppressed(webView: WebView) {
-        webView.getSettings().javaScriptEnabled = true; // bad
-        webView.getSettings().setJavaScriptEnabled(true) // bad
-        webView.getSettings().setJavaScriptEnabled(false); // good
-        webView.loadUrl("file:///android_asset/www/index.html");
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/sharedPrefs.kt b/idea/testData/android/lint/sharedPrefs.kt
deleted file mode 100644
index 37e5514..0000000
--- a/idea/testData/android/lint/sharedPrefs.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintCommitPrefEditsInspection
-
-import android.app.Activity
-import android.content.Context
-import android.os.Bundle
-import android.preference.PreferenceManager
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class SharedPrefsText(context: Context) : Activity() {
-    // OK 1
-    fun onCreate1(savedInstanceState: Bundle) {
-        super.onCreate(savedInstanceState)
-        val preferences = PreferenceManager.getDefaultSharedPreferences(this)
-        val editor = preferences.edit()
-        editor.putString("foo", "bar")
-        editor.putInt("bar", 42)
-        editor.commit()
-    }
-
-    // OK 2
-    fun onCreate2(savedInstanceState: Bundle, apply: Boolean) {
-        super.onCreate(savedInstanceState)
-        val preferences = PreferenceManager.getDefaultSharedPreferences(this)
-        val editor = preferences.edit()
-        editor.putString("foo", "bar")
-        editor.putInt("bar", 42)
-        if (apply) {
-            editor.apply()
-        }
-    }
-
-    // Not a bug
-    fun test(foo: Foo) {
-        val bar1 = foo.edit()
-        val bar3 = edit()
-        apply()
-    }
-
-    internal fun apply() {
-
-    }
-
-    fun edit(): Bar {
-        return Bar()
-    }
-
-    class Foo {
-        internal fun edit(): Bar {
-            return Bar()
-        }
-    }
-
-    class Bar
-
-    // Bug
-    fun bug1(savedInstanceState: Bundle) {
-        super.onCreate(savedInstanceState)
-        val preferences = PreferenceManager.getDefaultSharedPreferences(this)
-        val editor = preferences.<warning descr="`SharedPreferences.edit()` without a corresponding `commit()` or `apply()` call">edit()</warning>
-        editor.putString("foo", "bar")
-        editor.putInt("bar", 42)
-    }
-
-    init {
-        val preferences = PreferenceManager.getDefaultSharedPreferences(context)
-        val editor = preferences.<warning descr="`SharedPreferences.edit()` without a corresponding `commit()` or `apply()` call"><warning descr="`SharedPreferences.edit()` without a corresponding `commit()` or `apply()` call">edit()</warning></warning>
-        editor.putString("foo", "bar")
-    }
-
-    fun testResultOfCommit() {
-        val r1 = PreferenceManager.getDefaultSharedPreferences(this).edit().putString("wat", "wat").commit()
-        val r2 = PreferenceManager.getDefaultSharedPreferences(this).edit().putString("wat", "wat").commit().toString()
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/showDiagnosticsWhenFileIsRed.kt b/idea/testData/android/lint/showDiagnosticsWhenFileIsRed.kt
deleted file mode 100644
index 5623005..0000000
--- a/idea/testData/android/lint/showDiagnosticsWhenFileIsRed.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSQLiteStringInspection
-
-import android.database.sqlite.SQLiteDatabase
-
-fun test(db: SQLiteDatabase) {
-    val <warning descr="[UNUSED_VARIABLE] Variable 'a' is never used">a</warning>: String = <error descr="[CONSTANT_EXPECTED_TYPE_MISMATCH] The integer literal does not conform to the expected type String">1</error>
-
-    db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example, strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning>
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/sqlite.kt b/idea/testData/android/lint/sqlite.kt
deleted file mode 100644
index 93eab53..0000000
--- a/idea/testData/android/lint/sqlite.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSQLiteStringInspection
-
-import android.database.sqlite.SQLiteDatabase
-
-fun test(db: SQLiteDatabase) {
-    db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example, strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning>
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/systemServices.kt b/idea/testData/android/lint/systemServices.kt
deleted file mode 100644
index 2e68605..0000000
--- a/idea/testData/android/lint/systemServices.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintServiceCastInspection
-
-import android.content.ClipboardManager
-import android.app.Activity
-import android.app.WallpaperManager
-import android.content.Context
-import android.hardware.display.DisplayManager
-import android.service.wallpaper.WallpaperService
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class SystemServiceTest : Activity() {
-
-    fun test1() {
-        val displayServiceOk = getSystemService(DISPLAY_SERVICE) as DisplayManager
-        val displayServiceWrong = <error descr="Suspicious cast to `DisplayManager` for a `DEVICE_POLICY_SERVICE`: expected `DevicePolicyManager`">getSystemService(DEVICE_POLICY_SERVICE) as DisplayManager</error>
-        val wallPaperOk = getSystemService(WALLPAPER_SERVICE) as WallpaperService
-        val wallPaperWrong = <error descr="Suspicious cast to `WallpaperManager` for a `WALLPAPER_SERVICE`: expected `WallpaperService`">getSystemService(WALLPAPER_SERVICE) as WallpaperManager</error>
-    }
-
-    fun test2(context: Context) {
-        val displayServiceOk = context.getSystemService(DISPLAY_SERVICE) as DisplayManager
-        val displayServiceWrong = <error descr="Suspicious cast to `DisplayManager` for a `DEVICE_POLICY_SERVICE`: expected `DevicePolicyManager`">context.getSystemService(DEVICE_POLICY_SERVICE) as DisplayManager</error>
-    }
-
-    fun clipboard(context: Context) {
-        val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
-        val clipboard2 = context.getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/toast.kt b/idea/testData/android/lint/toast.kt
deleted file mode 100644
index 9cb2510..0000000
--- a/idea/testData/android/lint/toast.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintShowToastInspection
-
-import android.app.Activity
-import android.content.Context
-import android.widget.Toast
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class ToastTest(context: Context) : Activity() {
-    private fun createToast(context: Context): Toast {
-        // Don't warn here
-        return Toast.makeText(context, "foo", Toast.LENGTH_LONG)
-    }
-    
-    private fun insideRunnable(context: Context) {
-        Runnable {
-            Toast.makeText(context, "foo", Toast.LENGTH_LONG).show()
-        }
-
-        Runnable {
-            val toast = Toast.makeText(context, "foo", Toast.LENGTH_LONG)
-            if (5 > 3) {
-                toast.show()
-            }
-        }
-
-        Runnable {
-            Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
-        }
-    }
-
-    private fun showToast(context: Context) {
-        // Don't warn here
-        val toast = Toast.makeText(context, "foo", Toast.LENGTH_LONG)
-        System.out.println("Other intermediate code here")
-        val temp = 5 + 2
-        toast.show()
-    }
-
-    private fun showToast2(context: Context) {
-        // Don't warn here
-        val duration = Toast.LENGTH_LONG
-        Toast.makeText(context, "foo", Toast.LENGTH_LONG).show()
-        Toast.makeText(context, R.string.app_name, duration).show()
-    }
-
-    private fun broken(context: Context) {
-        // Errors
-        Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
-        val toast = Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, R.string.app_name, <warning descr="Expected duration `Toast.LENGTH_SHORT` or `Toast.LENGTH_LONG`, a custom duration value is not supported">5000</warning>)
-        toast.duration
-    }
-
-    init {
-        Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
-    }
-
-    @android.annotation.SuppressLint("ShowToast")
-    private fun checkSuppress1(context: Context) {
-        val toast = Toast.makeText(this, "MyToast", Toast.LENGTH_LONG)
-    }
-
-    private fun checkSuppress2(context: Context) {
-        @android.annotation.SuppressLint("ShowToast")
-        val toast = Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(this, "MyToast", Toast.LENGTH_LONG)
-    }
-
-    class R {
-        object string {
-            val app_name = 1
-        }
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/valueOf.kt b/idea/testData/android/lint/valueOf.kt
deleted file mode 100644
index 1702302..0000000
--- a/idea/testData/android/lint/valueOf.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintUseValueOfInspection
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class Simple {
-    fun test() {
-        <warning descr="Use `Integer.valueOf(5)` instead">Integer(5)</warning>
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/velocityTrackerRecycle.kt b/idea/testData/android/lint/velocityTrackerRecycle.kt
deleted file mode 100644
index 73a5933..0000000
--- a/idea/testData/android/lint/velocityTrackerRecycle.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintRecycleInspection
-
-@file:Suppress("UNUSED_VARIABLE")
-
-import android.app.Activity
-import android.os.Bundle
-import android.view.VelocityTracker
-
-class MainActivity : Activity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        VelocityTracker.<warning descr="This `VelocityTracker` should be recycled after use with `#recycle()`">obtain</warning>()
-
-        VelocityTracker.obtain().recycle()
-
-        val v1 = VelocityTracker.<warning descr="This `VelocityTracker` should be recycled after use with `#recycle()`">obtain</warning>()
-
-        val v2 = VelocityTracker.obtain()
-        v2.recycle()
-    }
-}
diff --git a/idea/testData/android/lint/viewConstructor.kt b/idea/testData/android/lint/viewConstructor.kt
deleted file mode 100644
index 2087cee..0000000
--- a/idea/testData/android/lint/viewConstructor.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintViewConstructorInspection
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-import android.widget.TextView
-
-class View1(context: Context?) : View(context)
-class View2(context: Context?, attrs: AttributeSet?) : View(context, attrs)
-class View3(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : TextView(context, attrs, defStyleAttr)
-
-// Error
-class <warning descr="Custom view `View4` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`">View4</warning>(<warning descr="[UNUSED_PARAMETER] Parameter 'int' is never used">int</warning>: Int, context: Context?) : View(context)
-
-// Error
-class <warning descr="Custom view `View5` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`">View5</warning>(context: Context?, attrs: AttributeSet?, val name: String) : View(context, attrs)
-
-class View6 : View {
-    constructor(context: Context) : super(context) {
-
-    }
-}
-
-class View7 : View {
-    constructor(context: Context) : super(context)
-    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
-}
-
-// Error
-class <warning descr="Custom view `View8` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`">View8</warning> : View {
-    constructor(context: Context, <warning descr="[UNUSED_PARAMETER] Parameter 'a' is never used">a</warning>: Int) : super(context)
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/viewHolder.kt b/idea/testData/android/lint/viewHolder.kt
deleted file mode 100644
index ad2f7fc..0000000
--- a/idea/testData/android/lint/viewHolder.kt
+++ /dev/null
@@ -1,154 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintViewHolderInspection
-
-@file:Suppress("NAME_SHADOWING", "unused", "UNUSED_VALUE", "VARIABLE_WITH_REDUNDANT_INITIALIZER", "UNUSED_VARIABLE")
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.BaseAdapter
-import android.widget.LinearLayout
-import android.widget.TextView
-import java.util.ArrayList
-
-@SuppressWarnings("ConstantConditions", "UnusedDeclaration")
-abstract class ViewHolderTest : BaseAdapter() {
-    override fun getCount() = 0
-    override fun getItem(position: Int) = null
-    override fun getItemId(position: Int) = 0L
-
-    class Adapter1 : ViewHolderTest() {
-        override fun getView(position: Int, convertView: View, parent: ViewGroup) = null
-    }
-
-    class Adapter2 : ViewHolderTest() {
-        lateinit var mInflater: LayoutInflater
-
-        override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
-            var convertView = convertView
-            // Should use View Holder pattern here
-            convertView = mInflater.<warning descr="Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling">inflate(R.layout.your_layout, null)</warning>
-
-            val text = convertView.findViewById(R.id.text) as TextView
-            text.text = "Position " + position
-
-            return convertView
-        }
-    }
-
-    class Adapter3 : ViewHolderTest() {
-        lateinit var mInflater: LayoutInflater
-
-        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
-            var convertView = convertView
-            // Already using View Holder pattern
-            if (convertView == null) {
-                convertView = mInflater.inflate(R.layout.your_layout, null)
-            }
-
-            val text = convertView!!.findViewById(R.id.text) as TextView
-            text.text = "Position " + position
-
-            return convertView
-        }
-    }
-
-    class Adapter4 : ViewHolderTest() {
-        lateinit var mInflater: LayoutInflater
-
-        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
-            var convertView = convertView
-            // Already using View Holder pattern
-            //noinspection StatementWithEmptyBody
-            if (convertView != null) {
-            } else {
-                convertView = mInflater.inflate(R.layout.your_layout, null)
-            }
-
-            val text = convertView!!.findViewById(R.id.text) as TextView
-            text.text = "Position " + position
-
-            return convertView
-        }
-    }
-
-    class Adapter5 : ViewHolderTest() {
-        lateinit var mInflater: LayoutInflater
-
-        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
-            var convertView = convertView
-            // Already using View Holder pattern
-            convertView = if (convertView == null) mInflater.inflate(R.layout.your_layout, null) else convertView
-
-            val text = convertView!!.findViewById(R.id.text) as TextView
-            text.text = "Position " + position
-
-            return convertView
-        }
-    }
-
-    class Adapter6 : ViewHolderTest() {
-        private val mContext: Context? = null
-        private var mLayoutInflator: LayoutInflater? = null
-        private lateinit var mLapTimes: ArrayList<Double>
-
-        override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
-            if (mLayoutInflator == null)
-                mLayoutInflator = mContext!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
-
-            var v: View? = convertView
-            if (v == null) v = mLayoutInflator!!.inflate(R.layout.your_layout, null)
-
-            val listItemHolder = v!!.findViewById(R.id.laptimes_list_item_holder) as LinearLayout
-            listItemHolder.removeAllViews()
-
-            for (i in 1..5) {
-                val lapItemView = mLayoutInflator!!.inflate(R.layout.laptime_item, null)
-                if (i == 0) {
-                    val t = lapItemView.findViewById(R.id.laptime_text) as TextView
-                }
-
-                val t2 = lapItemView.findViewById(R.id.laptime_text2) as TextView
-                if (i < mLapTimes.size - 1 && mLapTimes.size > 1) {
-                    var laptime = mLapTimes[i] - mLapTimes[i + 1]
-                    if (laptime < 0) laptime = mLapTimes[i]
-                }
-
-                listItemHolder.addView(lapItemView)
-
-            }
-            return v
-        }
-    }
-
-    class Adapter7 : ViewHolderTest() {
-        lateinit var inflater: LayoutInflater
-
-        override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
-            var rootView: View? = convertView
-            val itemViewType = getItemViewType(position)
-            when (itemViewType) {
-                0 -> {
-                    if (rootView != null)
-                        return rootView
-                    rootView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
-                }
-            }
-            return rootView!!
-        }
-    }
-
-    class R {
-        object layout {
-            val your_layout = 1
-            val laptime_item = 2
-        }
-
-        object id {
-            val laptime_text = 1
-            val laptime_text2 = 2
-            val laptimes_list_item_holder = 3
-            val text = 4
-        }
-    }
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/wrongAnnotation.kt b/idea/testData/android/lint/wrongAnnotation.kt
deleted file mode 100644
index 62cb9f4..0000000
--- a/idea/testData/android/lint/wrongAnnotation.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintLocalSuppressInspection
-
-import android.annotation.SuppressLint
-import android.view.View
-
-@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
-class WrongAnnotation2 {
-    @SuppressLint("NewApi")
-    private val field1: Int = 0
-
-    @SuppressLint("NewApi")
-    private val field2 = 5
-
-    companion object {
-        @SuppressLint("NewApi") // Valid: class-file check on method
-        fun foobar(view: View, @SuppressLint("NewApi") foo: Int) {
-            // Invalid: class-file check
-            @SuppressLint("NewApi") // Invalid
-            val a: Boolean
-            @SuppressLint("SdCardPath", "NewApi") // Invalid: class-file based check on local variable
-            val b: Boolean
-            @android.annotation.SuppressLint("SdCardPath", "NewApi") // Invalid (FQN)
-            val c: Boolean
-            @SuppressLint("SdCardPath") // Valid: AST-based check
-            val d: Boolean
-        }
-
-        init {
-            // Local variable outside method: invalid
-            @SuppressLint("NewApi")
-            val localvar = 5
-        }
-
-        private fun test() {
-            @SuppressLint("NewApi") // Invalid
-            val a = View.MEASURED_STATE_MASK
-        }
-    }
-}
diff --git a/idea/testData/android/lint/wrongImport.kt b/idea/testData/android/lint/wrongImport.kt
deleted file mode 100644
index b688362..0000000
--- a/idea/testData/android/lint/wrongImport.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSuspiciousImportInspection
-
-//Warning
-<warning descr="Don't include `android.R` here; use a fully qualified name for each usage instead">import android.R</warning>
-
-fun a() {
-    R.id.button1
-}
\ No newline at end of file
diff --git a/idea/testData/android/lint/wrongViewCall.kt b/idea/testData/android/lint/wrongViewCall.kt
deleted file mode 100644
index 0ee6e92..0000000
--- a/idea/testData/android/lint/wrongViewCall.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintWrongCallInspection
-
-import android.content.Context
-import android.graphics.Canvas
-import android.util.AttributeSet
-import android.widget.FrameLayout
-import android.widget.LinearLayout
-
-abstract class WrongViewCall(context: Context, attrs: AttributeSet, defStyle: Int) : LinearLayout(context, attrs, defStyle) {
-    private val child: MyChild? = null
-
-    override fun onDraw(canvas: Canvas) {
-        super.onDraw(canvas)
-        child?.<error descr="Suspicious method call; should probably call \"`draw`\" rather than \"`onDraw`\"">onDraw</error>(canvas)
-    }
-
-    private inner class MyChild(context: Context, attrs: AttributeSet, defStyle: Int) : FrameLayout(context, attrs, defStyle) {
-
-        public override fun onDraw(canvas: Canvas) {
-            super.onDraw(canvas)
-        }
-    }
-}
diff --git a/idea/testData/android/lintQuickfix/parcelable/missingCreator.kt b/idea/testData/android/lintQuickfix/parcelable/missingCreator.kt
index 6274bc4..5323b6d 100644
--- a/idea/testData/android/lintQuickfix/parcelable/missingCreator.kt
+++ b/idea/testData/android/lintQuickfix/parcelable/missingCreator.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add Parcelable Implementation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintParcelCreatorInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintParcelCreatorInspection
 import android.os.Parcel
 import android.os.Parcelable
 
diff --git a/idea/testData/android/lintQuickfix/parcelable/noImplementation.kt b/idea/testData/android/lintQuickfix/parcelable/noImplementation.kt
index e045a31..77379bd 100644
--- a/idea/testData/android/lintQuickfix/parcelable/noImplementation.kt
+++ b/idea/testData/android/lintQuickfix/parcelable/noImplementation.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add Parcelable Implementation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintParcelCreatorInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintParcelCreatorInspection
 import android.os.Parcelable
 
 class <caret>NoImplementation : Parcelable
\ No newline at end of file
diff --git a/idea/testData/android/lintQuickfix/requiresApi/annotation.kt b/idea/testData/android/lintQuickfix/requiresApi/annotation.kt
index dbf09a0..76db9697 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/annotation.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/annotation.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/companion.kt b/idea/testData/android/lintQuickfix/requiresApi/companion.kt
index d332523..68568d4 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/companion.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/companion.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/defaultParameter.kt b/idea/testData/android/lintQuickfix/requiresApi/defaultParameter.kt
index 9f7d6c6..cddbbe5 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/defaultParameter.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/defaultParameter.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/extend.kt b/idea/testData/android/lintQuickfix/requiresApi/extend.kt
index 7b95585..233c746 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/extend.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/extend.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/functionLiteral.kt b/idea/testData/android/lintQuickfix/requiresApi/functionLiteral.kt
index 9b04c508..00575be 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/functionLiteral.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/functionLiteral.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/inlinedConstant.kt b/idea/testData/android/lintQuickfix/requiresApi/inlinedConstant.kt
index ee42d76..d838f2b 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/inlinedConstant.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/inlinedConstant.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(KITKAT) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintInlinedApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 class Test {
diff --git a/idea/testData/android/lintQuickfix/requiresApi/method.kt b/idea/testData/android/lintQuickfix/requiresApi/method.kt
index 79068fc..14ccb78 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/method.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/method.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/property.kt b/idea/testData/android/lintQuickfix/requiresApi/property.kt
index d4c0ae8..fa17b13 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/property.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/property.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/requiresApi/when.kt b/idea/testData/android/lintQuickfix/requiresApi/when.kt
index 67d45b8..71997f7 100644
--- a/idea/testData/android/lintQuickfix/requiresApi/when.kt
+++ b/idea/testData/android/lintQuickfix/requiresApi/when.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @RequiresApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 // DEPENDENCY: RequiresApi.java -> android/support/annotation/RequiresApi.java
 
 import android.graphics.drawable.VectorDrawable
diff --git a/idea/testData/android/lintQuickfix/suppressLint/activityMethod.kt b/idea/testData/android/lintQuickfix/suppressLint/activityMethod.kt
index 34cac7d..7df0f39 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/activityMethod.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/activityMethod.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 import android.app.Activity
 import android.os.Environment
diff --git a/idea/testData/android/lintQuickfix/suppressLint/addToExistingAnnotation.kt b/idea/testData/android/lintQuickfix/suppressLint/addToExistingAnnotation.kt
index a0a917d..ba329c0 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/addToExistingAnnotation.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/addToExistingAnnotation.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 import android.annotation.SuppressLint
 import android.app.Activity
diff --git a/idea/testData/android/lintQuickfix/suppressLint/constructorParameter.kt b/idea/testData/android/lintQuickfix/suppressLint/constructorParameter.kt
index bfed3b9..c9669de 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/constructorParameter.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/constructorParameter.kt
@@ -1,4 +1,4 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 class SdCard(val path: String = "<caret>/sdcard")
\ No newline at end of file
diff --git a/idea/testData/android/lintQuickfix/suppressLint/destructuringDeclaration.kt b/idea/testData/android/lintQuickfix/suppressLint/destructuringDeclaration.kt
index 346336d..0790faf 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/destructuringDeclaration.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/destructuringDeclaration.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 fun foo() {
     val (a: String, b: String) = "<caret>/sdcard"
diff --git a/idea/testData/android/lintQuickfix/suppressLint/lambdaArgument.kt b/idea/testData/android/lintQuickfix/suppressLint/lambdaArgument.kt
index 08556f1..3e28560 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/lambdaArgument.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/lambdaArgument.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 fun foo(l: Any) = l
 
diff --git a/idea/testData/android/lintQuickfix/suppressLint/lambdaArgumentProperty.kt b/idea/testData/android/lintQuickfix/suppressLint/lambdaArgumentProperty.kt
index 233767c..4e880f5 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/lambdaArgumentProperty.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/lambdaArgumentProperty.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 fun foo(l: Any) = l
 
diff --git a/idea/testData/android/lintQuickfix/suppressLint/methodParameter.kt b/idea/testData/android/lintQuickfix/suppressLint/methodParameter.kt
index 854638e..f9bc321 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/methodParameter.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/methodParameter.kt
@@ -1,4 +1,4 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 fun foo(path: String = "<caret>/sdcard") = path
\ No newline at end of file
diff --git a/idea/testData/android/lintQuickfix/suppressLint/propertyWithLambda.kt b/idea/testData/android/lintQuickfix/suppressLint/propertyWithLambda.kt
index 8afada5..529015f 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/propertyWithLambda.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/propertyWithLambda.kt
@@ -1,4 +1,4 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 val getPath = { "<caret>/sdcard" }
\ No newline at end of file
diff --git a/idea/testData/android/lintQuickfix/suppressLint/simpleProperty.kt b/idea/testData/android/lintQuickfix/suppressLint/simpleProperty.kt
index c4fee12..a9ff8da 100644
--- a/idea/testData/android/lintQuickfix/suppressLint/simpleProperty.kt
+++ b/idea/testData/android/lintQuickfix/suppressLint/simpleProperty.kt
@@ -1,4 +1,4 @@
 // INTENTION_TEXT: Suppress: Add @SuppressLint("SdCardPath") annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSdCardPathInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintSdCardPathInspection
 
 val path = "<caret>/sdcard"
\ No newline at end of file
diff --git a/idea/testData/android/lintQuickfix/targetApi/annotation.kt b/idea/testData/android/lintQuickfix/targetApi/annotation.kt
index f9f0553..ceceadd 100644
--- a/idea/testData/android/lintQuickfix/targetApi/annotation.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/annotation.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 import kotlin.reflect.KClass
diff --git a/idea/testData/android/lintQuickfix/targetApi/companion.kt b/idea/testData/android/lintQuickfix/targetApi/companion.kt
index a35ae52..6ecbaca 100644
--- a/idea/testData/android/lintQuickfix/targetApi/companion.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/companion.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/defaultParameter.kt b/idea/testData/android/lintQuickfix/targetApi/defaultParameter.kt
index 8cff109..673405e 100644
--- a/idea/testData/android/lintQuickfix/targetApi/defaultParameter.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/defaultParameter.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/extend.kt b/idea/testData/android/lintQuickfix/targetApi/extend.kt
index b47ea57..0c26fe2 100644
--- a/idea/testData/android/lintQuickfix/targetApi/extend.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/extend.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/functionLiteral.kt b/idea/testData/android/lintQuickfix/targetApi/functionLiteral.kt
index ea1b9c2..a4c3c411 100644
--- a/idea/testData/android/lintQuickfix/targetApi/functionLiteral.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/functionLiteral.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/inlinedConstant.kt b/idea/testData/android/lintQuickfix/targetApi/inlinedConstant.kt
index ed8cd3c3..45fb5d2 100644
--- a/idea/testData/android/lintQuickfix/targetApi/inlinedConstant.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/inlinedConstant.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(KITKAT) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintInlinedApiInspection
 
 class Test {
     fun foo(): Int {
diff --git a/idea/testData/android/lintQuickfix/targetApi/method.kt b/idea/testData/android/lintQuickfix/targetApi/method.kt
index 4df86f6..aeac2f9 100644
--- a/idea/testData/android/lintQuickfix/targetApi/method.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/method.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/property.kt b/idea/testData/android/lintQuickfix/targetApi/property.kt
index 0cc187c..7418db2 100644
--- a/idea/testData/android/lintQuickfix/targetApi/property.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/property.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetApi/when.kt b/idea/testData/android/lintQuickfix/targetApi/when.kt
index 27a5919..df92ce5 100644
--- a/idea/testData/android/lintQuickfix/targetApi/when.kt
+++ b/idea/testData/android/lintQuickfix/targetApi/when.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Add @TargetApi(LOLLIPOP) Annotation
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/annotation.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/annotation.kt
index e052b68..31fed00 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/annotation.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/annotation.kt
@@ -1,6 +1,6 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
 // INTENTION_NOT_AVAILABLE
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 import kotlin.reflect.KClass
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/defaultParameter.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/defaultParameter.kt
index 97f5da2..f448c22 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/defaultParameter.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/defaultParameter.kt
@@ -1,6 +1,6 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
 // INTENTION_NOT_AVAILABLE
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt
index 16ee93f..dd8fe5b 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/functionLiteral.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/functionLiteral.kt
index 915c5c6..17633e8 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/functionLiteral.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/functionLiteral.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/if.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/if.kt
index e2f81f2..4087654 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/if.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/if.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/ifWithBlock.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/ifWithBlock.kt
index c74f3ee..0e6ba0f 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/ifWithBlock.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/ifWithBlock.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/inlinedConstant.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/inlinedConstant.kt
index febb06d..64281cd 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/inlinedConstant.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/inlinedConstant.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintInlinedApiInspection
 
 class Test {
     fun foo(): Int {
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/method.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/method.kt
index a1bbff2..f0ad689 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/method.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/method.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/idea/testData/android/lintQuickfix/targetVersionCheck/when.kt b/idea/testData/android/lintQuickfix/targetVersionCheck/when.kt
index 11474ac..5a00d18 100644
--- a/idea/testData/android/lintQuickfix/targetVersionCheck/when.kt
+++ b/idea/testData/android/lintQuickfix/targetVersionCheck/when.kt
@@ -1,5 +1,5 @@
 // INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
-// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
+// INSPECTION_CLASS: org.jetbrains.android.inspections.lint.AndroidLintInspectionToolProvider$AndroidLintNewApiInspection
 
 import android.graphics.drawable.VectorDrawable
 
diff --git a/plugins/lint/android-annotations/android-annotations.iml b/plugins/lint/android-annotations/android-annotations.iml
deleted file mode 100644
index c90834f..0000000
--- a/plugins/lint/android-annotations/android-annotations.iml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/NonNull.java b/plugins/lint/android-annotations/src/com/android/annotations/NonNull.java
deleted file mode 100644
index d16451b..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/NonNull.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-
-/**
- * Denotes that a parameter, field or method return value can never be null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target({METHOD,PARAMETER,LOCAL_VARIABLE,FIELD})
-public @interface NonNull {
-}
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/NonNullByDefault.java b/plugins/lint/android-annotations/src/com/android/annotations/NonNullByDefault.java
deleted file mode 100644
index 9ce54d8..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/NonNullByDefault.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-/**
- * Denotes that all parameters, fields or methods within a class or method by
- * default can not be null. This can be overridden by adding specific
- * {@link com.android.annotations.Nullable} annotations on fields, parameters or
- * methods that should not use the default.
- * <p/>
- * NOTE: Eclipse does not yet handle defaults well (in particular, if
- * you add this on a class which implements Comparable, then it will insist
- * that your compare method is changing the nullness of the compare parameter,
- * so you'll need to add @Nullable on it, which also is not right (since
- * the method should have implied @NonNull and you do not need to check
- * the parameter.). For now, it's best to individually annotate methods,
- * parameters and fields.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target({PACKAGE, TYPE})
-public @interface NonNullByDefault {
-}
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/Nullable.java b/plugins/lint/android-annotations/src/com/android/annotations/Nullable.java
deleted file mode 100755
index a0377cb..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/Nullable.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-
-/**
- * Denotes that a parameter, field or method return value can be null.
- * <b>Note</b>: this is the default assumption for most Java APIs and the
- * default assumption made by most static code checking tools, so usually you
- * don't need to use this annotation; its primary use is to override a default
- * wider annotation like {@link NonNullByDefault}.
- * <p/>
- * When decorating a method call parameter, this denotes the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically
- * used on optional parameters.
- * <p/>
- * When decorating a method, this denotes the method might legitimately return
- * null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target({METHOD, PARAMETER, LOCAL_VARIABLE, FIELD})
-public @interface Nullable {
-}
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/VisibleForTesting.java b/plugins/lint/android-annotations/src/com/android/annotations/VisibleForTesting.java
deleted file mode 100755
index 7f41d70..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/concurrency/GuardedBy.java b/plugins/lint/android-annotations/src/com/android/annotations/concurrency/GuardedBy.java
deleted file mode 100644
index 5a151ac..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/concurrency/GuardedBy.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotations.concurrency;
-
-import java.lang.annotation.*;
-
-/**
- * Indicates that the target field or method should only be accessed
- * with the specified lock being held.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD, ElementType.FIELD})
-public @interface GuardedBy {
-    String value();
-}
diff --git a/plugins/lint/android-annotations/src/com/android/annotations/concurrency/Immutable.java b/plugins/lint/android-annotations/src/com/android/annotations/concurrency/Immutable.java
deleted file mode 100644
index c83f9f0..0000000
--- a/plugins/lint/android-annotations/src/com/android/annotations/concurrency/Immutable.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotations.concurrency;
-
-import java.lang.annotation.*;
-
-/**
- * Indicates that the target class to which this annotation is applied
- * is immutable.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target(ElementType.TYPE)
-public @interface Immutable {
-}
diff --git a/plugins/lint/lint-api/lint-api.iml b/plugins/lint/lint-api/lint-api.iml
deleted file mode 100644
index e654110..0000000
--- a/plugins/lint/lint-api/lint-api.iml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="guava" level="project" />
-    <orderEntry type="library" name="android-plugin" level="project" />
-    <orderEntry type="library" name="intellij-core" level="project" />
-    <orderEntry type="module" module-name="android-annotations" />
-    <orderEntry type="library" name="kotlin-runtime" level="project" />
-    <orderEntry type="library" name="uast-android-studio" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AndroidReference.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AndroidReference.java
deleted file mode 100644
index db26881..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AndroidReference.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-
-import com.android.annotations.NonNull;
-import com.android.resources.ResourceType;
-
-import org.jetbrains.uast.UExpression;
-
-public class AndroidReference {
-    public final UExpression node;
-
-    private final String rPackage;
-
-    private final ResourceType type;
-
-    private final String name;
-
-    // getPackage() can be empty if not a package-qualified import (e.g. android.R.id.name).
-    @NonNull
-    public String getPackage() {
-        return rPackage;
-    }
-
-    @NonNull
-    public ResourceType getType() {
-        return type;
-    }
-
-    @NonNull
-    public String getName() {
-        return name;
-    }
-
-    boolean isFramework() {
-        return rPackage.equals(ANDROID_PKG);
-    }
-
-    public AndroidReference(
-            UExpression node,
-            String rPackage,
-            ResourceType type,
-            String name) {
-        this.node = node;
-        this.rPackage = rPackage;
-        this.type = type;
-        this.name = name;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AsmVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AsmVisitor.java
deleted file mode 100644
index 9c8c861..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/AsmVisitor.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.ClassScanner;
-import com.google.common.annotations.Beta;
-
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.InsnList;
-import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Specialized visitor for running detectors on a class object model.
- * <p>
- * It operates in two phases:
- * <ol>
- *   <li> First, it computes a set of maps where it generates a map from each
- *        significant method name to a list of detectors to consult for that method
- *        name. The set of method names that a detector is interested in is provided
- *        by the detectors themselves.
- *   <li> Second, it iterates over the DOM a single time. For each method call it finds,
- *        it dispatches to any check that has registered interest in that method name.
- *   <li> Finally, it runs a full check on those class scanners that do not register
- *        specific method names to be checked. This is intended for those detectors
- *        that do custom work, not related specifically to method calls.
- * </ol>
- * It also notifies all the detectors before and after the document is processed
- * such that they can do pre- and post-processing.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-class AsmVisitor {
-    /**
-     * Number of distinct node types specified in {@link AbstractInsnNode}. Sadly
-     * there isn't a max-constant there, so update this along with ASM library
-     * updates.
-     */
-    private static final int TYPE_COUNT = AbstractInsnNode.LINE + 1;
-    private final Map<String, List<ClassScanner>> mMethodNameToChecks =
-            new HashMap<String, List<ClassScanner>>();
-    private final Map<String, List<ClassScanner>> mMethodOwnerToChecks =
-            new HashMap<String, List<ClassScanner>>();
-    private final List<Detector> mFullClassChecks = new ArrayList<Detector>();
-
-    private final List<? extends Detector> mAllDetectors;
-    private List<ClassScanner>[] mNodeTypeDetectors;
-
-    // Really want this:
-    //<T extends List<Detector> & Detector.ClassScanner> ClassVisitor(T xmlDetectors) {
-    // but it makes client code tricky and ugly.
-    @SuppressWarnings("unchecked")
-    AsmVisitor(@NonNull LintClient client, @NonNull List<? extends Detector> classDetectors) {
-        mAllDetectors = classDetectors;
-
-        // TODO: Check appliesTo() for files, and find a quick way to enable/disable
-        // rules when running through a full project!
-        for (Detector detector : classDetectors) {
-            Detector.ClassScanner scanner = (Detector.ClassScanner) detector;
-
-            boolean checkFullClass = true;
-
-            Collection<String> names = scanner.getApplicableCallNames();
-            if (names != null) {
-                checkFullClass = false;
-                for (String element : names) {
-                    List<Detector.ClassScanner> list = mMethodNameToChecks.get(element);
-                    if (list == null) {
-                        list = new ArrayList<Detector.ClassScanner>();
-                        mMethodNameToChecks.put(element, list);
-                    }
-                    list.add(scanner);
-                }
-            }
-
-            Collection<String> owners = scanner.getApplicableCallOwners();
-            if (owners != null) {
-                checkFullClass = false;
-                for (String element : owners) {
-                    List<Detector.ClassScanner> list = mMethodOwnerToChecks.get(element);
-                    if (list == null) {
-                        list = new ArrayList<Detector.ClassScanner>();
-                        mMethodOwnerToChecks.put(element, list);
-                    }
-                    list.add(scanner);
-                }
-            }
-
-            int[] types = scanner.getApplicableAsmNodeTypes();
-            if (types != null) {
-                checkFullClass = false;
-                for (int type : types) {
-                    if (type < 0 || type >= TYPE_COUNT) {
-                        // Can't support this node type: looks like ASM wasn't updated correctly.
-                        client.log(null, "Out of range node type %1$d from detector %2$s",
-                                type, scanner);
-                        continue;
-                    }
-                    if (mNodeTypeDetectors == null) {
-                        mNodeTypeDetectors = new List[TYPE_COUNT];
-                    }
-                    List<ClassScanner> checks = mNodeTypeDetectors[type];
-                    if (checks == null) {
-                        checks = new ArrayList<ClassScanner>();
-                        mNodeTypeDetectors[type] = checks;
-                    }
-                    checks.add(scanner);
-                }
-            }
-
-            if (checkFullClass) {
-                mFullClassChecks.add(detector);
-            }
-        }
-    }
-
-    @SuppressWarnings("rawtypes") // ASM API uses raw types
-    void runClassDetectors(ClassContext context) {
-        ClassNode classNode = context.getClassNode();
-
-        for (Detector detector : mAllDetectors) {
-            detector.beforeCheckFile(context);
-        }
-
-        for (Detector detector : mFullClassChecks) {
-            Detector.ClassScanner scanner = (Detector.ClassScanner) detector;
-            scanner.checkClass(context, classNode);
-            detector.afterCheckFile(context);
-        }
-
-        if (!mMethodNameToChecks.isEmpty() || !mMethodOwnerToChecks.isEmpty() ||
-                mNodeTypeDetectors != null && mNodeTypeDetectors.length > 0) {
-            List methodList = classNode.methods;
-            for (Object m : methodList) {
-                MethodNode method = (MethodNode) m;
-                InsnList nodes = method.instructions;
-                for (int i = 0, n = nodes.size(); i < n; i++) {
-                    AbstractInsnNode instruction = nodes.get(i);
-                    int type = instruction.getType();
-                    if (type == AbstractInsnNode.METHOD_INSN) {
-                        MethodInsnNode call = (MethodInsnNode) instruction;
-
-                        String owner = call.owner;
-                        List<ClassScanner> scanners = mMethodOwnerToChecks.get(owner);
-                        if (scanners != null) {
-                            for (ClassScanner scanner : scanners) {
-                                scanner.checkCall(context, classNode, method, call);
-                            }
-                        }
-
-                        String name = call.name;
-                        scanners = mMethodNameToChecks.get(name);
-                        if (scanners != null) {
-                            for (ClassScanner scanner : scanners) {
-                                scanner.checkCall(context, classNode, method, call);
-                            }
-                        }
-                    }
-
-                    if (mNodeTypeDetectors != null && type < mNodeTypeDetectors.length) {
-                        List<ClassScanner> scanners = mNodeTypeDetectors[type];
-                        if (scanners != null) {
-                            for (ClassScanner scanner : scanners) {
-                                scanner.checkInstruction(context, classNode, method, instruction);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        for (Detector detector : mAllDetectors) {
-            detector.afterCheckFile(context);
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CircularDependencyException.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CircularDependencyException.java
deleted file mode 100644
index 94020e0..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CircularDependencyException.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.google.common.annotations.Beta;
-
-/**
- * Exception thrown when there is a circular dependency, such as a circular dependency
- * of library mProject references
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class CircularDependencyException extends RuntimeException {
-    @Nullable
-    private Project mProject;
-
-    @Nullable
-    private Location mLocation;
-
-    CircularDependencyException(@NonNull String message) {
-        super(message);
-    }
-
-    /**
-     * Returns the associated project, if any
-     *
-     * @return the associated project, if any
-     */
-    @Nullable
-    public Project getProject() {
-        return mProject;
-    }
-
-    /**
-     * Sets the associated project, if any
-     *
-     * @param project the associated project, if any
-     */
-    public void setProject(@Nullable Project project) {
-        mProject = project;
-    }
-
-    /**
-     * Returns the associated location, if any
-     *
-     * @return the associated location, if any
-     */
-    @Nullable
-    public Location getLocation() {
-        return mLocation;
-    }
-
-    /**
-     * Sets the associated location, if any
-     *
-     * @param location the associated location, if any
-     */
-    public void setLocation(@Nullable Location location) {
-        mLocation = location;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ClassEntry.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ClassEntry.java
deleted file mode 100644
index 88fb792..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ClassEntry.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.client.api;
-
-import static com.android.SdkConstants.DOT_CLASS;
-import static com.android.SdkConstants.DOT_JAR;
-import static org.jetbrains.org.objectweb.asm.Opcodes.ASM5;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.Closeables;
-
-import org.jetbrains.org.objectweb.asm.ClassReader;
-import org.jetbrains.org.objectweb.asm.ClassVisitor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/** A class, present either as a .class file on disk, or inside a .jar file. */
-@VisibleForTesting
-class ClassEntry implements Comparable<ClassEntry> {
-    public final File file;
-    public final File jarFile;
-    public final File binDir;
-    public final byte[] bytes;
-
-    @VisibleForTesting
-    ClassEntry(
-            @NonNull File file,
-            @Nullable File jarFile,
-            @NonNull File binDir,
-            @NonNull byte[] bytes) {
-        super();
-        this.file = file;
-        this.jarFile = jarFile;
-        this.binDir = binDir;
-        this.bytes = bytes;
-    }
-
-    @NonNull
-    public String path() {
-        if (jarFile != null) {
-            return jarFile.getPath() + ':' + file.getPath();
-        } else {
-            return file.getPath();
-        }
-    }
-
-    @Override
-    public int compareTo(@NonNull ClassEntry other) {
-        String p1 = file.getPath();
-        String p2 = other.file.getPath();
-        int m1 = p1.length();
-        int m2 = p2.length();
-        if (m1 == m2 && p1.equals(p2)) {
-            return 0;
-        }
-        int m = Math.min(m1, m2);
-
-        for (int i = 0; i < m; i++) {
-            char c1 = p1.charAt(i);
-            char c2 = p2.charAt(i);
-            if (c1 != c2) {
-                // Sort Foo$Bar.class *after* Foo.class, even though $ < .
-                if (c1 == '.' && c2 == '$') {
-                    return -1;
-                }
-                if (c1 == '$' && c2 == '.') {
-                    return 1;
-                }
-                return c1 - c2;
-            }
-        }
-
-        return (m == m1) ? -1 : 1;
-    }
-
-    @Override
-    public String toString() {
-        return file.getPath();
-    }
-
-    /**
-     * Creates a list of class entries from the given class path.
-     *
-     * @param client the client to report errors to and to use to read files
-     * @param classPath the class path (directories and jar files) to scan
-     * @param sort if true, sort the results
-     * @return the list of class entries, never null.
-     */
-    @NonNull
-    public static List<ClassEntry> fromClassPath(
-            @NonNull LintClient client,
-            @NonNull List<File> classPath,
-            boolean sort) {
-        if (!classPath.isEmpty()) {
-            List<ClassEntry> libraryEntries = new ArrayList<ClassEntry>(64);
-            addEntries(client, libraryEntries, classPath);
-            if (sort) {
-                Collections.sort(libraryEntries);
-            }
-            return libraryEntries;
-        } else {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * Creates a list of class entries from the given class path and specific set of
-     * files within it.
-     *
-     * @param client the client to report errors to and to use to read files
-     * @param classFiles the specific set of class files to look for
-     * @param classFolders the list of class folders to look in (to determine the
-     *                     package root)
-     * @param sort if true, sort the results
-     * @return the list of class entries, never null.
-     */
-    @NonNull
-    public static List<ClassEntry> fromClassFiles(
-            @NonNull LintClient client,
-            @NonNull List<File> classFiles, @NonNull List<File> classFolders,
-            boolean sort) {
-        List<ClassEntry> entries = new ArrayList<ClassEntry>(classFiles.size());
-
-        if (!classFolders.isEmpty()) {
-            for (File file : classFiles) {
-                String path = file.getPath();
-                if (file.isFile() && path.endsWith(DOT_CLASS)) {
-                    try {
-                        byte[] bytes = client.readBytes(file);
-                        for (File dir : classFolders) {
-                            if (path.startsWith(dir.getPath())) {
-                                entries.add(new ClassEntry(file, null /* jarFile*/, dir,
-                                        bytes));
-                                break;
-                            }
-                        }
-                    } catch (IOException e) {
-                        client.log(e, null);
-                    }
-                }
-            }
-
-            if (sort && !entries.isEmpty()) {
-                Collections.sort(entries);
-            }
-        }
-
-        return entries;
-    }
-
-    /**
-     * Given a classpath, add all the class files found within the directories and inside jar files
-     */
-    private static void addEntries(
-            @NonNull LintClient client,
-            @NonNull List<ClassEntry> entries,
-            @NonNull List<File> classPath) {
-        for (File classPathEntry : classPath) {
-            if (classPathEntry.getName().endsWith(DOT_JAR)) {
-                //noinspection UnnecessaryLocalVariable
-                File jarFile = classPathEntry;
-                if (!jarFile.exists()) {
-                    continue;
-                }
-                ZipInputStream zis = null;
-                try {
-                    FileInputStream fis = new FileInputStream(jarFile);
-                    try {
-                        zis = new ZipInputStream(fis);
-                        ZipEntry entry = zis.getNextEntry();
-                        while (entry != null) {
-                            String name = entry.getName();
-                            if (name.endsWith(DOT_CLASS)) {
-                                try {
-                                    byte[] bytes = ByteStreams.toByteArray(zis);
-                                    if (bytes != null) {
-                                        File file = new File(entry.getName());
-                                        entries.add(new ClassEntry(file, jarFile, jarFile, bytes));
-                                    }
-                                } catch (Exception e) {
-                                    client.log(e, null);
-                                    continue;
-                                }
-                            }
-
-                            entry = zis.getNextEntry();
-                        }
-                    } finally {
-                        Closeables.close(fis, true);
-                    }
-                } catch (IOException e) {
-                    client.log(e, "Could not read jar file contents from %1$s", jarFile);
-                } finally {
-                    try {
-                        Closeables.close(zis, true);
-                    } catch (IOException e) {
-                        // cannot happen
-                    }
-                }
-            } else if (classPathEntry.isDirectory()) {
-                //noinspection UnnecessaryLocalVariable
-                File binDir = classPathEntry;
-                List<File> classFiles = new ArrayList<File>();
-                addClassFiles(binDir, classFiles);
-
-                for (File file : classFiles) {
-                    try {
-                        byte[] bytes = client.readBytes(file);
-                        entries.add(new ClassEntry(file, null /* jarFile*/, binDir, bytes));
-                    } catch (IOException e) {
-                        client.log(e, null);
-                    }
-                }
-            } else {
-                client.log(null, "Ignoring class path entry %1$s", classPathEntry);
-            }
-        }
-    }
-
-    /** Adds in all the .class files found recursively in the given directory */
-    private static void addClassFiles(@NonNull File dir, @NonNull List<File> classFiles) {
-        // Process the resource folder
-        File[] files = dir.listFiles();
-        if (files != null && files.length > 0) {
-            for (File file : files) {
-                if (file.isFile() && file.getName().endsWith(DOT_CLASS)) {
-                    classFiles.add(file);
-                } else if (file.isDirectory()) {
-                    // Recurse
-                    addClassFiles(file, classFiles);
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a super class map (from class to its super class) for the given set of entries
-     *
-     * @param client the client to report errors to and to use to access files
-     * @param libraryEntries the set of library entries to consult
-     * @param classEntries the set of class entries to consult
-     * @return a map from name to super class internal names
-     */
-    @NonNull
-    public static Map<String, String> createSuperClassMap(
-            @NonNull LintClient client,
-            @NonNull List<ClassEntry> libraryEntries,
-            @NonNull List<ClassEntry> classEntries) {
-        int size = libraryEntries.size() + classEntries.size();
-        Map<String, String> map = Maps.newHashMapWithExpectedSize(size);
-        SuperclassVisitor visitor = new SuperclassVisitor(map);
-        addSuperClasses(client, visitor, libraryEntries);
-        addSuperClasses(client, visitor, classEntries);
-        return map;
-    }
-
-    /**
-     * Creates a super class map (from class to its super class) for the given set of entries
-     *
-     * @param client the client to report errors to and to use to access files
-     * @param entries the set of library entries to consult
-     * @return a map from name to super class internal names
-     */
-    @NonNull
-    public static Map<String, String> createSuperClassMap(
-            @NonNull LintClient client,
-            @NonNull List<ClassEntry> entries) {
-        Map<String, String> map = Maps.newHashMapWithExpectedSize(entries.size());
-        SuperclassVisitor visitor = new SuperclassVisitor(map);
-        addSuperClasses(client, visitor, entries);
-        return map;
-    }
-
-    /** Adds in all the super classes found for the given class entries into the given map */
-    private static void addSuperClasses(
-            @NonNull LintClient client,
-            @NonNull SuperclassVisitor visitor,
-            @NonNull List<ClassEntry> entries) {
-        for (ClassEntry entry : entries) {
-            try {
-                ClassReader reader = new ClassReader(entry.bytes);
-                int flags = ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG
-                        | ClassReader.SKIP_FRAMES;
-                reader.accept(visitor, flags);
-            } catch (Throwable t) {
-                client.log(null, "Error processing %1$s: broken class file?", entry.path());
-            }
-        }
-    }
-
-    /** Visitor skimming classes and initializing a map of super classes */
-    private static class SuperclassVisitor extends ClassVisitor {
-        private final Map<String, String> mMap;
-
-        public SuperclassVisitor(Map<String, String> map) {
-            super(ASM5);
-            mMap = map;
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            // Record super class in the map (but don't waste space on java.lang.Object)
-            if (superName != null && !"java/lang/Object".equals(superName)) {
-                mMap.put(name, superName);
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CompositeIssueRegistry.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CompositeIssueRegistry.java
deleted file mode 100644
index b66a841..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/CompositeIssueRegistry.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.tools.klint.detector.api.Issue;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-/**
- * Registry which merges many issue registries into one, and presents a unified list
- * of issues.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-class CompositeIssueRegistry extends IssueRegistry {
-    private final List<IssueRegistry> myRegistries;
-    private List<Issue> myIssues;
-
-    public CompositeIssueRegistry(@NonNull List<IssueRegistry> registries) {
-        myRegistries = registries;
-    }
-
-    @NonNull
-    @Override
-    public List<Issue> getIssues() {
-        if (myIssues == null) {
-            List<Issue> issues = Lists.newArrayListWithExpectedSize(200);
-            for (IssueRegistry registry : myRegistries) {
-                issues.addAll(registry.getIssues());
-            }
-            myIssues = issues;
-        }
-
-        return myIssues;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/Configuration.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/Configuration.java
deleted file mode 100644
index 5952b10..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/Configuration.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.annotations.Beta;
-
-/**
- * Lint configuration for an Android project such as which specific rules to include,
- * which specific rules to exclude, and which specific errors to ignore.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class Configuration {
-    /**
-     * Checks whether this issue should be ignored because the user has already
-     * suppressed the error? Note that this refers to individual issues being
-     * suppressed/ignored, not a whole detector being disabled via something
-     * like {@link #isEnabled(Issue)}.
-     *
-     * @param context the context used by the detector when the issue was found
-     * @param issue the issue that was found
-     * @param location the location of the issue
-     * @param message the associated user message
-     * @return true if this issue should be suppressed
-     */
-    public boolean isIgnored(
-            @NonNull Context context,
-            @NonNull Issue issue,
-            @Nullable Location location,
-            @NonNull String message) {
-        return false;
-    }
-
-    /**
-     * Returns false if the given issue has been disabled. This is just
-     * a convenience method for {@code getSeverity(issue) != Severity.IGNORE}.
-     *
-     * @param issue the issue to check
-     * @return false if the issue has been disabled
-     */
-    public boolean isEnabled(@NonNull Issue issue) {
-        return getSeverity(issue) != Severity.IGNORE;
-    }
-
-    /**
-     * Returns the severity for a given issue. This is the same as the
-     * {@link Issue#getDefaultSeverity()} unless the user has selected a custom
-     * severity (which is tool context dependent).
-     *
-     * @param issue the issue to look up the severity from
-     * @return the severity use for issues for the given detector
-     */
-    public Severity getSeverity(@NonNull Issue issue) {
-        return issue.getDefaultSeverity();
-    }
-
-    // Editing configurations
-
-    /**
-     * Marks the given warning as "ignored".
-     *
-     * @param context The scanning context
-     * @param issue the issue to be ignored
-     * @param location The location to ignore the warning at, if any
-     * @param message The message for the warning
-     */
-    public abstract void ignore(
-            @NonNull Context context,
-            @NonNull Issue issue,
-            @Nullable Location location,
-            @NonNull String message);
-
-    /**
-     * Sets the severity to be used for this issue.
-     *
-     * @param issue the issue to set the severity for
-     * @param severity the severity to associate with this issue, or null to
-     *            reset the severity to the default
-     */
-    public abstract void setSeverity(@NonNull Issue issue, @Nullable Severity severity);
-
-    // Bulk editing support
-
-    /**
-     * Marks the beginning of a "bulk" editing operation with repeated calls to
-     * {@link #setSeverity} or {@link #ignore}. After all the values have been
-     * set, the client <b>must</b> call {@link #finishBulkEditing()}. This
-     * allows configurations to avoid doing expensive I/O (such as writing out a
-     * config XML file) for each and every editing operation when they are
-     * applied in bulk, such as from a configuration dialog's "Apply" action.
-     */
-    public void startBulkEditing() {
-    }
-
-    /**
-     * Marks the end of a "bulk" editing operation, where values should be
-     * committed to persistent storage. See {@link #startBulkEditing()} for
-     * details.
-     */
-    public void finishBulkEditing() {
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultConfiguration.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultConfiguration.java
deleted file mode 100644
index eb2d9f0..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultConfiguration.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.CURRENT_PLATFORM;
-import static com.android.SdkConstants.PLATFORM_WINDOWS;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.android.utils.XmlUtils;
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Splitter;
-
-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.SAXParseException;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * Default implementation of a {@link Configuration} which reads and writes
- * configuration data into {@code lint.xml} in the project directory.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class DefaultConfiguration extends Configuration {
-    private final LintClient mClient;
-    /** Default name of the configuration file */
-    public static final String CONFIG_FILE_NAME = "lint.xml"; //$NON-NLS-1$
-
-    // Lint XML File
-    @NonNull
-    private static final String TAG_ISSUE = "issue"; //$NON-NLS-1$
-    @NonNull
-    private static final String ATTR_ID = "id"; //$NON-NLS-1$
-    @NonNull
-    private static final String ATTR_SEVERITY = "severity"; //$NON-NLS-1$
-    @NonNull
-    private static final String ATTR_PATH = "path"; //$NON-NLS-1$
-    @NonNull
-    private static final String ATTR_REGEXP = "regexp"; //$NON-NLS-1$
-    @NonNull
-    private static final String TAG_IGNORE = "ignore"; //$NON-NLS-1$
-    @NonNull
-    private static final String VALUE_ALL = "all"; //$NON-NLS-1$
-
-    private final Configuration mParent;
-    private final Project mProject;
-    private final File mConfigFile;
-    private boolean mBulkEditing;
-
-    /** Map from id to list of project-relative paths for suppressed warnings */
-    private Map<String, List<String>> mSuppressed;
-
-    /** Map from id to regular expressions. */
-    @Nullable
-    private Map<String, List<Pattern>> mRegexps;
-
-    /**
-     * Map from id to custom {@link Severity} override
-     */
-    private Map<String, Severity> mSeverity;
-
-    protected DefaultConfiguration(
-            @NonNull LintClient client,
-            @Nullable Project project,
-            @Nullable Configuration parent,
-            @NonNull File configFile) {
-        mClient = client;
-        mProject = project;
-        mParent = parent;
-        mConfigFile = configFile;
-    }
-
-    protected DefaultConfiguration(
-            @NonNull LintClient client,
-            @NonNull Project project,
-            @Nullable Configuration parent) {
-        this(client, project, parent, new File(project.getDir(), CONFIG_FILE_NAME));
-    }
-
-    /**
-     * Creates a new {@link DefaultConfiguration}
-     *
-     * @param client the client to report errors to etc
-     * @param project the associated project
-     * @param parent the parent/fallback configuration or null
-     * @return a new configuration
-     */
-    @NonNull
-    public static DefaultConfiguration create(
-            @NonNull LintClient client,
-            @NonNull Project project,
-            @Nullable Configuration parent) {
-        return new DefaultConfiguration(client, project, parent);
-    }
-
-    /**
-     * Creates a new {@link DefaultConfiguration} for the given lint config
-     * file, not affiliated with a project. This is used for global
-     * configurations.
-     *
-     * @param client the client to report errors to etc
-     * @param lintFile the lint file containing the configuration
-     * @return a new configuration
-     */
-    @NonNull
-    public static DefaultConfiguration create(@NonNull LintClient client, @NonNull File lintFile) {
-        return new DefaultConfiguration(client, null /*project*/, null /*parent*/, lintFile);
-    }
-
-    @Override
-    public boolean isIgnored(
-            @NonNull Context context,
-            @NonNull Issue issue,
-            @Nullable Location location,
-            @NonNull String message) {
-        ensureInitialized();
-
-        String id = issue.getId();
-        List<String> paths = mSuppressed.get(id);
-        if (paths == null) {
-            paths = mSuppressed.get(VALUE_ALL);
-        }
-        if (paths != null && location != null) {
-            File file = location.getFile();
-            String relativePath = context.getProject().getRelativePath(file);
-            for (String suppressedPath : paths) {
-                if (suppressedPath.equals(relativePath)) {
-                    return true;
-                }
-                // Also allow a prefix
-                if (relativePath.startsWith(suppressedPath)) {
-                    return true;
-                }
-            }
-        }
-
-        if (mRegexps != null) {
-            List<Pattern> regexps = mRegexps.get(id);
-            if (regexps == null) {
-                regexps = mRegexps.get(VALUE_ALL);
-            }
-            if (regexps != null && location != null) {
-                // Check message
-                for (Pattern regexp : regexps) {
-                    Matcher matcher = regexp.matcher(message);
-                    if (matcher.find()) {
-                        return true;
-                    }
-                }
-
-                // Check location
-                File file = location.getFile();
-                String relativePath = context.getProject().getRelativePath(file);
-                boolean checkUnixPath = false;
-                for (Pattern regexp : regexps) {
-                    Matcher matcher = regexp.matcher(relativePath);
-                    if (matcher.find()) {
-                        return true;
-                    } else if (regexp.pattern().indexOf('/') != -1) {
-                        checkUnixPath = true;
-                    }
-                }
-
-                if (checkUnixPath && CURRENT_PLATFORM == PLATFORM_WINDOWS) {
-                    relativePath = relativePath.replace('\\', '/');
-                    for (Pattern regexp : regexps) {
-                        Matcher matcher = regexp.matcher(relativePath);
-                        if (matcher.find()) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-
-        return mParent != null && mParent.isIgnored(context, issue, location, message);
-    }
-
-    @NonNull
-    protected Severity getDefaultSeverity(@NonNull Issue issue) {
-        if (!issue.isEnabledByDefault()) {
-            return Severity.IGNORE;
-        }
-
-        return issue.getDefaultSeverity();
-    }
-
-    @Override
-    @NonNull
-    public Severity getSeverity(@NonNull Issue issue) {
-        ensureInitialized();
-
-        Severity severity = mSeverity.get(issue.getId());
-        if (severity == null) {
-            severity = mSeverity.get(VALUE_ALL);
-        }
-
-        if (severity != null) {
-            return severity;
-        }
-
-        if (mParent != null) {
-            return mParent.getSeverity(issue);
-        }
-
-        return getDefaultSeverity(issue);
-    }
-
-    private void ensureInitialized() {
-        if (mSuppressed == null) {
-            readConfig();
-        }
-    }
-
-    private void formatError(String message, Object... args) {
-        if (args != null && args.length > 0) {
-            message = String.format(message, args);
-        }
-        message = "Failed to parse `lint.xml` configuration file: " + message;
-        LintDriver driver = new LintDriver(new IssueRegistry() {
-            @Override @NonNull public List<Issue> getIssues() {
-                return Collections.emptyList();
-            }
-        }, mClient);
-        mClient.report(new Context(driver, mProject, mProject, mConfigFile),
-                IssueRegistry.LINT_ERROR,
-                mProject.getConfiguration(driver).getSeverity(IssueRegistry.LINT_ERROR),
-                Location.create(mConfigFile), message, TextFormat.RAW);
-    }
-
-    private void readConfig() {
-        mSuppressed = new HashMap<String, List<String>>();
-        mSeverity = new HashMap<String, Severity>();
-
-        if (!mConfigFile.exists()) {
-            return;
-        }
-
-        try {
-            Document document = XmlUtils.parseUtfXmlFile(mConfigFile, false);
-            NodeList issues = document.getElementsByTagName(TAG_ISSUE);
-            Splitter splitter = Splitter.on(',').trimResults().omitEmptyStrings();
-            for (int i = 0, count = issues.getLength(); i < count; i++) {
-                Node node = issues.item(i);
-                Element element = (Element) node;
-                String idList = element.getAttribute(ATTR_ID);
-                if (idList.isEmpty()) {
-                    formatError("Invalid lint config file: Missing required issue id attribute");
-                    continue;
-                }
-                Iterable<String> ids = splitter.split(idList);
-
-                NamedNodeMap attributes = node.getAttributes();
-                for (int j = 0, n = attributes.getLength(); j < n; j++) {
-                    Node attribute = attributes.item(j);
-                    String name = attribute.getNodeName();
-                    String value = attribute.getNodeValue();
-                    if (ATTR_ID.equals(name)) {
-                        // already handled
-                    } else if (ATTR_SEVERITY.equals(name)) {
-                        for (Severity severity : Severity.values()) {
-                            if (value.equalsIgnoreCase(severity.name())) {
-                                for (String id : ids) {
-                                    mSeverity.put(id, severity);
-                                }
-                                break;
-                            }
-                        }
-                    } else {
-                        formatError("Unexpected attribute \"%1$s\"", name);
-                    }
-                }
-
-                // Look up ignored errors
-                NodeList childNodes = element.getChildNodes();
-                if (childNodes.getLength() > 0) {
-                    for (int j = 0, n = childNodes.getLength(); j < n; j++) {
-                        Node child = childNodes.item(j);
-                        if (child.getNodeType() == Node.ELEMENT_NODE) {
-                            Element ignore = (Element) child;
-                            String path = ignore.getAttribute(ATTR_PATH);
-                            if (path.isEmpty()) {
-                                String regexp = ignore.getAttribute(ATTR_REGEXP);
-                                if (regexp.isEmpty()) {
-                                    formatError("Missing required attribute %1$s or %2$s under %3$s",
-                                        ATTR_PATH, ATTR_REGEXP, idList);
-                                } else {
-                                    addRegexp(idList, ids, n, regexp, false);
-                                }
-                            } else {
-                                // Normalize path format to File.separator. Also
-                                // handle the file format containing / or \.
-                                if (File.separatorChar == '/') {
-                                    path = path.replace('\\', '/');
-                                } else {
-                                    path = path.replace('/', File.separatorChar);
-                                }
-
-                                if (path.indexOf('*') != -1) {
-                                    String regexp = globToRegexp(path);
-                                    addRegexp(idList, ids, n, regexp, false);
-                                } else {
-                                    for (String id : ids) {
-                                        List<String> paths = mSuppressed.get(id);
-                                        if (paths == null) {
-                                            paths = new ArrayList<String>(n / 2 + 1);
-                                            mSuppressed.put(id, paths);
-                                        }
-                                        paths.add(path);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (SAXParseException e) {
-            formatError(e.getMessage());
-        } catch (Exception e) {
-            mClient.log(e, null);
-        }
-    }
-
-    @NonNull
-    public static String globToRegexp(@NonNull String glob) {
-        StringBuilder sb = new StringBuilder(glob.length() * 2);
-        int begin = 0;
-        sb.append('^');
-        for (int i = 0, n = glob.length(); i < n; i++) {
-            char c = glob.charAt(i);
-            if (c == '*') {
-                begin = appendQuoted(sb, glob, begin, i) + 1;
-                if (i < n - 1 && glob.charAt(i + 1) == '*') {
-                    i++;
-                    begin++;
-                }
-                sb.append(".*?");
-            } else if (c == '?') {
-                begin = appendQuoted(sb, glob, begin, i) + 1;
-                sb.append(".?");
-            }
-        }
-        appendQuoted(sb, glob, begin, glob.length());
-        sb.append('$');
-        return sb.toString();
-    }
-
-    private static int appendQuoted(StringBuilder sb, String s, int from, int to) {
-        if (to > from) {
-            boolean isSimple = true;
-            for (int i = from; i < to; i++) {
-                char c = s.charAt(i);
-                if (!Character.isLetterOrDigit(c) && c != '/' && c != ' ') {
-                    isSimple = false;
-                    break;
-                }
-            }
-            if (isSimple) {
-                for (int i = from; i < to; i++) {
-                    sb.append(s.charAt(i));
-                }
-                return to;
-            }
-            sb.append(Pattern.quote(s.substring(from, to)));
-        }
-        return to;
-    }
-
-    private void addRegexp(@NonNull String idList, @NonNull Iterable<String> ids, int n,
-            @NonNull String regexp, boolean silent) {
-        try {
-            if (mRegexps == null) {
-                mRegexps = new HashMap<String, List<Pattern>>();
-            }
-            Pattern pattern = Pattern.compile(regexp);
-            for (String id : ids) {
-                List<Pattern> paths = mRegexps.get(id);
-                if (paths == null) {
-                    paths = new ArrayList<Pattern>(n / 2 + 1);
-                    mRegexps.put(id, paths);
-                }
-                paths.add(pattern);
-            }
-        } catch (PatternSyntaxException e) {
-            if (!silent) {
-                formatError("Invalid pattern %1$s under %2$s: %3$s",
-                        regexp, idList, e.getDescription());
-            }
-        }
-    }
-
-    private void writeConfig() {
-        try {
-            // Write the contents to a new file first such that we don't clobber the
-            // existing file if some I/O error occurs.
-            File file = new File(mConfigFile.getParentFile(),
-                    mConfigFile.getName() + ".new"); //$NON-NLS-1$
-
-            Writer writer = new BufferedWriter(new FileWriter(file));
-            writer.write(
-                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +     //$NON-NLS-1$
-                    "<lint>\n");                                         //$NON-NLS-1$
-
-            if (!mSuppressed.isEmpty() || !mSeverity.isEmpty()) {
-                // Process the maps in a stable sorted order such that if the
-                // files are checked into version control with the project,
-                // there are no random diffs just because hashing algorithms
-                // differ:
-                Set<String> idSet = new HashSet<String>();
-                for (String id : mSuppressed.keySet()) {
-                    idSet.add(id);
-                }
-                for (String id : mSeverity.keySet()) {
-                    idSet.add(id);
-                }
-                List<String> ids = new ArrayList<String>(idSet);
-                Collections.sort(ids);
-
-                for (String id : ids) {
-                    writer.write("    <");                               //$NON-NLS-1$
-                    writer.write(TAG_ISSUE);
-                    writeAttribute(writer, ATTR_ID, id);
-                    Severity severity = mSeverity.get(id);
-                    if (severity != null) {
-                        writeAttribute(writer, ATTR_SEVERITY,
-                                severity.name().toLowerCase(Locale.US));
-                    }
-
-                    List<Pattern> regexps = mRegexps != null ? mRegexps.get(id) : null;
-                    List<String> paths = mSuppressed.get(id);
-                    if (paths != null && !paths.isEmpty()
-                            || regexps != null && !regexps.isEmpty()) {
-                        writer.write('>');
-                        writer.write('\n');
-                        // The paths are already kept in sorted order when they are modified
-                        // by ignore(...)
-                        if (paths != null) {
-                            for (String path : paths) {
-                                writer.write("        <");                   //$NON-NLS-1$
-                                writer.write(TAG_IGNORE);
-                                writeAttribute(writer, ATTR_PATH, path.replace('\\', '/'));
-                                writer.write(" />\n");                       //$NON-NLS-1$
-                            }
-                        }
-                        if (regexps != null) {
-                            for (Pattern regexp : regexps) {
-                                writer.write("        <");                   //$NON-NLS-1$
-                                writer.write(TAG_IGNORE);
-                                writeAttribute(writer, ATTR_REGEXP, regexp.pattern());
-                                writer.write(" />\n");                       //$NON-NLS-1$
-                            }
-                        }
-                        writer.write("    </");                          //$NON-NLS-1$
-                        writer.write(TAG_ISSUE);
-                        writer.write('>');
-                        writer.write('\n');
-                    } else {
-                        writer.write(" />\n");                           //$NON-NLS-1$
-                    }
-                }
-            }
-
-            writer.write("</lint>");                                     //$NON-NLS-1$
-            writer.close();
-
-            // Move file into place: move current version to lint.xml~ (removing the old ~ file
-            // if it exists), then move the new version to lint.xml.
-            File oldFile = new File(mConfigFile.getParentFile(),
-                    mConfigFile.getName() + '~'); //$NON-NLS-1$
-            if (oldFile.exists()) {
-                oldFile.delete();
-            }
-            if (mConfigFile.exists()) {
-                mConfigFile.renameTo(oldFile);
-            }
-            boolean ok = file.renameTo(mConfigFile);
-            if (ok && oldFile.exists()) {
-                oldFile.delete();
-            }
-        } catch (Exception e) {
-            mClient.log(e, null);
-        }
-    }
-
-    private static void writeAttribute(
-            @NonNull Writer writer, @NonNull String name, @NonNull String value)
-            throws IOException {
-        writer.write(' ');
-        writer.write(name);
-        writer.write('=');
-        writer.write('"');
-        writer.write(value);
-        writer.write('"');
-    }
-
-    @Override
-    public void ignore(
-            @NonNull Context context,
-            @NonNull Issue issue,
-            @Nullable Location location,
-            @NonNull String message) {
-        // This configuration only supports suppressing warnings on a per-file basis
-        if (location != null) {
-            ignore(issue, location.getFile());
-        }
-    }
-
-    /**
-     * Marks the given issue and file combination as being ignored.
-     *
-     * @param issue the issue to be ignored in the given file
-     * @param file the file to ignore the issue in
-     */
-    public void ignore(@NonNull Issue issue, @NonNull File file) {
-        ensureInitialized();
-
-        String path = mProject != null ? mProject.getRelativePath(file) : file.getPath();
-
-        List<String> paths = mSuppressed.get(issue.getId());
-        if (paths == null) {
-            paths = new ArrayList<String>();
-            mSuppressed.put(issue.getId(), paths);
-        }
-        paths.add(path);
-
-        // Keep paths sorted alphabetically; makes XML output stable
-        Collections.sort(paths);
-
-        if (!mBulkEditing) {
-            writeConfig();
-        }
-    }
-
-    @Override
-    public void setSeverity(@NonNull Issue issue, @Nullable Severity severity) {
-        ensureInitialized();
-
-        String id = issue.getId();
-        if (severity == null) {
-            mSeverity.remove(id);
-        } else {
-            mSeverity.put(id, severity);
-        }
-
-        if (!mBulkEditing) {
-            writeConfig();
-        }
-    }
-
-    @Override
-    public void startBulkEditing() {
-        mBulkEditing = true;
-    }
-
-    @Override
-    public void finishBulkEditing() {
-        mBulkEditing = false;
-        writeConfig();
-    }
-
-    @VisibleForTesting
-    File getConfigFile() {
-        return mConfigFile;
-    }
-}
\ No newline at end of file
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultSdkInfo.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultSdkInfo.java
deleted file mode 100644
index cc7b157..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/DefaultSdkInfo.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.ABSOLUTE_LAYOUT;
-import static com.android.SdkConstants.ABS_LIST_VIEW;
-import static com.android.SdkConstants.ABS_SEEK_BAR;
-import static com.android.SdkConstants.ABS_SPINNER;
-import static com.android.SdkConstants.ADAPTER_VIEW;
-import static com.android.SdkConstants.AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.BUTTON;
-import static com.android.SdkConstants.CHECKABLE;
-import static com.android.SdkConstants.CHECKED_TEXT_VIEW;
-import static com.android.SdkConstants.CHECK_BOX;
-import static com.android.SdkConstants.COMPOUND_BUTTON;
-import static com.android.SdkConstants.EDIT_TEXT;
-import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
-import static com.android.SdkConstants.FRAME_LAYOUT;
-import static com.android.SdkConstants.GALLERY;
-import static com.android.SdkConstants.GRID_VIEW;
-import static com.android.SdkConstants.HORIZONTAL_SCROLL_VIEW;
-import static com.android.SdkConstants.IMAGE_BUTTON;
-import static com.android.SdkConstants.IMAGE_VIEW;
-import static com.android.SdkConstants.LINEAR_LAYOUT;
-import static com.android.SdkConstants.LIST_VIEW;
-import static com.android.SdkConstants.MULTI_AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.PROGRESS_BAR;
-import static com.android.SdkConstants.RADIO_BUTTON;
-import static com.android.SdkConstants.RADIO_GROUP;
-import static com.android.SdkConstants.RELATIVE_LAYOUT;
-import static com.android.SdkConstants.SCROLL_VIEW;
-import static com.android.SdkConstants.SEEK_BAR;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.SURFACE_VIEW;
-import static com.android.SdkConstants.SWITCH;
-import static com.android.SdkConstants.TABLE_LAYOUT;
-import static com.android.SdkConstants.TABLE_ROW;
-import static com.android.SdkConstants.TAB_HOST;
-import static com.android.SdkConstants.TAB_WIDGET;
-import static com.android.SdkConstants.TEXT_VIEW;
-import static com.android.SdkConstants.TOGGLE_BUTTON;
-import static com.android.SdkConstants.VIEW;
-import static com.android.SdkConstants.VIEW_ANIMATOR;
-import static com.android.SdkConstants.VIEW_GROUP;
-import static com.android.SdkConstants.VIEW_PKG_PREFIX;
-import static com.android.SdkConstants.VIEW_STUB;
-import static com.android.SdkConstants.VIEW_SWITCHER;
-import static com.android.SdkConstants.WEB_VIEW;
-import static com.android.SdkConstants.WIDGET_PKG_PREFIX;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.annotations.Beta;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Default simple implementation of an {@link SdkInfo}
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-class DefaultSdkInfo extends SdkInfo {
-    @Override
-    @Nullable
-    public String getParentViewName(@NonNull String name) {
-        name = getRawType(name);
-
-        return PARENTS.get(name);
-    }
-
-    @Override
-    @Nullable
-    public String getParentViewClass(@NonNull String fqcn) {
-        int index = fqcn.lastIndexOf('.');
-        if (index != -1) {
-            fqcn = fqcn.substring(index + 1);
-        }
-
-        String parent = PARENTS.get(fqcn);
-        if (parent == null) {
-            return null;
-        }
-        // The map only stores class names internally; correct for full package paths
-        if (parent.equals(VIEW) || parent.equals(VIEW_GROUP) || parent.equals(SURFACE_VIEW)) {
-            return VIEW_PKG_PREFIX + parent;
-        } else {
-            return WIDGET_PKG_PREFIX + parent;
-        }
-    }
-
-    @Override
-    public boolean isSubViewOf(@NonNull String parentType, @NonNull String childType) {
-        String parent = getRawType(parentType);
-        String child = getRawType(childType);
-
-        // Do analysis just on non-fqcn paths
-        if (parent.indexOf('.') != -1) {
-            parent = parent.substring(parent.lastIndexOf('.') + 1);
-        }
-        if (child.indexOf('.') != -1) {
-            child = child.substring(child.lastIndexOf('.') + 1);
-        }
-
-        if (parent.equals(VIEW)) {
-            return true;
-        }
-
-        while (!child.equals(VIEW)) {
-            if (parent.equals(child)) {
-                return true;
-            }
-            if (implementsInterface(child, parent)) {
-                return true;
-            }
-            child = PARENTS.get(child);
-            if (child == null) {
-                // Unknown view - err on the side of caution
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean implementsInterface(String className, String interfaceName) {
-        return interfaceName.equals(INTERFACES.get(className));
-    }
-
-    // Strip off type parameters, e.g. AdapterView<?> ⇒ AdapterView
-    private static String getRawType(String type) {
-        if (type != null) {
-            int index = type.indexOf('<');
-            if (index != -1) {
-                type = type.substring(0, index);
-            }
-        }
-
-        return type;
-    }
-
-    @Override
-    public boolean isLayout(@NonNull String tag) {
-        // TODO: Read in widgets.txt from the platform install area to look up this information
-        // dynamically instead!
-
-        if (super.isLayout(tag)) {
-            return true;
-        }
-
-        return LAYOUTS.contains(tag);
-    }
-
-    private static final int CLASS_COUNT = 59;
-    private static final int LAYOUT_COUNT = 20;
-
-    private static final Map<String,String> PARENTS = Maps.newHashMapWithExpectedSize(CLASS_COUNT);
-    private static final Set<String> LAYOUTS =  Sets.newHashSetWithExpectedSize(CLASS_COUNT);
-
-    static {
-        PARENTS.put(COMPOUND_BUTTON, BUTTON);
-        PARENTS.put(ABS_SPINNER, ADAPTER_VIEW);
-        PARENTS.put(ABS_LIST_VIEW, ADAPTER_VIEW);
-        PARENTS.put(ABS_SEEK_BAR, ADAPTER_VIEW);
-        PARENTS.put(ADAPTER_VIEW, VIEW_GROUP);
-        PARENTS.put(VIEW_GROUP, VIEW);
-
-        PARENTS.put(TEXT_VIEW, VIEW);
-        PARENTS.put(CHECKED_TEXT_VIEW, TEXT_VIEW);
-        PARENTS.put(RADIO_BUTTON, COMPOUND_BUTTON);
-        PARENTS.put(SPINNER, ABS_SPINNER);
-        PARENTS.put(IMAGE_BUTTON, IMAGE_VIEW);
-        PARENTS.put(IMAGE_VIEW, VIEW);
-        PARENTS.put(EDIT_TEXT, TEXT_VIEW);
-        PARENTS.put(PROGRESS_BAR, VIEW);
-        PARENTS.put(TOGGLE_BUTTON, COMPOUND_BUTTON);
-        PARENTS.put(VIEW_STUB, VIEW);
-        PARENTS.put(BUTTON, TEXT_VIEW);
-        PARENTS.put(SEEK_BAR, ABS_SEEK_BAR);
-        PARENTS.put(CHECK_BOX, COMPOUND_BUTTON);
-        PARENTS.put(SWITCH, COMPOUND_BUTTON);
-        PARENTS.put(GALLERY, ABS_SPINNER);
-        PARENTS.put(SURFACE_VIEW, VIEW);
-        PARENTS.put(ABSOLUTE_LAYOUT, VIEW_GROUP);
-        PARENTS.put(LINEAR_LAYOUT, VIEW_GROUP);
-        PARENTS.put(RELATIVE_LAYOUT, VIEW_GROUP);
-        PARENTS.put(LIST_VIEW, ABS_LIST_VIEW);
-        PARENTS.put(VIEW_SWITCHER, VIEW_ANIMATOR);
-        PARENTS.put(FRAME_LAYOUT, VIEW_GROUP);
-        PARENTS.put(HORIZONTAL_SCROLL_VIEW, FRAME_LAYOUT);
-        PARENTS.put(VIEW_ANIMATOR, FRAME_LAYOUT);
-        PARENTS.put(TAB_HOST, FRAME_LAYOUT);
-        PARENTS.put(TABLE_ROW, LINEAR_LAYOUT);
-        PARENTS.put(RADIO_GROUP, LINEAR_LAYOUT);
-        PARENTS.put(TAB_WIDGET, LINEAR_LAYOUT);
-        PARENTS.put(EXPANDABLE_LIST_VIEW, LIST_VIEW);
-        PARENTS.put(TABLE_LAYOUT, LINEAR_LAYOUT);
-        PARENTS.put(SCROLL_VIEW, FRAME_LAYOUT);
-        PARENTS.put(GRID_VIEW, ABS_LIST_VIEW);
-        PARENTS.put(WEB_VIEW, ABSOLUTE_LAYOUT);
-        PARENTS.put(AUTO_COMPLETE_TEXT_VIEW, EDIT_TEXT);
-        PARENTS.put(MULTI_AUTO_COMPLETE_TEXT_VIEW, AUTO_COMPLETE_TEXT_VIEW);
-        PARENTS.put(CHECKED_TEXT_VIEW, TEXT_VIEW);
-
-        PARENTS.put("MediaController", FRAME_LAYOUT);     //$NON-NLS-1$
-        PARENTS.put("SlidingDrawer", VIEW_GROUP);         //$NON-NLS-1$
-        PARENTS.put("DialerFilter", RELATIVE_LAYOUT);     //$NON-NLS-1$
-        PARENTS.put("DigitalClock", TEXT_VIEW);           //$NON-NLS-1$
-        PARENTS.put("Chronometer", TEXT_VIEW);            //$NON-NLS-1$
-        PARENTS.put("ImageSwitcher", VIEW_SWITCHER);      //$NON-NLS-1$
-        PARENTS.put("TextSwitcher", VIEW_SWITCHER);       //$NON-NLS-1$
-        PARENTS.put("AnalogClock", VIEW);                 //$NON-NLS-1$
-        PARENTS.put("TwoLineListItem", RELATIVE_LAYOUT);  //$NON-NLS-1$
-        PARENTS.put("ZoomControls", LINEAR_LAYOUT);       //$NON-NLS-1$
-        PARENTS.put("DatePicker", FRAME_LAYOUT);          //$NON-NLS-1$
-        PARENTS.put("TimePicker", FRAME_LAYOUT);          //$NON-NLS-1$
-        PARENTS.put("VideoView", SURFACE_VIEW);           //$NON-NLS-1$
-        PARENTS.put("ZoomButton", IMAGE_BUTTON);          //$NON-NLS-1$
-        PARENTS.put("RatingBar", ABS_SEEK_BAR);           //$NON-NLS-1$
-        PARENTS.put("ViewFlipper", VIEW_ANIMATOR);        //$NON-NLS-1$
-        PARENTS.put("NumberPicker", LINEAR_LAYOUT);       //$NON-NLS-1$
-
-        assert PARENTS.size() <= CLASS_COUNT : PARENTS.size();
-
-        /*
-        // Check that all widgets lead to the root view
-        if (LintUtils.assertionsEnabled()) {
-            for (String key : PARENTS.keySet()) {
-                String parent = PARENTS.get(key);
-                if (!parent.equals(VIEW)) {
-                    String grandParent = PARENTS.get(parent);
-                    assert grandParent != null : parent;
-                }
-            }
-        }
-        */
-
-        LAYOUTS.add(TAB_HOST);
-        LAYOUTS.add(HORIZONTAL_SCROLL_VIEW);
-        LAYOUTS.add(VIEW_SWITCHER);
-        LAYOUTS.add(TAB_WIDGET);
-        LAYOUTS.add(VIEW_ANIMATOR);
-        LAYOUTS.add(SCROLL_VIEW);
-        LAYOUTS.add(GRID_VIEW);
-        LAYOUTS.add(TABLE_ROW);
-        LAYOUTS.add(RADIO_GROUP);
-        LAYOUTS.add(LIST_VIEW);
-        LAYOUTS.add(EXPANDABLE_LIST_VIEW);
-        LAYOUTS.add("MediaController");        //$NON-NLS-1$
-        LAYOUTS.add("DialerFilter");           //$NON-NLS-1$
-        LAYOUTS.add("ViewFlipper");            //$NON-NLS-1$
-        LAYOUTS.add("SlidingDrawer");          //$NON-NLS-1$
-        LAYOUTS.add("StackView");              //$NON-NLS-1$
-        LAYOUTS.add("SearchView");             //$NON-NLS-1$
-        LAYOUTS.add("TextSwitcher");           //$NON-NLS-1$
-        LAYOUTS.add("AdapterViewFlipper");     //$NON-NLS-1$
-        LAYOUTS.add("ImageSwitcher");          //$NON-NLS-1$
-        assert LAYOUTS.size() <= LAYOUT_COUNT : LAYOUTS.size();
-    }
-
-    // Currently using a map; this should really be a list, but using a map until we actually
-    // start adding more than one item
-    @NonNull
-    private static final Map<String, String> INTERFACES = new HashMap<String, String>(2);
-    static {
-        INTERFACES.put(CHECKED_TEXT_VIEW, CHECKABLE);
-        INTERFACES.put(COMPOUND_BUTTON, CHECKABLE);
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ExternalReferenceExpression.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ExternalReferenceExpression.java
deleted file mode 100644
index c7e19a6..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ExternalReferenceExpression.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import com.android.annotations.Nullable;
-import com.intellij.psi.PsiElement;
-
-public interface ExternalReferenceExpression {
-    @Nullable
-    PsiElement resolve(PsiElement context);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/IssueRegistry.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/IssueRegistry.java
deleted file mode 100644
index bc822ec..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/IssueRegistry.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.annotations.Beta;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Registry which provides a list of checks to be performed on an Android project
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class IssueRegistry {
-    private static volatile List<Category> sCategories;
-    private static volatile Map<String, Issue> sIdToIssue;
-    private static Map<EnumSet<Scope>, List<Issue>> sScopeIssues = Maps.newHashMap();
-
-    /**
-     * Creates a new {@linkplain IssueRegistry}
-     */
-    protected IssueRegistry() {
-    }
-
-    private static final Implementation DUMMY_IMPLEMENTATION = new Implementation(Detector.class,
-            EnumSet.noneOf(Scope.class));
-    /**
-     * Issue reported by lint (not a specific detector) when it cannot even
-     * parse an XML file prior to analysis
-     */
-    @NonNull
-    public static final Issue PARSER_ERROR = Issue.create(
-            "ParserError", //$NON-NLS-1$
-            "Parser Errors",
-            "Lint will ignore any files that contain fatal parsing errors. These may contain " +
-            "other errors, or contain code which affects issues in other files.",
-            Category.CORRECTNESS,
-            10,
-            Severity.ERROR,
-            DUMMY_IMPLEMENTATION);
-
-    /**
-     * Issue reported by lint for various other issues which prevents lint from
-     * running normally when it's not necessarily an error in the user's code base.
-     */
-    @NonNull
-    public static final Issue LINT_ERROR = Issue.create(
-            "LintError", //$NON-NLS-1$
-            "Lint Failure",
-            "This issue type represents a problem running lint itself. Examples include " +
-            "failure to find bytecode for source files (which means certain detectors " +
-            "could not be run), parsing errors in lint configuration files, etc." +
-            "\n" +
-            "These errors are not errors in your own code, but they are shown to make " +
-            "it clear that some checks were not completed.",
-
-            Category.LINT,
-            10,
-            Severity.ERROR,
-            DUMMY_IMPLEMENTATION);
-
-    /**
-     * Issue reported when lint is canceled
-     */
-    @NonNull
-    public static final Issue CANCELLED = Issue.create(
-            "LintCanceled", //$NON-NLS-1$
-            "Lint Canceled",
-            "Lint canceled by user; the issue report may not be complete.",
-
-            Category.LINT,
-            0,
-            Severity.INFORMATIONAL,
-            DUMMY_IMPLEMENTATION);
-
-    /**
-     * Returns the list of issues that can be found by all known detectors.
-     *
-     * @return the list of issues to be checked (including those that may be
-     *         disabled!)
-     */
-    @NonNull
-    public abstract List<Issue> getIssues();
-
-    /**
-     * Get an approximate issue count for a given scope. This is just an optimization,
-     * so the number does not have to be accurate.
-     *
-     * @param scope the scope set
-     * @return an approximate ceiling of the number of issues expected for a given scope set
-     */
-    protected int getIssueCapacity(@NonNull EnumSet<Scope> scope) {
-        return 20;
-    }
-
-    /**
-     * Returns all available issues of a given scope (regardless of whether
-     * they are actually enabled for a given configuration etc)
-     *
-     * @param scope the applicable scope set
-     * @return a list of issues
-     */
-    @NonNull
-    protected List<Issue> getIssuesForScope(@NonNull EnumSet<Scope> scope) {
-        List<Issue> list = sScopeIssues.get(scope);
-        if (list == null) {
-            List<Issue> issues = getIssues();
-            if (scope.equals(Scope.ALL)) {
-                list = issues;
-            } else {
-                list = new ArrayList<Issue>(getIssueCapacity(scope));
-                for (Issue issue : issues) {
-                    // Determine if the scope matches
-                    if (issue.getImplementation().isAdequate(scope)) {
-                        list.add(issue);
-                    }
-                }
-            }
-            sScopeIssues.put(scope, list);
-        }
-
-        return list;
-    }
-
-    /**
-     * Creates a list of detectors applicable to the given scope, and with the
-     * given configuration.
-     *
-     * @param client the client to report errors to
-     * @param configuration the configuration to look up which issues are
-     *            enabled etc from
-     * @param scope the scope for the analysis, to filter out detectors that
-     *            require wider analysis than is currently being performed
-     * @param scopeToDetectors an optional map which (if not null) will be
-     *            filled by this method to contain mappings from each scope to
-     *            the applicable detectors for that scope
-     * @return a list of new detector instances
-     */
-    @NonNull
-    final List<? extends Detector> createDetectors(
-            @NonNull LintClient client,
-            @NonNull Configuration configuration,
-            @NonNull EnumSet<Scope> scope,
-            @Nullable Map<Scope, List<Detector>> scopeToDetectors) {
-
-        List<Issue> issues = getIssuesForScope(scope);
-        if (issues.isEmpty()) {
-            return Collections.emptyList();
-        }
-
-        Set<Class<? extends Detector>> detectorClasses = new HashSet<Class<? extends Detector>>();
-        Map<Class<? extends Detector>, EnumSet<Scope>> detectorToScope =
-                new HashMap<Class<? extends Detector>, EnumSet<Scope>>();
-
-        for (Issue issue : issues) {
-            Implementation implementation = issue.getImplementation();
-            Class<? extends Detector> detectorClass = implementation.getDetectorClass();
-            EnumSet<Scope> issueScope = implementation.getScope();
-            if (!detectorClasses.contains(detectorClass)) {
-                // Determine if the issue is enabled
-                if (!configuration.isEnabled(issue)) {
-                    continue;
-                }
-
-                assert implementation.isAdequate(scope); // Ensured by getIssuesForScope above
-
-                detectorClass = client.replaceDetector(detectorClass);
-
-                assert detectorClass != null : issue.getId();
-                detectorClasses.add(detectorClass);
-            }
-
-            if (scopeToDetectors != null) {
-                EnumSet<Scope> s = detectorToScope.get(detectorClass);
-                if (s == null) {
-                    detectorToScope.put(detectorClass, issueScope);
-                } else if (!s.containsAll(issueScope)) {
-                    EnumSet<Scope> union = EnumSet.copyOf(s);
-                    union.addAll(issueScope);
-                    detectorToScope.put(detectorClass, union);
-                }
-            }
-        }
-
-        List<Detector> detectors = new ArrayList<Detector>(detectorClasses.size());
-        for (Class<? extends Detector> clz : detectorClasses) {
-            try {
-                Detector detector = clz.newInstance();
-                detectors.add(detector);
-
-                if (scopeToDetectors != null) {
-                    EnumSet<Scope> union = detectorToScope.get(clz);
-                    for (Scope s : union) {
-                        List<Detector> list = scopeToDetectors.get(s);
-                        if (list == null) {
-                            list = new ArrayList<Detector>();
-                            scopeToDetectors.put(s, list);
-                        }
-                        list.add(detector);
-                    }
-
-                }
-            } catch (Throwable t) {
-                client.log(t, "Can't initialize detector %1$s", clz.getName()); //$NON-NLS-1$
-            }
-        }
-
-        return detectors;
-    }
-
-    /**
-     * Returns true if the given id represents a valid issue id
-     *
-     * @param id the id to be checked
-     * @return true if the given id is valid
-     */
-    public final boolean isIssueId(@NonNull String id) {
-        return getIssue(id) != null;
-    }
-
-    /**
-     * Returns true if the given category is a valid category
-     *
-     * @param name the category name to be checked
-     * @return true if the given string is a valid category
-     */
-    public final boolean isCategoryName(@NonNull String name) {
-        for (Category category : getCategories()) {
-            if (category.getName().equals(name) || category.getFullName().equals(name)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the available categories
-     *
-     * @return an iterator for all the categories, never null
-     */
-    @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
-    @NonNull
-    public List<Category> getCategories() {
-        List<Category> categories = sCategories;
-        if (categories == null) {
-            synchronized (IssueRegistry.class) {
-                categories = sCategories;
-                if (categories == null) {
-                    sCategories = categories = Collections.unmodifiableList(createCategoryList());
-                }
-            }
-        }
-
-        return categories;
-    }
-
-    @NonNull
-    private List<Category> createCategoryList() {
-        Set<Category> categorySet = Sets.newHashSetWithExpectedSize(20);
-        for (Issue issue : getIssues()) {
-            categorySet.add(issue.getCategory());
-        }
-        List<Category> sorted = new ArrayList<Category>(categorySet);
-        Collections.sort(sorted);
-        return sorted;
-    }
-
-    /**
-     * Returns the issue for the given id, or null if it's not a valid id
-     *
-     * @param id the id to be checked
-     * @return the corresponding issue, or null
-     */
-    @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
-    @Nullable
-    public final Issue getIssue(@NonNull String id) {
-        Map<String, Issue> map = sIdToIssue;
-        if (map == null) {
-            synchronized (IssueRegistry.class) {
-                map = sIdToIssue;
-                if (map == null) {
-                    map = createIdToIssueMap();
-                    sIdToIssue = map;
-                }
-            }
-        }
-
-        return map.get(id);
-    }
-
-    @NonNull
-    private Map<String, Issue> createIdToIssueMap() {
-        List<Issue> issues = getIssues();
-        Map<String, Issue> map = Maps.newHashMapWithExpectedSize(issues.size() + 2);
-        for (Issue issue : issues) {
-            map.put(issue.getId(), issue);
-        }
-
-        map.put(PARSER_ERROR.getId(), PARSER_ERROR);
-        map.put(LINT_ERROR.getId(), LINT_ERROR);
-        return map;
-    }
-
-    /**
-     * Reset the registry such that it recomputes its available issues.
-     */
-    protected static void reset() {
-        sIdToIssue = null;
-        sCategories = null;
-        sScopeIssues = Maps.newHashMap();
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JarFileIssueRegistry.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JarFileIssueRegistry.java
deleted file mode 100644
index 79b4dca..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JarFileIssueRegistry.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.client.api;
-
-import static com.android.SdkConstants.DOT_CLASS;
-
-import com.android.annotations.NonNull;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.utils.SdkUtils;
-import com.google.common.collect.Lists;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-
-/**
- * <p> An {@link IssueRegistry} for a custom lint rule jar file. The rule jar should provide a
- * manifest entry with the key {@code Lint-Registry} and the value of the fully qualified name of an
- * implementation of {@link IssueRegistry} (with a default constructor). </p>
- *
- * <p> NOTE: The custom issue registry should not extend this file; it should be a plain
- * IssueRegistry! This file is used internally to wrap the given issue registry.</p>
- */
-class JarFileIssueRegistry extends IssueRegistry {
-    /**
-     * Manifest constant for declaring an issue provider. Example: Lint-Registry:
-     * foo.bar.CustomIssueRegistry
-     */
-    private static final String MF_LINT_REGISTRY_OLD = "Lint-Registry"; //$NON-NLS-1$
-    private static final String MF_LINT_REGISTRY = "Lint-Registry-v2"; //$NON-NLS-1$
-
-    private static Map<File, SoftReference<JarFileIssueRegistry>> sCache;
-
-    private final List<Issue> myIssues;
-
-    private boolean mHasLegacyDetectors;
-
-    /** True if one or more java detectors were found that use the old Lombok-based API */
-    public boolean hasLegacyDetectors() {
-        return mHasLegacyDetectors;
-    }
-
-    @NonNull
-    static JarFileIssueRegistry get(@NonNull LintClient client, @NonNull File jarFile)
-            throws IOException, ClassNotFoundException, IllegalAccessException,
-            InstantiationException {
-        if (sCache == null) {
-           sCache = new HashMap<File, SoftReference<JarFileIssueRegistry>>();
-        } else {
-            SoftReference<JarFileIssueRegistry> reference = sCache.get(jarFile);
-            if (reference != null) {
-                JarFileIssueRegistry registry = reference.get();
-                if (registry != null) {
-                    return registry;
-                }
-            }
-        }
-
-        // Ensure that the scope-to-detector map doesn't return stale results
-        IssueRegistry.reset();
-
-        JarFileIssueRegistry registry = new JarFileIssueRegistry(client, jarFile);
-        sCache.put(jarFile, new SoftReference<JarFileIssueRegistry>(registry));
-        return registry;
-    }
-
-    private JarFileIssueRegistry(@NonNull LintClient client, @NonNull File file)
-            throws IOException, ClassNotFoundException, IllegalAccessException,
-                    InstantiationException {
-        myIssues = Lists.newArrayList();
-        JarFile jarFile = null;
-        try {
-            //noinspection IOResourceOpenedButNotSafelyClosed
-            jarFile = new JarFile(file);
-            Manifest manifest = jarFile.getManifest();
-            Attributes attrs = manifest.getMainAttributes();
-            Object object = attrs.get(new Attributes.Name(MF_LINT_REGISTRY));
-            boolean isLegacy = false;
-            if (object == null) {
-                object = attrs.get(new Attributes.Name(MF_LINT_REGISTRY_OLD));
-                //noinspection VariableNotUsedInsideIf
-                if (object != null) {
-                    // It's an old rule. We don't yet conclude that
-                    //   mHasLegacyDetectors=true
-                    // because the lint checks may not be Java related.
-                    isLegacy = true;
-                }
-            }
-            if (object instanceof String) {
-                String className = (String) object;
-                // Make a class loader for this jar
-                URL url = SdkUtils.fileToUrl(file);
-                ClassLoader loader = client.createUrlClassLoader(new URL[]{url},
-                        JarFileIssueRegistry.class.getClassLoader());
-                Class<?> registryClass = Class.forName(className, true, loader);
-                IssueRegistry registry = (IssueRegistry) registryClass.newInstance();
-                myIssues.addAll(registry.getIssues());
-
-                if (isLegacy) {
-                    // If it's an old registry, look through the issues to see if it
-                    // provides Java scanning and if so create the old style visitors
-                    for (Issue issue : myIssues) {
-                        EnumSet<Scope> scope = issue.getImplementation().getScope();
-                        if (scope.contains(Scope.JAVA_FILE) || scope.contains(Scope.JAVA_LIBRARIES)
-                                || scope.contains(Scope.ALL_JAVA_FILES)) {
-                            mHasLegacyDetectors = true;
-                            break;
-                        }
-                    }
-                }
-
-                if (loader instanceof URLClassLoader) {
-                    loadAndCloseURLClassLoader(client, file, (URLClassLoader)loader);
-                }
-            } else {
-                client.log(Severity.ERROR, null,
-                    "Custom lint rule jar %1$s does not contain a valid registry manifest key " +
-                    "(%2$s).\n" +
-                    "Either the custom jar is invalid, or it uses an outdated API not supported " +
-                    "this lint client", file.getPath(), MF_LINT_REGISTRY);
-            }
-        } finally {
-            if (jarFile != null) {
-                jarFile.close();
-            }
-        }
-    }
-
-    /**
-     * Work around http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5041014 :
-     * URLClassLoader, on Windows, locks the .jar file forever.
-     * As of Java 7, there's a workaround: you can call close() when you're "done"
-     * with the file. We'll do that here. However, the whole point of the
-     * {@linkplain JarFileIssueRegistry} is that when lint is run over and over again
-     * as the user is editing in the IDE and we're background checking the code, we
-     * don't to keep loading the custom view classes over and over again: we want to
-     * cache them. Therefore, just closing the URLClassLoader right away isn't great
-     * either. However, it turns out it's safe to close the URLClassLoader once you've
-     * loaded the classes you need, since the URLClassLoader will continue to serve
-     * those classes even after its close() methods has been called.
-     * <p>
-     * Therefore, if we can call close() on this URLClassLoader, we'll proactively load
-     * all class files we find in the .jar file, then close it.
-     *
-     * @param client the client to report errors to
-     * @param file the .jar file
-     * @param loader the URLClassLoader we should close
-     */
-    private static void loadAndCloseURLClassLoader(
-            @NonNull LintClient client,
-            @NonNull File file,
-            @NonNull URLClassLoader loader) {
-        try {
-            // Proactively close out the .jar file. This is only available on Java 7.
-            Method closeMethod = loader.getClass().getDeclaredMethod("close");
-
-            // But first, proactively load all classes:
-            try {
-                InputStream inputStream = new FileInputStream(file);
-                try {
-                    JarInputStream jarInputStream = new JarInputStream(inputStream);
-                    try {
-                        ZipEntry entry = jarInputStream.getNextEntry();
-                        while (entry != null) {
-                            String name = entry.getName();
-                            // Load non-inner-classes
-                            if (name.endsWith(DOT_CLASS)) {
-                                // Strip .class suffix and change .jar file path (/)
-                                // to class name (.'s).
-                                name = name.substring(0,
-                                        name.length() - DOT_CLASS.length());
-                                name = name.replace('/', '.');
-                                try {
-                                    Class.forName(name, true, loader);
-                                } catch (Throwable e) {
-                                    client.log(Severity.ERROR, e,
-                                            "Failed to prefetch " + name + " from " + file);
-                                }
-                            }
-                            entry = jarInputStream.getNextEntry();
-                        }
-                    } finally {
-                        jarInputStream.close();
-                    }
-                } finally {
-                    inputStream.close();
-                }
-            } catch (Throwable ignore) {
-            } finally {
-                // Finally close the URL class loader
-                try {
-                    closeMethod.invoke(loader);
-                } catch (Throwable ignore) {
-                    // Couldn't close. This is unlikely.
-                }
-            }
-        } catch (NoSuchMethodException ignore) {
-            // No close method - we're on 1.6
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<Issue> getIssues() {
-        return myIssues;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaEvaluator.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaEvaluator.java
deleted file mode 100644
index 46eeb1f..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaEvaluator.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiMember;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiModifier;
-import com.intellij.psi.PsiModifierList;
-import com.intellij.psi.PsiModifierListOwner;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiParameterList;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.util.InheritanceUtil;
-
-import java.io.File;
-
-@SuppressWarnings("MethodMayBeStatic") // Some of these methods may be overridden by LintClients
-public abstract class JavaEvaluator {
-    public boolean isMemberInSubClassOf(
-            @NonNull PsiMember method,
-            @NonNull String className,
-            boolean strict) {
-        PsiClass containingClass = method.getContainingClass();
-        return containingClass != null && InheritanceUtil.isInheritor(containingClass, strict, className);
-    }
-
-    public static boolean isMemberInClass(
-            @Nullable PsiMember method,
-            @NonNull String className) {
-        if (method == null) {
-            return false;
-        }
-        PsiClass containingClass = method.getContainingClass();
-        return containingClass != null && className.equals(containingClass.getQualifiedName());
-    }
-
-    public int getParameterCount(@NonNull PsiMethod method) {
-        return method.getParameterList().getParametersCount();
-    }
-
-    /**
-     * Returns true if the given method (which is typically looked up by resolving a method call) is
-     * either a method in the exact given class, or if {@code allowInherit} is true, a method in a
-     * class possibly extending the given class, and if the parameter types are the exact types
-     * specified.
-     *
-     * @param method        the method in question
-     * @param className     the class name the method should be defined in or inherit from (or
-     *                      if null, allow any class)
-     * @param allowInherit  whether we allow checking for inheritance
-     * @param argumentTypes the names of the types of the parameters
-     * @return true if this method is defined in the given class and with the given parameters
-     */
-    public boolean methodMatches(
-            @NonNull PsiMethod method,
-            @Nullable String className,
-            boolean allowInherit,
-            @NonNull String... argumentTypes) {
-        if (className != null && allowInherit) {
-            if (!isMemberInSubClassOf(method, className, false)) {
-                return false;
-            }
-        }
-
-        return parametersMatch(method, argumentTypes);
-    }
-
-    /**
-     * Returns true if the given method's parameters are the exact types specified.
-     *
-     * @param method        the method in question
-     * @param argumentTypes the names of the types of the parameters
-     * @return true if this method is defined in the given class and with the given parameters
-     */
-    public boolean parametersMatch(
-            @NonNull PsiMethod method,
-            @NonNull String... argumentTypes) {
-        PsiParameterList parameterList = method.getParameterList();
-        if (parameterList.getParametersCount() != argumentTypes.length) {
-            return false;
-        }
-        PsiParameter[] parameters = parameterList.getParameters();
-        for (int i = 0; i < parameters.length; i++) {
-            PsiType type = parameters[i].getType();
-            if (!type.getCanonicalText().equals(argumentTypes[i])) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /** Returns true if the given type matches the given fully qualified type name */
-    public boolean parameterHasType(
-            @Nullable PsiMethod method,
-            int parameterIndex,
-            @NonNull String typeName) {
-        if (method == null) {
-            return false;
-        }
-        PsiParameterList parameterList = method.getParameterList();
-        return parameterList.getParametersCount() > parameterIndex
-                && typeMatches(parameterList.getParameters()[parameterIndex].getType(), typeName);
-    }
-
-    /** Returns true if the given type matches the given fully qualified type name */
-    public boolean typeMatches(
-            @Nullable PsiType type,
-            @NonNull String typeName) {
-        return type != null && type.getCanonicalText().equals(typeName);
-
-    }
-
-    @Nullable
-    public PsiElement resolve(@NonNull PsiElement element) {
-        if (element instanceof PsiReference) {
-            return ((PsiReference)element).resolve();
-        } else if (element instanceof PsiMethodCallExpression) {
-            PsiElement resolved = ((PsiMethodCallExpression) element).resolveMethod();
-            if (resolved != null) {
-                return resolved;
-            }
-        }
-        return null;
-    }
-
-    public boolean isPublic(@Nullable PsiModifierListOwner owner) {
-        if (owner != null) {
-            PsiModifierList modifierList = owner.getModifierList();
-            return modifierList != null && modifierList.hasModifierProperty(PsiModifier.PUBLIC);
-        }
-        return false;
-    }
-
-    public boolean isStatic(@Nullable PsiModifierListOwner owner) {
-        if (owner != null) {
-            PsiModifierList modifierList = owner.getModifierList();
-            return modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC);
-        }
-        return false;
-    }
-
-    public boolean isPrivate(@Nullable PsiModifierListOwner owner) {
-        if (owner != null) {
-            PsiModifierList modifierList = owner.getModifierList();
-            return modifierList != null && modifierList.hasModifierProperty(PsiModifier.PRIVATE);
-        }
-        return false;
-    }
-
-    public boolean isAbstract(@Nullable PsiModifierListOwner owner) {
-        if (owner != null) {
-            PsiModifierList modifierList = owner.getModifierList();
-            return modifierList != null && modifierList.hasModifierProperty(PsiModifier.ABSTRACT);
-        }
-        return false;
-    }
-
-    public boolean isFinal(@Nullable PsiModifierListOwner owner) {
-        if (owner != null) {
-            PsiModifierList modifierList = owner.getModifierList();
-            return modifierList != null && modifierList.hasModifierProperty(PsiModifier.FINAL);
-        }
-        return false;
-    }
-
-    @Nullable
-    public PsiMethod getSuperMethod(@Nullable PsiMethod method) {
-        if (method == null) {
-            return null;
-        }
-        final PsiMethod[] superMethods = method.findSuperMethods();
-        if (superMethods.length > 0) {
-            return superMethods[0];
-        }
-        return null;
-    }
-
-    @NonNull
-    public String getInternalName(@NonNull PsiClass psiClass) {
-        String qualifiedName = psiClass.getQualifiedName();
-        if (qualifiedName == null) {
-            qualifiedName = psiClass.getName();
-            if (qualifiedName == null) {
-                assert psiClass instanceof PsiAnonymousClass;
-                //noinspection ConstantConditions
-                return getInternalName(psiClass.getContainingClass());
-            }
-        }
-        return ClassContext.getInternalName(qualifiedName);
-    }
-
-    @NonNull
-    public String getInternalName(@NonNull PsiClassType psiClassType) {
-        return ClassContext.getInternalName(psiClassType.getCanonicalText());
-    }
-
-    @Nullable
-    public abstract PsiClass findClass(@NonNull String qualifiedName);
-
-    @Nullable
-    public abstract PsiClassType getClassType(@Nullable PsiClass psiClass);
-
-    @NonNull
-    public abstract PsiAnnotation[] getAllAnnotations(@NonNull PsiModifierListOwner owner);
-
-    @Nullable
-    public abstract PsiAnnotation findAnnotationInHierarchy(
-            @NonNull PsiModifierListOwner listOwner,
-            @NonNull String... annotationNames);
-
-    @Nullable
-    public abstract PsiAnnotation findAnnotation(
-            @Nullable PsiModifierListOwner listOwner,
-            @NonNull String... annotationNames);
-
-    @Nullable
-    public abstract File getFile(@NonNull PsiFile file);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaParser.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaParser.java
deleted file mode 100644
index 9676385..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaParser.java
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.ATTR_VALUE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.DefaultPosition;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Position;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Splitter;
-import com.intellij.mock.MockProject;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiComment;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiJavaFile;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UFile;
-import org.jetbrains.uast.UastContext;
-
-import java.io.File;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.List;
-
-import lombok.ast.Catch;
-import lombok.ast.For;
-import lombok.ast.Identifier;
-import lombok.ast.If;
-import lombok.ast.Node;
-import lombok.ast.Return;
-import lombok.ast.StrictListAccessor;
-import lombok.ast.Switch;
-import lombok.ast.Throw;
-import lombok.ast.TypeReference;
-import lombok.ast.TypeReferencePart;
-import lombok.ast.While;
-
-/**
- * A wrapper for a Java parser. This allows tools integrating lint to map directly
- * to builtin services, such as already-parsed data structures in Java editors.
- * <p>
- * <b>NOTE: This is not public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-// Currently ships with deprecated API support
-@SuppressWarnings({"deprecation", "UnusedParameters"})
-@Beta
-public abstract class JavaParser {
-    public static final String TYPE_OBJECT = "java.lang.Object";
-    public static final String TYPE_STRING = "java.lang.String";
-    public static final String TYPE_INT = "int";
-    public static final String TYPE_LONG = "long";
-    public static final String TYPE_CHAR = "char";
-    public static final String TYPE_FLOAT = "float";
-    public static final String TYPE_DOUBLE = "double";
-    public static final String TYPE_BOOLEAN = "boolean";
-    public static final String TYPE_SHORT = "short";
-    public static final String TYPE_BYTE = "byte";
-    public static final String TYPE_NULL = "null";
-    public static final String TYPE_INTEGER_WRAPPER = "java.lang.Integer";
-    public static final String TYPE_BOOLEAN_WRAPPER = "java.lang.Boolean";
-    public static final String TYPE_BYTE_WRAPPER = "java.lang.Byte";
-    public static final String TYPE_SHORT_WRAPPER = "java.lang.Short";
-    public static final String TYPE_LONG_WRAPPER = "java.lang.Long";
-    public static final String TYPE_DOUBLE_WRAPPER = "java.lang.Double";
-    public static final String TYPE_FLOAT_WRAPPER = "java.lang.Float";
-    public static final String TYPE_CHARACTER_WRAPPER = "java.lang.Character";
-
-    /**
-     * Prepare to parse the given contexts. This method will be called before
-     * a series of {@link #parseJava(JavaContext)} calls, which allows some
-     * parsers to do up front global computation in case they want to more
-     * efficiently process multiple files at the same time. This allows a single
-     * type-attribution pass for example, which is a lot more efficient than
-     * performing global type analysis over and over again for each individual
-     * file
-     *
-     * @param contexts a list of contexts to be parsed
-     */
-    public abstract void prepareJavaParse(@NonNull List<JavaContext> contexts);
-
-    /**
-     * Parse the file pointed to by the given context.
-     *
-     * @param context the context pointing to the file to be parsed, typically
-     *            via {@link Context#getContents()} but the file handle (
-     *            {@link Context#file} can also be used to map to an existing
-     *            editor buffer in the surrounding tool, etc)
-     * @return the compilation unit node for the file
-     * @deprecated Use {@link #parseJavaToPsi(JavaContext)} instead
-     */
-    @Deprecated
-    @Nullable
-    public Node parseJava(@NonNull JavaContext context) {
-        return null;
-    }
-
-    /**
-     * Parse the file pointed to by the given context.
-     *
-     * @param context the context pointing to the file to be parsed, typically
-     *            via {@link Context#getContents()} but the file handle (
-     *            {@link Context#file} can also be used to map to an existing
-     *            editor buffer in the surrounding tool, etc)
-     * @return the compilation unit node for the file
-     */
-    @Nullable
-    public abstract PsiJavaFile parseJavaToPsi(@NonNull JavaContext context);
-
-    /**
-     * Returns an evaluator which can perform various resolution tasks,
-     * evaluate inheritance lookup etc.
-     *
-     * @return an evaluator
-     */
-    @NonNull
-    public abstract JavaEvaluator getEvaluator();
-    
-    public abstract Project getIdeaProject();
-    
-    public abstract UastContext getUastContext();
-
-    /**
-     * Returns a {@link Location} for the given node
-     *
-     * @param context information about the file being parsed
-     * @param node    the node to create a location for
-     * @return a location for the given node
-     * @deprecated Use {@link #getNameLocation(JavaContext, PsiElement)} instead
-     */
-    @Deprecated
-    @NonNull
-    public Location getLocation(@NonNull JavaContext context, @NonNull Node node) {
-        // No longer mandatory to override for children; this is a deprecated API
-        return Location.NONE;
-    }
-
-    /**
-     * Returns a {@link Location} for the given element
-     *
-     * @param context information about the file being parsed
-     * @param element the element to create a location for
-     * @return a location for the given node
-     */
-    @SuppressWarnings("MethodMayBeStatic") // subclasses may want to override/optimize
-    @NonNull
-    public Location getLocation(@NonNull JavaContext context, @NonNull PsiElement element) {
-        TextRange range = element.getTextRange();
-        UFile uFile = (UFile) getUastContext().convertElementWithParent(element.getContainingFile(), UFile.class);
-        if (uFile == null) {
-            return Location.NONE;
-        }
-        
-        PsiFile containingFile = uFile.getPsi();
-        File file = context.file;
-        if (containingFile != context.getUFile().getPsi()) {
-            // Reporting an error in a different file.
-            if (context.getDriver().getScope().size() == 1) {
-                // Don't bother with this error if it's in a different file during single-file analysis
-                return Location.NONE;
-            }
-            VirtualFile virtualFile = containingFile.getVirtualFile();
-            if (virtualFile == null) {
-                return Location.NONE;
-            }
-            file = VfsUtilCore.virtualToIoFile(virtualFile);
-        }
-        return Location.create(file, context.getContents(), range.getStartOffset(),
-                               range.getEndOffset());
-    }
-
-    /**
-     * Returns a {@link Location} for the given node range (from the starting offset of the first
-     * node to the ending offset of the second node).
-     *
-     * @param context   information about the file being parsed
-     * @param from      the AST node to get a starting location from
-     * @param fromDelta Offset delta to apply to the starting offset
-     * @param to        the AST node to get a ending location from
-     * @param toDelta   Offset delta to apply to the ending offset
-     * @return a location for the given node
-     * @deprecated Use {@link #getRangeLocation(JavaContext, PsiElement, int, PsiElement, int)}
-     * instead
-     */
-    @Deprecated
-    @NonNull
-    public abstract Location getRangeLocation(
-            @NonNull JavaContext context,
-            @NonNull Node from,
-            int fromDelta,
-            @NonNull Node to,
-            int toDelta);
-
-    /**
-     * Returns a {@link Location} for the given node range (from the starting offset of the first
-     * node to the ending offset of the second node).
-     *
-     * @param context   information about the file being parsed
-     * @param from      the AST node to get a starting location from
-     * @param fromDelta Offset delta to apply to the starting offset
-     * @param to        the AST node to get a ending location from
-     * @param toDelta   Offset delta to apply to the ending offset
-     * @return a location for the given node
-     */
-    @SuppressWarnings("MethodMayBeStatic") // subclasses may want to override/optimize
-    @NonNull
-    public Location getRangeLocation(
-            @NonNull JavaContext context,
-            @NonNull PsiElement from,
-            int fromDelta,
-            @NonNull PsiElement to,
-            int toDelta) {
-        String contents = context.getContents();
-        int start = Math.max(0, from.getTextRange().getStartOffset() + fromDelta);
-        int end = Math.min(contents == null ? Integer.MAX_VALUE : contents.length(),
-                to.getTextRange().getEndOffset() + toDelta);
-        return Location.create(context.file, contents, start, end);
-    }
-
-    /**
-     * Like {@link #getRangeLocation(JavaContext, PsiElement, int, PsiElement, int)}
-     * but both offsets are relative to the starting offset of the given node. This is
-     * sometimes more convenient than operating relative to the ending offset when you
-     * have a fixed range in mind.
-     *
-     * @param context   information about the file being parsed
-     * @param from      the AST node to get a starting location from
-     * @param fromDelta Offset delta to apply to the starting offset
-     * @param toDelta   Offset delta to apply to the starting offset
-     * @return a location for the given node
-     */
-    @SuppressWarnings("MethodMayBeStatic") // subclasses may want to override/optimize
-    @NonNull
-    public Location getRangeLocation(
-            @NonNull JavaContext context,
-            @NonNull PsiElement from,
-            int fromDelta,
-            int toDelta) {
-        return getRangeLocation(context, from, fromDelta, from,
-                -(from.getTextRange().getLength() - toDelta));
-    }
-
-    /**
-     * Returns a {@link Location} for the given node. This attempts to pick a shorter
-     * location range than the entire node; for a class or method for example, it picks
-     * the name node (if found). For statement constructs such as a {@code switch} statement
-     * it will highlight the keyword, etc.
-     *
-     * @param context information about the file being parsed
-     * @param node the node to create a location for
-     * @return a location for the given node
-     * @deprecated Use {@link #getNameLocation(JavaContext, PsiElement)} instead
-     */
-    @Deprecated
-    @NonNull
-    public Location getNameLocation(@NonNull JavaContext context, @NonNull Node node) {
-        Node nameNode = JavaContext.findNameNode(node);
-        if (nameNode != null) {
-            node = nameNode;
-        } else {
-            if (node instanceof Switch
-                    || node instanceof For
-                    || node instanceof If
-                    || node instanceof While
-                    || node instanceof Throw
-                    || node instanceof Return) {
-                // Lint doesn't want to highlight the entire statement/block associated
-                // with this node, it wants to just highlight the keyword.
-                Location location = getLocation(context, node);
-                Position start = location.getStart();
-                if (start != null) {
-                    // The Lombok classes happen to have the same length as the target keyword
-                    int length = node.getClass().getSimpleName().length();
-                    return Location.create(location.getFile(), start,
-                            new DefaultPosition(start.getLine(), start.getColumn() + length,
-                                    start.getOffset() + length));
-                }
-            }
-        }
-
-        return getLocation(context, node);
-    }
-
-    /**
-     * Returns a {@link Location} for the given node. This attempts to pick a shorter
-     * location range than the entire node; for a class or method for example, it picks
-     * the name node (if found). For statement constructs such as a {@code switch} statement
-     * it will highlight the keyword, etc.
-     *
-     * @param context information about the file being parsed
-     * @param element the node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getNameLocation(@NonNull JavaContext context, @NonNull PsiElement element) {
-        PsiElement nameNode = JavaContext.findNameElement(element);
-        if (nameNode != null) {
-            element = nameNode;
-        }
-
-        return getLocation(context, element);
-    }
-    /**
-     * Creates a light-weight handle to a location for the given node. It can be
-     * turned into a full fledged location by
-     * {@link com.android.tools.lint.detector.api.Location.Handle#resolve()}.
-     *
-     * @param context the context providing the node
-     * @param node the node (element or attribute) to create a location handle
-     *            for
-     * @return a location handle
-     * @deprecated Use PSI instead (where handles aren't necessary; use PsiElement directly)
-     */
-    @Deprecated
-    @NonNull
-    public abstract Location.Handle createLocationHandle(@NonNull JavaContext context,
-            @NonNull Node node);
-
-    /**
-     * Dispose any data structures held for the given context.
-     * @param context information about the file previously parsed
-     * @param compilationUnit the compilation unit being disposed
-     * @deprecated Use {@link #dispose(JavaContext, PsiJavaFile)} instead
-     */
-    @Deprecated
-    public void dispose(@NonNull JavaContext context, @NonNull Node compilationUnit) {
-    }
-
-    /**
-     * Dispose any data structures held for the given context.
-     * @param context information about the file previously parsed
-     * @param compilationUnit the compilation unit being disposed
-     */
-    public void dispose(@NonNull JavaContext context, @NonNull PsiFile compilationUnit) {
-    }
-
-    /**
-     * Dispose any data structures held for the given context.
-     * @param context information about the file previously parsed
-     * @param compilationUnit the compilation unit being disposed
-     */
-    public void dispose(@NonNull JavaContext context, @NonNull UFile compilationUnit) {
-    }
-
-    /**
-     * Dispose any remaining data structures held for all contexts.
-     * Typically frees up any resources allocated by
-     * {@link #prepareJavaParse(List)}
-     */
-    public void dispose() {
-    }
-
-    /**
-     * Resolves the given expression node: computes the declaration for the given symbol
-     *
-     * @param context information about the file being parsed
-     * @param node the node to resolve
-     * @return a node representing the resolved fully type: class/interface/annotation,
-     *          field, method or variable
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    @Nullable
-    public ResolvedNode resolve(@NonNull JavaContext context, @NonNull Node node) {
-        return null;
-    }
-
-    /**
-     * Finds the given type, if possible (which should be reachable from the compilation
-     * patch of the given node.
-     *
-     * @param context information about the file being parsed
-     * @param fullyQualifiedName the fully qualified name of the class to look up
-     * @return the class, or null if not found
-     */
-    @Nullable
-    public ResolvedClass findClass(
-            @NonNull JavaContext context,
-            @NonNull String fullyQualifiedName) {
-        return null;
-    }
-
-    /**
-     * Returns the set of exception types handled by the given catch block.
-     * <p>
-     * This is a workaround for the fact that the Lombok AST API (and implementation)
-     * doesn't support multi-catch statements.
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    public List<TypeDescriptor> getCatchTypes(@NonNull JavaContext context,
-            @NonNull Catch catchBlock) {
-        TypeReference typeReference = catchBlock.astExceptionDeclaration().astTypeReference();
-        return Collections.<TypeDescriptor>singletonList(new DefaultTypeDescriptor(
-                typeReference.getTypeName()));
-    }
-
-    /**
-     * Gets the type of the given node
-     *
-     * @param context information about the file being parsed
-     * @param node the node to look up the type for
-     * @return the type of the node, if known
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    @Nullable
-    public TypeDescriptor getType(@NonNull JavaContext context, @NonNull Node node) {
-        return null;
-    }
-
-    /**
-     * Runs the given runnable under a readlock such that it can access the PSI
-     *
-     * @param runnable the runnable to be run
-     */
-    public abstract void runReadAction(@NonNull Runnable runnable);
-
-    /**
-     * A description of a type, such as a primitive int or the android.app.Activity class
-     * @deprecated Use {@link PsiType} instead
-     */
-    @SuppressWarnings("unused")
-    @Deprecated
-    public abstract static class TypeDescriptor {
-        /**
-         * Returns the fully qualified name of the type, such as "int" or "android.app.Activity"
-         * */
-        @NonNull public abstract String getName();
-
-        /** Returns the simple name of this class */
-        @NonNull
-        public String getSimpleName() {
-            // This doesn't handle inner classes properly, so subclasses with more
-            // accurate type information will override to handle it correctly.
-            String name = getName();
-            int index = name.lastIndexOf('.');
-            if (index != -1) {
-                return name.substring(index + 1);
-            }
-            return name;
-        }
-
-        /**
-         * Returns the full signature of the type, which is normally the same as {@link #getName()}
-         * but for arrays can include []'s, for generic methods can include generics parameters
-         * etc
-         */
-        @NonNull public abstract String getSignature();
-
-        /**
-         * Computes the internal class name of the given fully qualified class name.
-         * For example, it converts foo.bar.Foo.Bar into foo/bar/Foo$Bar.
-         * This should only be called for class types, not primitives.
-         *
-         * @return the internal class name
-         */
-        @NonNull public String getInternalName() {
-            return ClassContext.getInternalName(getName());
-        }
-
-        public abstract boolean matchesName(@NonNull String name);
-
-        /**
-         * Returns true if the given TypeDescriptor represents an array
-         * @return true if this type represents an array
-         */
-        public abstract boolean isArray();
-
-        /**
-         * Returns true if the given TypeDescriptor represents a primitive
-         * @return true if this type represents a primitive
-         */
-        public abstract boolean isPrimitive();
-
-        public abstract boolean matchesSignature(@NonNull String signature);
-
-        @NonNull
-        public TypeReference getNode() {
-            TypeReference typeReference = new TypeReference();
-            StrictListAccessor<TypeReferencePart, TypeReference> parts = typeReference.astParts();
-            for (String part : Splitter.on('.').split(getName())) {
-                Identifier identifier = Identifier.of(part);
-                parts.addToEnd(new TypeReferencePart().astIdentifier(identifier));
-            }
-
-            return typeReference;
-        }
-
-        /** If the type is not primitive, returns the class of the type if known */
-        @Nullable
-        public abstract ResolvedClass getTypeClass();
-
-        @Override
-        public abstract boolean equals(Object o);
-
-        @Override
-        public String toString() {
-            return getName();
-        }
-    }
-
-    /**
-     * Convenience implementation of {@link TypeDescriptor}
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    public static class DefaultTypeDescriptor extends TypeDescriptor {
-
-        private String mName;
-
-        public DefaultTypeDescriptor(String name) {
-            mName = name;
-        }
-
-        @NonNull
-        @Override
-        public String getName() {
-            return mName;
-        }
-
-        @NonNull
-        @Override
-        public String getSignature() {
-            return getName();
-        }
-
-        @Override
-        public boolean matchesName(@NonNull String name) {
-            return mName.equals(name);
-        }
-
-        @Override
-        public boolean isArray() {
-            return mName.endsWith("[]");
-        }
-
-        @Override
-        public boolean isPrimitive() {
-            return mName.indexOf('.') != -1;
-        }
-
-        @Override
-        public boolean matchesSignature(@NonNull String signature) {
-            return matchesName(signature);
-        }
-
-        @Override
-        public String toString() {
-            return getSignature();
-        }
-
-        @Override
-        @Nullable
-        public ResolvedClass getTypeClass() {
-            return null;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            DefaultTypeDescriptor that = (DefaultTypeDescriptor) o;
-
-            return !(mName != null ? !mName.equals(that.mName) : that.mName != null);
-
-        }
-
-        @Override
-        public int hashCode() {
-            return mName != null ? mName.hashCode() : 0;
-        }
-    }
-
-    /**
-     * A resolved declaration from an AST Node reference
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @SuppressWarnings("unused")
-    @Deprecated
-    public abstract static class ResolvedNode {
-        @NonNull
-        public abstract String getName();
-
-        /** Returns the signature of the resolved node */
-        public abstract String getSignature();
-
-        public abstract int getModifiers();
-
-        @Override
-        public String toString() {
-            return getSignature();
-        }
-
-        /** Returns any annotations defined on this node */
-        @NonNull
-        public abstract Iterable<ResolvedAnnotation> getAnnotations();
-
-        /**
-         * Searches for the annotation of the given type on this node
-         *
-         * @param type the fully qualified name of the annotation to check
-         * @return the annotation, or null if not found
-         */
-        @Nullable
-        public ResolvedAnnotation getAnnotation(@NonNull String type) {
-            for (ResolvedAnnotation annotation : getAnnotations()) {
-                if (annotation.getType().matchesSignature(type)) {
-                    return annotation;
-                }
-            }
-
-            return null;
-        }
-
-        /**
-         * Returns true if this element is in the given package (or optionally, in one of its sub
-         * packages)
-         *
-         * @param pkg                the package name
-         * @param includeSubPackages whether to include subpackages
-         * @return true if the element is in the given package
-         */
-        public boolean isInPackage(@NonNull String pkg, boolean includeSubPackages) {
-            return getSignature().startsWith(pkg);
-        }
-
-        /**
-         * Attempts to find the corresponding AST node, if possible. This won't work if for example
-         * the resolved node is from a binary (such as a compiled class in a .jar) or if the
-         * underlying parser doesn't support it.
-         * <p>
-         * Note that looking up the AST node can result in different instances for each lookup.
-         *
-         * @return an AST node, if possible.
-         */
-        @Nullable
-        public Node findAstNode() {
-            return null;
-        }
-    }
-
-    /**
-     * A resolved class declaration (class, interface, enumeration or annotation)
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @SuppressWarnings("unused")
-    @Deprecated
-    public abstract static class ResolvedClass extends ResolvedNode {
-        /** Returns the fully qualified name of this class */
-        @Override
-        @NonNull
-        public abstract String getName();
-
-        /** Returns the simple name of this class */
-        @NonNull
-        public abstract String getSimpleName();
-
-        /** Returns the package name of this class */
-        @NonNull
-        public String getPackageName() {
-            String name = getName();
-            String simpleName = getSimpleName();
-            if (name.length() > simpleName.length() + 1) {
-                return name.substring(0, name.length() - simpleName.length() - 1);
-            }
-            return name;
-        }
-
-        /** Returns whether this class' fully qualified name matches the given name */
-        public abstract boolean matches(@NonNull String name);
-
-        @Nullable
-        public abstract ResolvedClass getSuperClass();
-
-        @NonNull
-        public abstract Iterable<ResolvedClass> getInterfaces();
-
-        @Nullable
-        public abstract ResolvedClass getContainingClass();
-
-        public abstract boolean isInterface();
-        public abstract boolean isEnum();
-
-        public TypeDescriptor getType() {
-            return new DefaultTypeDescriptor(getName());
-        }
-
-        /**
-         * Determines whether this class extends the given name. If strict is true,
-         * it will not consider C extends C true.
-         * <p>
-         * The target must be a class; to check whether this class extends an interface,
-         * use {@link #isImplementing(String,boolean)} instead. If you're not sure, use
-         * {@link #isInheritingFrom(String, boolean)}.
-         *
-         * @param name the fully qualified class name
-         * @param strict if true, do not consider a class to be extending itself
-         * @return true if this class extends the given class
-         */
-        public abstract boolean isSubclassOf(@NonNull String name, boolean strict);
-
-        /**
-         * Determines whether this is implementing the given interface.
-         * <p>
-         * The target must be an interface; to check whether this class extends a class,
-         * use {@link #isSubclassOf(String, boolean)} instead. If you're not sure, use
-         * {@link #isInheritingFrom(String, boolean)}.
-         *
-         * @param name the fully qualified interface name
-         * @param strict if true, do not consider a class to be extending itself
-         * @return true if this class implements the given interface
-         */
-        public abstract boolean isImplementing(@NonNull String name, boolean strict);
-
-        /**
-         * Determines whether this class extends or implements the class of the given name.
-         * If strict is true, it will not consider C extends C true.
-         * <p>
-         * For performance reasons, if you know that the target is a class, consider using
-         * {@link #isSubclassOf(String, boolean)} instead, and if the target is an interface,
-         * consider using {@link #isImplementing(String,boolean)}.
-         *
-         * @param name the fully qualified class name
-         * @param strict if true, do not consider a class to be inheriting from itself
-         * @return true if this class extends or implements the given class
-         */
-        public abstract boolean isInheritingFrom(@NonNull String name, boolean strict);
-
-        @NonNull
-        public abstract Iterable<ResolvedMethod> getConstructors();
-
-        /** Returns the methods defined in this class, and optionally any methods inherited from any superclasses as well */
-        @NonNull
-        public abstract Iterable<ResolvedMethod> getMethods(boolean includeInherited);
-
-        /** Returns the methods of a given name defined in this class, and optionally any methods inherited from any superclasses as well */
-        @NonNull
-        public abstract Iterable<ResolvedMethod> getMethods(@NonNull String name, boolean includeInherited);
-
-        /** Returns the fields defined in this class, and optionally any fields declared in any superclasses as well */
-        @NonNull
-        public abstract Iterable<ResolvedField> getFields(boolean includeInherited);
-
-        /** Returns the named field defined in this class, or optionally inherited from a superclass */
-        @Nullable
-        public abstract ResolvedField getField(@NonNull String name, boolean includeInherited);
-
-        /** Returns the package containing this class */
-        @Nullable
-        public abstract ResolvedPackage getPackage();
-
-        @Override
-        public boolean isInPackage(@NonNull String pkg, boolean includeSubPackages) {
-            String packageName = getPackageName();
-
-            //noinspection SimplifiableIfStatement
-            if (pkg.equals(packageName)) {
-                return true;
-            }
-
-            return includeSubPackages && packageName.length() > pkg.length() &&
-                    packageName.charAt(pkg.length()) == '.' &&
-                    packageName.startsWith(pkg);
-        }
-    }
-
-    /**
-     * A method or constructor declaration
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @SuppressWarnings("unused")
-    @Deprecated
-    public abstract static class ResolvedMethod extends ResolvedNode {
-        @Override
-        @NonNull
-        public abstract String getName();
-
-        /** Returns whether this method name matches the given name */
-        public abstract boolean matches(@NonNull String name);
-
-        @NonNull
-        public abstract ResolvedClass getContainingClass();
-
-        public abstract int getArgumentCount();
-
-        @NonNull
-        public abstract TypeDescriptor getArgumentType(int index);
-
-        /** Returns true if the parameter at the given index matches the given type signature */
-        public boolean argumentMatchesType(int index, @NonNull String signature) {
-            return getArgumentType(index).matchesSignature(signature);
-        }
-
-        @Nullable
-        public abstract TypeDescriptor getReturnType();
-
-        public boolean isConstructor() {
-            return getReturnType() == null;
-        }
-
-        /** Returns any annotations defined on the given parameter of this method */
-        @NonNull
-        public abstract Iterable<ResolvedAnnotation> getParameterAnnotations(int index);
-
-        /**
-         * Searches for the annotation of the given type on the method
-         *
-         * @param type the fully qualified name of the annotation to check
-         * @param parameterIndex the index of the parameter to look up
-         * @return the annotation, or null if not found
-         */
-        @Nullable
-        public ResolvedAnnotation getParameterAnnotation(@NonNull String type,
-                int parameterIndex) {
-            for (ResolvedAnnotation annotation : getParameterAnnotations(parameterIndex)) {
-                if (annotation.getType().matchesSignature(type)) {
-                    return annotation;
-                }
-            }
-
-            return null;
-        }
-
-        /** Returns the super implementation of the given method, if any */
-        @Nullable
-        public ResolvedMethod getSuperMethod() {
-            if ((getModifiers() & Modifier.PRIVATE) != 0) {
-                // Private methods aren't overriding anything
-                return null;
-            }
-            ResolvedClass cls = getContainingClass().getSuperClass();
-            if (cls != null) {
-                String methodName = getName();
-                int argCount = getArgumentCount();
-                for (ResolvedMethod method : cls.getMethods(methodName, true)) {
-                    if (argCount != method.getArgumentCount()) {
-                        continue;
-                    }
-                    boolean sameTypes = true;
-                    for (int arg = 0; arg < argCount; arg++) {
-                        if (!method.getArgumentType(arg).equals(getArgumentType(arg))) {
-                            sameTypes = false;
-                            break;
-                        }
-                    }
-                    if (sameTypes) {
-                        if ((method.getModifiers() & Modifier.PRIVATE) != 0) {
-                            // Normally can't override private methods - unless they're
-                            // in the same compilation unit where the compiler will create
-                            // an accessor method to trampoline over to it.
-                            //
-                            // Compare compilation units:
-                            if (haveSameCompilationUnit(getContainingClass(),
-                                    method.getContainingClass())) {
-                                return method;
-                            } else {
-                                // We can stop the search; this is invalid (you can't have a
-                                // private method in the middle of a chain; the compiler would
-                                // complain about weaker access)
-                                return null;
-                            }
-                        }
-                        return method;
-                    }
-                }
-            }
-
-            return null;
-        }
-
-        @Override
-        public boolean isInPackage(@NonNull String pkg, boolean includeSubPackages) {
-            String packageName = getContainingClass().getPackageName();
-
-            //noinspection SimplifiableIfStatement
-            if (pkg.equals(packageName)) {
-                return true;
-            }
-
-            return includeSubPackages && packageName.length() > pkg.length() &&
-                    packageName.charAt(pkg.length()) == '.' &&
-                    packageName.startsWith(pkg);
-        }
-    }
-
-    /**
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    private static boolean haveSameCompilationUnit(@Nullable ResolvedClass cls1,
-            @Nullable ResolvedClass cls2) {
-        if (cls1 == null || cls2 == null) {
-            return false;
-        }
-        //noinspection ConstantConditions
-        while (cls1.getContainingClass() != null) {
-            cls1 = cls1.getContainingClass();
-        }
-        //noinspection ConstantConditions
-        while (cls2.getContainingClass() != null) {
-            cls2 = cls2.getContainingClass();
-        }
-        return cls1.equals(cls2);
-    }
-
-    /**
-     * A field declaration
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    public abstract static class ResolvedField extends ResolvedNode {
-        @Override
-        @NonNull
-        public abstract String getName();
-
-        /** Returns whether this field name matches the given name */
-        public abstract boolean matches(@NonNull String name);
-
-        @NonNull
-        public abstract TypeDescriptor getType();
-
-        @Nullable
-        public abstract ResolvedClass getContainingClass();
-
-        @Nullable
-        public abstract Object getValue();
-
-        @Nullable
-        public String getContainingClassName() {
-            ResolvedClass containingClass = getContainingClass();
-            return containingClass != null ? containingClass.getName() : null;
-        }
-
-        @Override
-        public boolean isInPackage(@NonNull String pkg, boolean includeSubPackages) {
-            ResolvedClass containingClass = getContainingClass();
-            if (containingClass == null) {
-                return false;
-            }
-
-            String packageName = containingClass.getPackageName();
-
-            //noinspection SimplifiableIfStatement
-            if (pkg.equals(packageName)) {
-                return true;
-            }
-
-            return includeSubPackages && packageName.length() > pkg.length() &&
-                   packageName.charAt(pkg.length()) == '.' &&
-                   packageName.startsWith(pkg);
-        }
-    }
-
-    /**
-     * An annotation <b>reference</b>. Note that this refers to a usage of an annotation,
-     * not a declaraton of an annotation. You can call {@link #getClassType()} to
-     * find the declaration for the annotation.
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    public abstract static class ResolvedAnnotation extends ResolvedNode {
-        @Override
-        @NonNull
-        public abstract String getName();
-
-        /** Returns whether this field name matches the given name */
-        public abstract boolean matches(@NonNull String name);
-
-        @NonNull
-        public abstract TypeDescriptor getType();
-
-        /** Returns the {@link ResolvedClass} which defines the annotation */
-        @Nullable
-        public abstract ResolvedClass getClassType();
-
-        public static class Value {
-            @NonNull public final String name;
-            @Nullable public final Object value;
-
-            public Value(@NonNull String name, @Nullable Object value) {
-                this.name = name;
-                this.value = value;
-            }
-        }
-
-        @NonNull
-        public abstract List<Value> getValues();
-
-        @Nullable
-        public Object getValue(@NonNull String name) {
-            for (Value value : getValues()) {
-                if (name.equals(value.name)) {
-                    return value.value;
-                }
-            }
-            return null;
-        }
-
-        @Nullable
-        public Object getValue() {
-            return getValue(ATTR_VALUE);
-        }
-
-        @NonNull
-        @Override
-        public Iterable<ResolvedAnnotation> getAnnotations() {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * A package declaration
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @SuppressWarnings("unused")
-    @Deprecated
-    public abstract static class ResolvedPackage extends ResolvedNode {
-        /** Returns the parent package of this package, if any. */
-        @Nullable
-        public abstract ResolvedPackage getParentPackage();
-
-        @NonNull
-        @Override
-        public Iterable<ResolvedAnnotation> getAnnotations() {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * A local variable or parameter declaration
-     * @deprecated Use {@link JavaPsiScanner} APIs instead
-     */
-    @Deprecated
-    public abstract static class ResolvedVariable extends ResolvedNode {
-        @Override
-        @NonNull
-        public abstract String getName();
-
-        /** Returns whether this variable name matches the given name */
-        public abstract boolean matches(@NonNull String name);
-
-        @NonNull
-        public abstract TypeDescriptor getType();
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaPsiVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaPsiVisitor.java
deleted file mode 100644
index 772ca31..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaPsiVisitor.java
+++ /dev/null
@@ -1,1716 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.R_CLASS;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.psi.ImplicitVariable;
-import com.intellij.psi.JavaElementVisitor;
-import com.intellij.psi.JavaRecursiveElementVisitor;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiAnnotationMethod;
-import com.intellij.psi.PsiAnnotationParameterList;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiArrayAccessExpression;
-import com.intellij.psi.PsiArrayInitializerExpression;
-import com.intellij.psi.PsiArrayInitializerMemberValue;
-import com.intellij.psi.PsiAssertStatement;
-import com.intellij.psi.PsiAssignmentExpression;
-import com.intellij.psi.PsiBinaryExpression;
-import com.intellij.psi.PsiBlockStatement;
-import com.intellij.psi.PsiBreakStatement;
-import com.intellij.psi.PsiCallExpression;
-import com.intellij.psi.PsiCatchSection;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassInitializer;
-import com.intellij.psi.PsiClassObjectAccessExpression;
-import com.intellij.psi.PsiCodeBlock;
-import com.intellij.psi.PsiConditionalExpression;
-import com.intellij.psi.PsiContinueStatement;
-import com.intellij.psi.PsiDeclarationStatement;
-import com.intellij.psi.PsiDoWhileStatement;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiEmptyStatement;
-import com.intellij.psi.PsiEnumConstant;
-import com.intellij.psi.PsiEnumConstantInitializer;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiExpressionList;
-import com.intellij.psi.PsiExpressionListStatement;
-import com.intellij.psi.PsiExpressionStatement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiForStatement;
-import com.intellij.psi.PsiForeachStatement;
-import com.intellij.psi.PsiIdentifier;
-import com.intellij.psi.PsiIfStatement;
-import com.intellij.psi.PsiImportList;
-import com.intellij.psi.PsiImportStatement;
-import com.intellij.psi.PsiImportStaticReferenceElement;
-import com.intellij.psi.PsiImportStaticStatement;
-import com.intellij.psi.PsiInstanceOfExpression;
-import com.intellij.psi.PsiJavaCodeReferenceElement;
-import com.intellij.psi.PsiJavaFile;
-import com.intellij.psi.PsiJavaToken;
-import com.intellij.psi.PsiKeyword;
-import com.intellij.psi.PsiLabeledStatement;
-import com.intellij.psi.PsiLambdaExpression;
-import com.intellij.psi.PsiLiteralExpression;
-import com.intellij.psi.PsiLocalVariable;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiMethodReferenceExpression;
-import com.intellij.psi.PsiModifierList;
-import com.intellij.psi.PsiNameValuePair;
-import com.intellij.psi.PsiNewExpression;
-import com.intellij.psi.PsiPackage;
-import com.intellij.psi.PsiPackageStatement;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiParameterList;
-import com.intellij.psi.PsiParenthesizedExpression;
-import com.intellij.psi.PsiPolyadicExpression;
-import com.intellij.psi.PsiPostfixExpression;
-import com.intellij.psi.PsiPrefixExpression;
-import com.intellij.psi.PsiReceiverParameter;
-import com.intellij.psi.PsiReferenceExpression;
-import com.intellij.psi.PsiReferenceList;
-import com.intellij.psi.PsiReferenceParameterList;
-import com.intellij.psi.PsiResourceList;
-import com.intellij.psi.PsiResourceVariable;
-import com.intellij.psi.PsiReturnStatement;
-import com.intellij.psi.PsiStatement;
-import com.intellij.psi.PsiSuperExpression;
-import com.intellij.psi.PsiSwitchLabelStatement;
-import com.intellij.psi.PsiSwitchStatement;
-import com.intellij.psi.PsiSynchronizedStatement;
-import com.intellij.psi.PsiThisExpression;
-import com.intellij.psi.PsiThrowStatement;
-import com.intellij.psi.PsiTryStatement;
-import com.intellij.psi.PsiTypeCastExpression;
-import com.intellij.psi.PsiTypeElement;
-import com.intellij.psi.PsiTypeParameter;
-import com.intellij.psi.PsiTypeParameterList;
-import com.intellij.psi.PsiVariable;
-import com.intellij.psi.PsiWhileStatement;
-import com.intellij.psi.javadoc.PsiDocComment;
-import com.intellij.psi.javadoc.PsiDocTag;
-import com.intellij.psi.javadoc.PsiDocTagValue;
-import com.intellij.psi.javadoc.PsiDocToken;
-import com.intellij.psi.javadoc.PsiInlineDocTag;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Specialized visitor for running detectors on a Java AST.
- * It operates in three phases:
- * <ol>
- *   <li> First, it computes a set of maps where it generates a map from each
- *        significant AST attribute (such as method call names) to a list
- *        of detectors to consult whenever that attribute is encountered.
- *        Examples of "attributes" are method names, Android resource identifiers,
- *        and general AST node types such as "cast" nodes etc. These are
- *        defined on the {@link JavaPsiScanner} interface.
- *   <li> Second, it iterates over the document a single time, delegating to
- *        the detectors found at each relevant AST attribute.
- *   <li> Finally, it calls the remaining visitors (those that need to process a
- *        whole document on their own).
- * </ol>
- * It also notifies all the detectors before and after the document is processed
- * such that they can do pre- and post-processing.
- */
-public class JavaPsiVisitor {
-    /** Default size of lists holding detectors of the same type for a given node type */
-    private static final int SAME_TYPE_COUNT = 8;
-
-    private final Map<String, List<VisitingDetector>> mMethodDetectors =
-            Maps.newHashMapWithExpectedSize(80);
-    private final Map<String, List<VisitingDetector>> mConstructorDetectors =
-            Maps.newHashMapWithExpectedSize(12);
-    private final Map<String, List<VisitingDetector>> mReferenceDetectors =
-            Maps.newHashMapWithExpectedSize(10);
-    private Set<String> mConstructorSimpleNames;
-    private final List<VisitingDetector> mResourceFieldDetectors =
-            new ArrayList<VisitingDetector>();
-    private final List<VisitingDetector> mAllDetectors;
-    private final List<VisitingDetector> mFullTreeDetectors;
-    private final Map<Class<? extends PsiElement>, List<VisitingDetector>> mNodePsiTypeDetectors =
-            new HashMap<Class<? extends PsiElement>, List<VisitingDetector>>(16);
-    private final JavaParser mParser;
-    private final Map<String, List<VisitingDetector>> mSuperClassDetectors =
-            new HashMap<String, List<VisitingDetector>>();
-
-    /**
-     * Number of fatal exceptions (internal errors, usually from ECJ) we've
-     * encountered; we don't log each and every one to avoid massive log spam
-     * in code which triggers this condition
-     */
-    private static int sExceptionCount;
-    /** Max number of logs to include */
-    private static final int MAX_REPORTED_CRASHES = 20;
-
-    JavaPsiVisitor(@NonNull JavaParser parser, @NonNull List<Detector> detectors) {
-        mParser = parser;
-        mAllDetectors = new ArrayList<VisitingDetector>(detectors.size());
-        mFullTreeDetectors = new ArrayList<VisitingDetector>(detectors.size());
-
-        for (Detector detector : detectors) {
-            JavaPsiScanner javaPsiScanner = (JavaPsiScanner) detector;
-            VisitingDetector v = new VisitingDetector(detector, javaPsiScanner);
-            mAllDetectors.add(v);
-
-            List<String> applicableSuperClasses = detector.applicableSuperClasses();
-            if (applicableSuperClasses != null) {
-                for (String fqn : applicableSuperClasses) {
-                    List<VisitingDetector> list = mSuperClassDetectors.get(fqn);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mSuperClassDetectors.put(fqn, list);
-                    }
-                    list.add(v);
-                }
-                continue;
-            }
-
-            List<Class<? extends PsiElement>> nodePsiTypes = detector.getApplicablePsiTypes();
-            if (nodePsiTypes != null) {
-                for (Class<? extends PsiElement> type : nodePsiTypes) {
-                    List<VisitingDetector> list = mNodePsiTypeDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mNodePsiTypeDetectors.put(type, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> names = detector.getApplicableMethodNames();
-            if (names != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert names != XmlScanner.ALL;
-
-                for (String name : names) {
-                    List<VisitingDetector> list = mMethodDetectors.get(name);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mMethodDetectors.put(name, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> types = detector.getApplicableConstructorTypes();
-            if (types != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert types != XmlScanner.ALL;
-                if (mConstructorSimpleNames == null) {
-                    mConstructorSimpleNames = Sets.newHashSet();
-                }
-                for (String type : types) {
-                    List<VisitingDetector> list = mConstructorDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mConstructorDetectors.put(type, list);
-                        mConstructorSimpleNames.add(type.substring(type.lastIndexOf('.')+1));
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> referenceNames = detector.getApplicableReferenceNames();
-            if (referenceNames != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert referenceNames != XmlScanner.ALL;
-
-                for (String name : referenceNames) {
-                    List<VisitingDetector> list = mReferenceDetectors.get(name);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mReferenceDetectors.put(name, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            if (detector.appliesToResourceRefs()) {
-                mResourceFieldDetectors.add(v);
-            } else if ((referenceNames == null || referenceNames.isEmpty())
-                    && (nodePsiTypes == null || nodePsiTypes.isEmpty())
-                    && (types == null || types.isEmpty())) {
-                mFullTreeDetectors.add(v);
-            }
-        }
-    }
-
-    void visitFile(@NonNull final JavaContext context) {
-        try {
-            final PsiJavaFile javaFile = mParser.parseJavaToPsi(context);
-            if (javaFile == null) {
-                // No need to log this; the parser should be reporting
-                // a full warning (such as IssueRegistry#PARSER_ERROR)
-                // with details, location, etc.
-                return;
-            }
-            try {
-                context.setJavaFile(javaFile);
-
-                mParser.runReadAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        for (VisitingDetector v : mAllDetectors) {
-                            v.setContext(context);
-                            v.getDetector().beforeCheckFile(context);
-                        }
-                    }
-                });
-
-                if (!mSuperClassDetectors.isEmpty()) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            SuperclassPsiVisitor visitor = new SuperclassPsiVisitor(context);
-                            javaFile.accept(visitor);
-                        }
-                    });
-                }
-
-                for (final VisitingDetector v : mFullTreeDetectors) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            JavaElementVisitor visitor = v.getVisitor();
-                            javaFile.accept(visitor);
-                        }
-                    });
-                }
-
-                if (!mMethodDetectors.isEmpty()
-                        || !mResourceFieldDetectors.isEmpty()
-                        || !mConstructorDetectors.isEmpty()
-                        || !mReferenceDetectors.isEmpty()) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            // TODO: Do we need to break this one up into finer grain
-                            // locking units
-                            JavaElementVisitor visitor = new DelegatingPsiVisitor(context);
-                            javaFile.accept(visitor);
-                        }
-                    });
-                } else {
-                    if (!mNodePsiTypeDetectors.isEmpty()) {
-                        mParser.runReadAction(new Runnable() {
-                            @Override
-                            public void run() {
-                                // TODO: Do we need to break this one up into finer grain
-                                // locking units
-                                JavaElementVisitor visitor = new DispatchPsiVisitor();
-                                javaFile.accept(visitor);
-                            }
-                        });
-                    }
-                }
-
-                mParser.runReadAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        for (VisitingDetector v : mAllDetectors) {
-                            v.getDetector().afterCheckFile(context);
-                        }
-                    }
-                });
-            } finally {
-                mParser.dispose(context, javaFile);
-                context.setJavaFile(null);
-            }
-        } catch (ProcessCanceledException ignore) {
-            // Cancelling inspections in the IDE
-        } catch (RuntimeException e) {
-            if (sExceptionCount++ > MAX_REPORTED_CRASHES) {
-                // No need to keep spamming the user that a lot of the files
-                // are tripping up ECJ, they get the picture.
-                return;
-            }
-
-            if (e.getClass().getSimpleName().equals("IndexNotReadyException")) {
-                // Attempting to access PSI during startup before indices are ready; ignore these.
-                // See http://b.android.com/176644 for an example.
-                return;
-            }
-
-            // Work around ECJ bugs; see https://code.google.com/p/android/issues/detail?id=172268
-            // Don't allow lint bugs to take down the whole build. TRY to log this as a
-            // lint error instead!
-            StringBuilder sb = new StringBuilder(100);
-            sb.append("Unexpected failure during lint analysis of ");
-            sb.append(context.file.getName());
-            sb.append(" (this is a bug in lint or one of the libraries it depends on)\n");
-
-            sb.append(e.getClass().getSimpleName());
-            sb.append(':');
-            StackTraceElement[] stackTrace = e.getStackTrace();
-            int count = 0;
-            for (StackTraceElement frame : stackTrace) {
-                if (count > 0) {
-                    sb.append("<-");
-                }
-
-                String className = frame.getClassName();
-                sb.append(className.substring(className.lastIndexOf('.') + 1));
-                sb.append('.').append(frame.getMethodName());
-                sb.append('(');
-                sb.append(frame.getFileName()).append(':').append(frame.getLineNumber());
-                sb.append(')');
-                count++;
-                // Only print the top 3-4 frames such that we can identify the bug
-                if (count == 4) {
-                    break;
-                }
-            }
-            Throwable throwable = null; // NOT e: this makes for very noisy logs
-            //noinspection ConstantConditions
-            context.log(throwable, sb.toString());
-        }
-    }
-
-    /**
-     * For testing only: returns the number of exceptions thrown during Java AST analysis
-     *
-     * @return the number of internal errors found
-     */
-    @VisibleForTesting
-    public static int getCrashCount() {
-        return sExceptionCount;
-    }
-
-    /**
-     * For testing only: clears the crash counter
-     */
-    @VisibleForTesting
-    public static void clearCrashCount() {
-        sExceptionCount = 0;
-    }
-
-    public void prepare(@NonNull List<JavaContext> contexts) {
-        mParser.prepareJavaParse(contexts);
-    }
-
-    public void dispose() {
-        mParser.dispose();
-    }
-
-    @Nullable
-    private static Set<String> getInterfaceNames(
-            @Nullable Set<String> addTo,
-            @NonNull PsiClass cls) {
-        for (PsiClass resolvedInterface : cls.getInterfaces()) {
-            String name = resolvedInterface.getQualifiedName();
-            if (addTo == null) {
-                addTo = Sets.newHashSet();
-            } else if (addTo.contains(name)) {
-                // Superclasses can explicitly implement the same interface,
-                // so keep track of visited interfaces as we traverse up the
-                // super class chain to avoid checking the same interface
-                // more than once.
-                continue;
-            }
-            addTo.add(name);
-            getInterfaceNames(addTo, resolvedInterface);
-        }
-
-        return addTo;
-    }
-
-    private static class VisitingDetector {
-        private JavaElementVisitor mVisitor;
-        private JavaContext mContext;
-        public final Detector mDetector;
-        public final JavaPsiScanner mJavaScanner;
-
-        public VisitingDetector(@NonNull Detector detector, @NonNull JavaPsiScanner javaScanner) {
-            mDetector = detector;
-            mJavaScanner = javaScanner;
-        }
-
-        @NonNull
-        public Detector getDetector() {
-            return mDetector;
-        }
-
-        @Nullable
-        public JavaPsiScanner getJavaScanner() {
-            return mJavaScanner;
-        }
-
-        public void setContext(@NonNull JavaContext context) {
-            mContext = context;
-
-            // The visitors are one-per-context, so clear them out here and construct
-            // lazily only if needed
-            mVisitor = null;
-        }
-
-        @NonNull
-        JavaElementVisitor getVisitor() {
-            if (mVisitor == null) {
-                mVisitor = mDetector.createPsiVisitor(mContext);
-                assert !(mVisitor instanceof JavaRecursiveElementVisitor) :
-                        "Your visitor (returned by " + mDetector.getClass().getSimpleName()
-                        + "#createPsiVisitor(...) should *not* extend "
-                        + " JavaRecursiveElementVisitor; use a plain "
-                        + "JavaElementVisitor instead. The lint infrastructure does its own "
-                        + "recursion calling *just* your visit methods specified in "
-                        + "getApplicablePsiTypes";
-                if (mVisitor == null) {
-                    mVisitor = new JavaElementVisitor() {
-                        @Override
-                        public void visitElement(PsiElement element) {
-                            // No-op. Workaround for super currently calling
-                            //   ProgressIndicatorProvider.checkCanceled();
-                        }
-                    };
-                }
-            }
-            return mVisitor;
-        }
-    }
-
-    private class SuperclassPsiVisitor extends JavaRecursiveElementVisitor {
-        private JavaContext mContext;
-
-        public SuperclassPsiVisitor(@NonNull JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public void visitClass(@NonNull PsiClass node) {
-            super.visitClass(node);
-            checkClass(node);
-        }
-
-        private void checkClass(@NonNull PsiClass node) {
-            if (node instanceof PsiTypeParameter) {
-                // Not included: explained in javadoc for JavaPsiScanner#checkClass
-                return;
-            }
-
-            PsiClass cls = node;
-            int depth = 0;
-            while (cls != null) {
-                List<VisitingDetector> list = mSuperClassDetectors.get(cls.getQualifiedName());
-                if (list != null) {
-                    for (VisitingDetector v : list) {
-                        JavaPsiScanner javaPsiScanner = v.getJavaScanner();
-                        if (javaPsiScanner != null) {
-                            javaPsiScanner.checkClass(mContext, node);
-                        }
-                    }
-                }
-
-                // Check interfaces too
-                Set<String> interfaceNames = getInterfaceNames(null, cls);
-                if (interfaceNames != null) {
-                    for (String name : interfaceNames) {
-                        list = mSuperClassDetectors.get(name);
-                        if (list != null) {
-                            for (VisitingDetector v : list) {
-                                JavaPsiScanner javaPsiScanner = v.getJavaScanner();
-                                if (javaPsiScanner != null) {
-                                    javaPsiScanner.checkClass(mContext, node);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                cls = cls.getSuperClass();
-                depth++;
-                if (depth == 500) {
-                    // Shouldn't happen in practice; this prevents the IDE from
-                    // hanging if the user has accidentally typed in an incorrect
-                    // super class which creates a cycle.
-                    break;
-                }
-            }
-        }
-    }
-
-    private class DispatchPsiVisitor extends JavaRecursiveElementVisitor {
-
-        @Override
-        public void visitAnonymousClass(PsiAnonymousClass node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiAnonymousClass.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnonymousClass(node);
-                }
-            }
-            super.visitAnonymousClass(node);
-        }
-
-        @Override
-        public void visitArrayAccessExpression(PsiArrayAccessExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiArrayAccessExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayAccessExpression(node);
-                }
-            }
-            super.visitArrayAccessExpression(node);
-        }
-
-        @Override
-        public void visitArrayInitializerExpression(PsiArrayInitializerExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiArrayInitializerExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayInitializerExpression(node);
-                }
-            }
-            super.visitArrayInitializerExpression(node);
-        }
-
-        @Override
-        public void visitAssertStatement(PsiAssertStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiAssertStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAssertStatement(node);
-                }
-            }
-            super.visitAssertStatement(node);
-        }
-
-        @Override
-        public void visitAssignmentExpression(PsiAssignmentExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiAssignmentExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAssignmentExpression(node);
-                }
-            }
-            super.visitAssignmentExpression(node);
-        }
-
-        @Override
-        public void visitBinaryExpression(PsiBinaryExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiBinaryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBinaryExpression(node);
-                }
-            }
-            super.visitBinaryExpression(node);
-        }
-
-        @Override
-        public void visitBlockStatement(PsiBlockStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiBlockStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBlockStatement(node);
-                }
-            }
-            super.visitBlockStatement(node);
-        }
-
-        @Override
-        public void visitBreakStatement(PsiBreakStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiBreakStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBreakStatement(node);
-                }
-            }
-            super.visitBreakStatement(node);
-        }
-
-        @Override
-        public void visitClass(PsiClass node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiClass.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClass(node);
-                }
-            }
-            super.visitClass(node);
-        }
-
-        @Override
-        public void visitClassInitializer(PsiClassInitializer node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiClassInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClassInitializer(node);
-                }
-            }
-            super.visitClassInitializer(node);
-        }
-
-        @Override
-        public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiClassObjectAccessExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClassObjectAccessExpression(node);
-                }
-            }
-            super.visitClassObjectAccessExpression(node);
-        }
-
-        @Override
-        public void visitCodeBlock(PsiCodeBlock node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiCodeBlock.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCodeBlock(node);
-                }
-            }
-            super.visitCodeBlock(node);
-        }
-
-        @Override
-        public void visitConditionalExpression(PsiConditionalExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiConditionalExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitConditionalExpression(node);
-                }
-            }
-            super.visitConditionalExpression(node);
-        }
-
-        @Override
-        public void visitContinueStatement(PsiContinueStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiContinueStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitContinueStatement(node);
-                }
-            }
-            super.visitContinueStatement(node);
-        }
-
-        @Override
-        public void visitDeclarationStatement(PsiDeclarationStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDeclarationStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDeclarationStatement(node);
-                }
-            }
-            super.visitDeclarationStatement(node);
-        }
-
-        @Override
-        public void visitDocComment(PsiDocComment node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDocComment.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDocComment(node);
-                }
-            }
-            super.visitDocComment(node);
-        }
-
-        @Override
-        public void visitDocTag(PsiDocTag node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDocTag.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDocTag(node);
-                }
-            }
-            super.visitDocTag(node);
-        }
-
-        @Override
-        public void visitDocTagValue(PsiDocTagValue node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDocTagValue.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDocTagValue(node);
-                }
-            }
-            super.visitDocTagValue(node);
-        }
-
-        @Override
-        public void visitDoWhileStatement(PsiDoWhileStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDoWhileStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDoWhileStatement(node);
-                }
-            }
-            super.visitDoWhileStatement(node);
-        }
-
-        @Override
-        public void visitEmptyStatement(PsiEmptyStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiEmptyStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEmptyStatement(node);
-                }
-            }
-            super.visitEmptyStatement(node);
-        }
-
-        @Override
-        public void visitExpression(PsiExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpression(node);
-                }
-            }
-            super.visitExpression(node);
-        }
-
-        @Override
-        public void visitExpressionList(PsiExpressionList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiExpressionList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpressionList(node);
-                }
-            }
-            super.visitExpressionList(node);
-        }
-
-        @Override
-        public void visitExpressionListStatement(PsiExpressionListStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiExpressionListStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpressionListStatement(node);
-                }
-            }
-            super.visitExpressionListStatement(node);
-        }
-
-        @Override
-        public void visitExpressionStatement(PsiExpressionStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiExpressionStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpressionStatement(node);
-                }
-            }
-            super.visitExpressionStatement(node);
-        }
-
-        @Override
-        public void visitField(PsiField node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiField.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitField(node);
-                }
-            }
-            super.visitField(node);
-        }
-
-        @Override
-        public void visitForStatement(PsiForStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiForStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitForStatement(node);
-                }
-            }
-            super.visitForStatement(node);
-        }
-
-        @Override
-        public void visitForeachStatement(PsiForeachStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiForeachStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitForeachStatement(node);
-                }
-            }
-            super.visitForeachStatement(node);
-        }
-
-        @Override
-        public void visitIdentifier(PsiIdentifier node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiIdentifier.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIdentifier(node);
-                }
-            }
-            super.visitIdentifier(node);
-        }
-
-        @Override
-        public void visitIfStatement(PsiIfStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiIfStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIfStatement(node);
-                }
-            }
-            super.visitIfStatement(node);
-        }
-
-        @Override
-        public void visitImportList(PsiImportList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiImportList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportList(node);
-                }
-            }
-            super.visitImportList(node);
-        }
-
-        @Override
-        public void visitImportStatement(PsiImportStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiImportStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportStatement(node);
-                }
-            }
-            super.visitImportStatement(node);
-        }
-
-        @Override
-        public void visitImportStaticStatement(PsiImportStaticStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiImportStaticStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportStaticStatement(node);
-                }
-            }
-            super.visitImportStaticStatement(node);
-        }
-
-        @Override
-        public void visitInlineDocTag(PsiInlineDocTag node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiInlineDocTag.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInlineDocTag(node);
-                }
-            }
-            super.visitInlineDocTag(node);
-        }
-
-        @Override
-        public void visitInstanceOfExpression(PsiInstanceOfExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiInstanceOfExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInstanceOfExpression(node);
-                }
-            }
-            super.visitInstanceOfExpression(node);
-        }
-
-        @Override
-        public void visitJavaToken(PsiJavaToken node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiJavaToken.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitJavaToken(node);
-                }
-            }
-            super.visitJavaToken(node);
-        }
-
-        @Override
-        public void visitKeyword(PsiKeyword node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiKeyword.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitKeyword(node);
-                }
-            }
-            super.visitKeyword(node);
-        }
-
-        @Override
-        public void visitLabeledStatement(PsiLabeledStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiLabeledStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLabeledStatement(node);
-                }
-            }
-            super.visitLabeledStatement(node);
-        }
-
-        @Override
-        public void visitLiteralExpression(PsiLiteralExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiLiteralExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLiteralExpression(node);
-                }
-            }
-            super.visitLiteralExpression(node);
-        }
-
-        @Override
-        public void visitLocalVariable(PsiLocalVariable node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiLocalVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLocalVariable(node);
-                }
-            }
-            super.visitLocalVariable(node);
-        }
-
-        @Override
-        public void visitMethod(PsiMethod node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiMethod.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethod(node);
-                }
-            }
-            super.visitMethod(node);
-        }
-
-        @Override
-        public void visitMethodCallExpression(PsiMethodCallExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiMethodCallExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethodCallExpression(node);
-                }
-            }
-            super.visitMethodCallExpression(node);
-        }
-
-        @Override
-        public void visitCallExpression(PsiCallExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiCallExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCallExpression(node);
-                }
-            }
-            super.visitCallExpression(node);
-        }
-
-        @Override
-        public void visitModifierList(PsiModifierList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiModifierList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitModifierList(node);
-                }
-            }
-            super.visitModifierList(node);
-        }
-
-        @Override
-        public void visitNewExpression(PsiNewExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiNewExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitNewExpression(node);
-                }
-            }
-            super.visitNewExpression(node);
-        }
-
-        @Override
-        public void visitPackage(PsiPackage node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiPackage.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPackage(node);
-                }
-            }
-            super.visitPackage(node);
-        }
-
-        @Override
-        public void visitPackageStatement(PsiPackageStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiPackageStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPackageStatement(node);
-                }
-            }
-            super.visitPackageStatement(node);
-        }
-
-        @Override
-        public void visitParameter(PsiParameter node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiParameter.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitParameter(node);
-                }
-            }
-            super.visitParameter(node);
-        }
-
-        @Override
-        public void visitReceiverParameter(PsiReceiverParameter node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiReceiverParameter.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReceiverParameter(node);
-                }
-            }
-            super.visitReceiverParameter(node);
-        }
-
-        @Override
-        public void visitParameterList(PsiParameterList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiParameterList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitParameterList(node);
-                }
-            }
-            super.visitParameterList(node);
-        }
-
-        @Override
-        public void visitParenthesizedExpression(PsiParenthesizedExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiParenthesizedExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitParenthesizedExpression(node);
-                }
-            }
-            super.visitParenthesizedExpression(node);
-        }
-
-        @Override
-        public void visitPostfixExpression(PsiPostfixExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiPostfixExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPostfixExpression(node);
-                }
-            }
-            super.visitPostfixExpression(node);
-        }
-
-        @Override
-        public void visitPrefixExpression(PsiPrefixExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiPrefixExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPrefixExpression(node);
-                }
-            }
-            super.visitPrefixExpression(node);
-        }
-
-        @Override
-        public void visitReferenceElement(PsiJavaCodeReferenceElement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiJavaCodeReferenceElement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReferenceElement(node);
-                }
-            }
-            super.visitReferenceElement(node);
-        }
-
-        @Override
-        public void visitImportStaticReferenceElement(PsiImportStaticReferenceElement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiImportStaticReferenceElement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportStaticReferenceElement(node);
-                }
-            }
-            super.visitImportStaticReferenceElement(node);
-        }
-
-        @Override
-        public void visitReferenceExpression(PsiReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReferenceExpression(node);
-                }
-            }
-            super.visitReferenceExpression(node);
-        }
-
-        @Override
-        public void visitMethodReferenceExpression(PsiMethodReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiMethodReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethodReferenceExpression(node);
-                }
-            }
-            super.visitMethodReferenceExpression(node);
-        }
-
-        @Override
-        public void visitReferenceList(PsiReferenceList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiReferenceList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReferenceList(node);
-                }
-            }
-            super.visitReferenceList(node);
-        }
-
-        @Override
-        public void visitReferenceParameterList(PsiReferenceParameterList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiReferenceParameterList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReferenceParameterList(node);
-                }
-            }
-            super.visitReferenceParameterList(node);
-        }
-
-        @Override
-        public void visitTypeParameterList(PsiTypeParameterList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiTypeParameterList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeParameterList(node);
-                }
-            }
-            super.visitTypeParameterList(node);
-        }
-
-        @Override
-        public void visitReturnStatement(PsiReturnStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiReturnStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReturnStatement(node);
-                }
-            }
-            super.visitReturnStatement(node);
-        }
-
-        @Override
-        public void visitStatement(PsiStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitStatement(node);
-                }
-            }
-            super.visitStatement(node);
-        }
-
-        @Override
-        public void visitSuperExpression(PsiSuperExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiSuperExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSuperExpression(node);
-                }
-            }
-            super.visitSuperExpression(node);
-        }
-
-        @Override
-        public void visitSwitchLabelStatement(PsiSwitchLabelStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiSwitchLabelStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSwitchLabelStatement(node);
-                }
-            }
-            super.visitSwitchLabelStatement(node);
-        }
-
-        @Override
-        public void visitSwitchStatement(PsiSwitchStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiSwitchStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSwitchStatement(node);
-                }
-            }
-            super.visitSwitchStatement(node);
-        }
-
-        @Override
-        public void visitSynchronizedStatement(PsiSynchronizedStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiSynchronizedStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSynchronizedStatement(node);
-                }
-            }
-            super.visitSynchronizedStatement(node);
-        }
-
-        @Override
-        public void visitThisExpression(PsiThisExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiThisExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThisExpression(node);
-                }
-            }
-            super.visitThisExpression(node);
-        }
-
-        @Override
-        public void visitThrowStatement(PsiThrowStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiThrowStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThrowStatement(node);
-                }
-            }
-            super.visitThrowStatement(node);
-        }
-
-        @Override
-        public void visitTryStatement(PsiTryStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiTryStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTryStatement(node);
-                }
-            }
-            super.visitTryStatement(node);
-        }
-
-        @Override
-        public void visitCatchSection(PsiCatchSection node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiCatchSection.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCatchSection(node);
-                }
-            }
-            super.visitCatchSection(node);
-        }
-
-        @Override
-        public void visitResourceList(PsiResourceList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiResourceList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitResourceList(node);
-                }
-            }
-            super.visitResourceList(node);
-        }
-
-        @Override
-        public void visitResourceVariable(PsiResourceVariable node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiResourceVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitResourceVariable(node);
-                }
-            }
-            super.visitResourceVariable(node);
-        }
-
-        @Override
-        public void visitTypeElement(PsiTypeElement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiTypeElement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeElement(node);
-                }
-            }
-            super.visitTypeElement(node);
-        }
-
-        @Override
-        public void visitTypeCastExpression(PsiTypeCastExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiTypeCastExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeCastExpression(node);
-                }
-            }
-            super.visitTypeCastExpression(node);
-        }
-
-        @Override
-        public void visitVariable(PsiVariable node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariable(node);
-                }
-            }
-            super.visitVariable(node);
-        }
-
-        @Override
-        public void visitWhileStatement(PsiWhileStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiWhileStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitWhileStatement(node);
-                }
-            }
-            super.visitWhileStatement(node);
-        }
-
-        @Override
-        public void visitJavaFile(PsiJavaFile node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiJavaFile.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitJavaFile(node);
-                }
-            }
-            super.visitJavaFile(node);
-        }
-
-        @Override
-        public void visitImplicitVariable(ImplicitVariable node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(ImplicitVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImplicitVariable(node);
-                }
-            }
-            super.visitImplicitVariable(node);
-        }
-
-        @Override
-        public void visitDocToken(PsiDocToken node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiDocToken.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDocToken(node);
-                }
-            }
-            super.visitDocToken(node);
-        }
-
-        @Override
-        public void visitTypeParameter(PsiTypeParameter node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiTypeParameter.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeParameter(node);
-                }
-            }
-            super.visitTypeParameter(node);
-        }
-
-        @Override
-        public void visitAnnotation(PsiAnnotation node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiAnnotation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotation(node);
-                }
-            }
-            super.visitAnnotation(node);
-        }
-
-        @Override
-        public void visitAnnotationParameterList(PsiAnnotationParameterList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiAnnotationParameterList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationParameterList(node);
-                }
-            }
-            super.visitAnnotationParameterList(node);
-        }
-
-        @Override
-        public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiArrayInitializerMemberValue.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationArrayInitializer(node);
-                }
-            }
-            super.visitAnnotationArrayInitializer(node);
-        }
-
-        @Override
-        public void visitNameValuePair(PsiNameValuePair node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiNameValuePair.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitNameValuePair(node);
-                }
-            }
-            super.visitNameValuePair(node);
-        }
-
-        @Override
-        public void visitAnnotationMethod(PsiAnnotationMethod node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiAnnotationMethod.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationMethod(node);
-                }
-            }
-            super.visitAnnotationMethod(node);
-        }
-
-        @Override
-        public void visitEnumConstant(PsiEnumConstant node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiEnumConstant.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEnumConstant(node);
-                }
-            }
-            super.visitEnumConstant(node);
-        }
-
-        @Override
-        public void visitEnumConstantInitializer(PsiEnumConstantInitializer node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors
-                    .get(PsiEnumConstantInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEnumConstantInitializer(node);
-                }
-            }
-            super.visitEnumConstantInitializer(node);
-        }
-
-        @Override
-        public void visitPolyadicExpression(PsiPolyadicExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiPolyadicExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPolyadicExpression(node);
-                }
-            }
-            super.visitPolyadicExpression(node);
-        }
-
-        @Override
-        public void visitLambdaExpression(PsiLambdaExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(PsiLambdaExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLambdaExpression(node);
-                }
-            }
-            super.visitLambdaExpression(node);
-        }
-    }
-
-    /** Performs common AST searches for method calls and R-type-field references.
-     * Note that this is a specialized form of the {@link DispatchPsiVisitor}. */
-    private class DelegatingPsiVisitor extends DispatchPsiVisitor {
-        private final JavaContext mContext;
-        private final boolean mVisitResources;
-        private final boolean mVisitMethods;
-        private final boolean mVisitConstructors;
-        private final boolean mVisitReferences;
-
-        public DelegatingPsiVisitor(JavaContext context) {
-            mContext = context;
-
-            mVisitMethods = !mMethodDetectors.isEmpty();
-            mVisitConstructors = !mConstructorDetectors.isEmpty();
-            mVisitResources = !mResourceFieldDetectors.isEmpty();
-            mVisitReferences = !mReferenceDetectors.isEmpty();
-        }
-
-        @Override
-        public void visitReferenceElement(PsiJavaCodeReferenceElement element) {
-            if (mVisitReferences) {
-                String name = element.getReferenceName();
-                if (name != null) {
-                    List<VisitingDetector> list = mReferenceDetectors.get(name);
-                    if (list != null) {
-                        PsiElement referenced = element.resolve();
-                        if (referenced != null) {
-                            for (VisitingDetector v : list) {
-                                JavaPsiScanner javaPsiScanner = v.getJavaScanner();
-                                if (javaPsiScanner != null) {
-                                    javaPsiScanner.visitReference(mContext, v.getVisitor(),
-                                            element, referenced);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            super.visitReferenceElement(element);
-        }
-
-        @Override
-        public void visitReferenceExpression(PsiReferenceExpression node) {
-            if (mVisitResources) {
-                // R.type.name
-                if (node.getQualifier() instanceof PsiReferenceExpression) {
-                    PsiReferenceExpression select = (PsiReferenceExpression) node.getQualifier();
-                    if (select.getQualifier() instanceof PsiReferenceExpression) {
-                        PsiReferenceExpression reference = (PsiReferenceExpression) select.getQualifier();
-                        if (R_CLASS.equals(reference.getReferenceName())) {
-                            String typeName = select.getReferenceName();
-                            String name = node.getReferenceName();
-
-                            ResourceType type = ResourceType.getEnum(typeName);
-                            if (type != null) {
-                                boolean isFramework =
-                                        reference.getQualifier() instanceof PsiReferenceExpression
-                                        && ANDROID_PKG.equals(((PsiReferenceExpression)reference.
-                                                getQualifier()).getReferenceName());
-
-                                for (VisitingDetector v : mResourceFieldDetectors) {
-                                    JavaPsiScanner detector = v.getJavaScanner();
-                                    if (detector != null) {
-                                        //noinspection ConstantConditions
-                                        detector.visitResourceReference(mContext, v.getVisitor(),
-                                                node, type, name, isFramework);
-                                    }
-                                }
-                            }
-
-                            return;
-                        }
-                    }
-                }
-
-                // Arbitrary packages -- android.R.type.name, foo.bar.R.type.name
-                if (R_CLASS.equals(node.getReferenceName())) {
-                    PsiElement parent = node.getParent();
-                    if (parent instanceof PsiReferenceExpression) {
-                        PsiElement grandParent = parent.getParent();
-                        if (grandParent instanceof PsiReferenceExpression) {
-                            PsiReferenceExpression select = (PsiReferenceExpression) grandParent;
-                            String name = select.getReferenceName();
-                            PsiElement typeOperand = select.getQualifier();
-                            if (name != null && typeOperand instanceof PsiReferenceExpression) {
-                                PsiReferenceExpression typeSelect =
-                                        (PsiReferenceExpression) typeOperand;
-                                String typeName = typeSelect.getReferenceName();
-                                ResourceType type = typeName != null
-                                        ? ResourceType.getEnum(typeName)
-                                        : null;
-                                if (type != null) {
-                                    boolean isFramework = node.getQualifier().getText().equals(
-                                            ANDROID_PKG);
-                                    for (VisitingDetector v : mResourceFieldDetectors) {
-                                        JavaPsiScanner detector = v.getJavaScanner();
-                                        if (detector != null) {
-                                            detector.visitResourceReference(mContext,
-                                                    v.getVisitor(),
-                                                    node, type, name, isFramework);
-                                        }
-                                    }
-                                }
-
-                                return;
-                            }
-                        }
-                    }
-                }
-            }
-
-            super.visitReferenceExpression(node);
-        }
-
-        @Override
-        public void visitMethodCallExpression(PsiMethodCallExpression node) {
-            super.visitMethodCallExpression(node);
-
-            if (mVisitMethods) {
-                String methodName = node.getMethodExpression().getReferenceName();
-                if (methodName != null) {
-                    List<VisitingDetector> list = mMethodDetectors.get(methodName);
-                    if (list != null) {
-                        PsiMethod method = node.resolveMethod();
-                        if (method != null) {
-                            for (VisitingDetector v : list) {
-                                JavaPsiScanner javaPsiScanner = v.getJavaScanner();
-                                if (javaPsiScanner != null) {
-                                    javaPsiScanner.visitMethod(mContext, v.getVisitor(), node,
-                                            method);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void visitNewExpression(PsiNewExpression node) {
-            super.visitNewExpression(node);
-
-            if (mVisitConstructors) {
-                PsiJavaCodeReferenceElement typeReference = node.getClassReference();
-                if (typeReference != null) {
-                    String type = typeReference.getQualifiedName();
-                    if (type != null) {
-                        List<VisitingDetector> list = mConstructorDetectors.get(type);
-                        if (list != null) {
-                            PsiMethod method = node.resolveMethod();
-                            if (method != null) {
-                                for (VisitingDetector v : list) {
-                                    JavaPsiScanner javaPsiScanner = v.getJavaScanner();
-                                    if (javaPsiScanner != null) {
-                                        javaPsiScanner.visitConstructor(mContext,
-                                                v.getVisitor(), node, method);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaVisitor.java
deleted file mode 100644
index f1584b2..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaVisitor.java
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.R_CLASS;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.client.api.JavaParser.ResolvedClass;
-import com.android.tools.klint.client.api.JavaParser.ResolvedMethod;
-import com.android.tools.klint.client.api.JavaParser.ResolvedNode;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaScanner;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import lombok.ast.AlternateConstructorInvocation;
-import lombok.ast.Annotation;
-import lombok.ast.AnnotationDeclaration;
-import lombok.ast.AnnotationElement;
-import lombok.ast.AnnotationMethodDeclaration;
-import lombok.ast.AnnotationValueArray;
-import lombok.ast.ArrayAccess;
-import lombok.ast.ArrayCreation;
-import lombok.ast.ArrayDimension;
-import lombok.ast.ArrayInitializer;
-import lombok.ast.Assert;
-import lombok.ast.AstVisitor;
-import lombok.ast.BinaryExpression;
-import lombok.ast.Block;
-import lombok.ast.BooleanLiteral;
-import lombok.ast.Break;
-import lombok.ast.Case;
-import lombok.ast.Cast;
-import lombok.ast.Catch;
-import lombok.ast.CharLiteral;
-import lombok.ast.ClassDeclaration;
-import lombok.ast.ClassLiteral;
-import lombok.ast.Comment;
-import lombok.ast.CompilationUnit;
-import lombok.ast.ConstructorDeclaration;
-import lombok.ast.ConstructorInvocation;
-import lombok.ast.Continue;
-import lombok.ast.Default;
-import lombok.ast.DoWhile;
-import lombok.ast.EmptyDeclaration;
-import lombok.ast.EmptyStatement;
-import lombok.ast.EnumConstant;
-import lombok.ast.EnumDeclaration;
-import lombok.ast.EnumTypeBody;
-import lombok.ast.Expression;
-import lombok.ast.ExpressionStatement;
-import lombok.ast.FloatingPointLiteral;
-import lombok.ast.For;
-import lombok.ast.ForEach;
-import lombok.ast.ForwardingAstVisitor;
-import lombok.ast.Identifier;
-import lombok.ast.If;
-import lombok.ast.ImportDeclaration;
-import lombok.ast.InlineIfExpression;
-import lombok.ast.InstanceInitializer;
-import lombok.ast.InstanceOf;
-import lombok.ast.IntegralLiteral;
-import lombok.ast.InterfaceDeclaration;
-import lombok.ast.KeywordModifier;
-import lombok.ast.LabelledStatement;
-import lombok.ast.MethodDeclaration;
-import lombok.ast.MethodInvocation;
-import lombok.ast.Modifiers;
-import lombok.ast.Node;
-import lombok.ast.NormalTypeBody;
-import lombok.ast.NullLiteral;
-import lombok.ast.PackageDeclaration;
-import lombok.ast.Return;
-import lombok.ast.Select;
-import lombok.ast.StaticInitializer;
-import lombok.ast.StringLiteral;
-import lombok.ast.Super;
-import lombok.ast.SuperConstructorInvocation;
-import lombok.ast.Switch;
-import lombok.ast.Synchronized;
-import lombok.ast.This;
-import lombok.ast.Throw;
-import lombok.ast.Try;
-import lombok.ast.TypeReference;
-import lombok.ast.TypeReferencePart;
-import lombok.ast.TypeVariable;
-import lombok.ast.UnaryExpression;
-import lombok.ast.VariableDeclaration;
-import lombok.ast.VariableDefinition;
-import lombok.ast.VariableDefinitionEntry;
-import lombok.ast.VariableReference;
-import lombok.ast.While;
-
-/**
- * Specialized visitor for running detectors on a Java AST.
- * It operates in three phases:
- * <ol>
- *   <li> First, it computes a set of maps where it generates a map from each
- *        significant AST attribute (such as method call names) to a list
- *        of detectors to consult whenever that attribute is encountered.
- *        Examples of "attributes" are method names, Android resource identifiers,
- *        and general AST node types such as "cast" nodes etc. These are
- *        defined on the {@link JavaScanner} interface.
- *   <li> Second, it iterates over the document a single time, delegating to
- *        the detectors found at each relevant AST attribute.
- *   <li> Finally, it calls the remaining visitors (those that need to process a
- *        whole document on their own).
- * </ol>
- * It also notifies all the detectors before and after the document is processed
- * such that they can do pre- and post-processing.
- */
-public class JavaVisitor {
-    /** Default size of lists holding detectors of the same type for a given node type */
-    private static final int SAME_TYPE_COUNT = 8;
-
-    private final Map<String, List<VisitingDetector>> mMethodDetectors =
-            Maps.newHashMapWithExpectedSize(40);
-    private final Map<String, List<VisitingDetector>> mConstructorDetectors =
-            Maps.newHashMapWithExpectedSize(12);
-    private Set<String> mConstructorSimpleNames;
-    private final List<VisitingDetector> mResourceFieldDetectors =
-            new ArrayList<VisitingDetector>();
-    private final List<VisitingDetector> mAllDetectors;
-    private final List<VisitingDetector> mFullTreeDetectors;
-    private final Map<Class<? extends Node>, List<VisitingDetector>> mNodeTypeDetectors =
-            new HashMap<Class<? extends Node>, List<VisitingDetector>>(16);
-    private final JavaParser mParser;
-    private final Map<String, List<VisitingDetector>> mSuperClassDetectors =
-            new HashMap<String, List<VisitingDetector>>();
-
-    /**
-     * Number of fatal exceptions (internal errors, usually from ECJ) we've
-     * encountered; we don't log each and every one to avoid massive log spam
-     * in code which triggers this condition
-     */
-    private static int sExceptionCount;
-    /** Max number of logs to include */
-    private static final int MAX_REPORTED_CRASHES = 20;
-
-    JavaVisitor(@NonNull JavaParser parser, @NonNull List<Detector> detectors) {
-        mParser = parser;
-        mAllDetectors = new ArrayList<VisitingDetector>(detectors.size());
-        mFullTreeDetectors = new ArrayList<VisitingDetector>(detectors.size());
-
-        for (Detector detector : detectors) {
-            VisitingDetector v = new VisitingDetector(detector, (JavaScanner) detector);
-            mAllDetectors.add(v);
-
-            List<String> applicableSuperClasses = detector.applicableSuperClasses();
-            if (applicableSuperClasses != null) {
-                for (String fqn : applicableSuperClasses) {
-                    List<VisitingDetector> list = mSuperClassDetectors.get(fqn);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mSuperClassDetectors.put(fqn, list);
-                    }
-                    list.add(v);
-                }
-                continue;
-            }
-
-            List<Class<? extends Node>> nodeTypes = detector.getApplicableNodeTypes();
-            if (nodeTypes != null) {
-                for (Class<? extends Node> type : nodeTypes) {
-                    List<VisitingDetector> list = mNodeTypeDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mNodeTypeDetectors.put(type, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> names = detector.getApplicableMethodNames();
-            if (names != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert names != XmlScanner.ALL;
-
-                for (String name : names) {
-                    List<VisitingDetector> list = mMethodDetectors.get(name);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mMethodDetectors.put(name, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> types = detector.getApplicableConstructorTypes();
-            if (types != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert types != XmlScanner.ALL;
-                if (mConstructorSimpleNames == null) {
-                    mConstructorSimpleNames = Sets.newHashSet();
-                }
-                for (String type : types) {
-                    List<VisitingDetector> list = mConstructorDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mConstructorDetectors.put(type, list);
-                        mConstructorSimpleNames.add(type.substring(type.lastIndexOf('.')+1));
-                    }
-                    list.add(v);
-                }
-            }
-
-            if (detector.appliesToResourceRefs()) {
-                mResourceFieldDetectors.add(v);
-            } else if ((names == null || names.isEmpty())
-                    && (nodeTypes == null || nodeTypes.isEmpty())
-                    && (types == null || types.isEmpty())) {
-                mFullTreeDetectors.add(v);
-            }
-        }
-    }
-
-    void visitFile(@NonNull JavaContext context) {
-        Node compilationUnit = null;
-        try {
-            compilationUnit = mParser.parseJava(context);
-            if (compilationUnit == null) {
-                // No need to log this; the parser should be reporting
-                // a full warning (such as IssueRegistry#PARSER_ERROR)
-                // with details, location, etc.
-                return;
-            }
-            context.setCompilationUnit(compilationUnit);
-
-            for (VisitingDetector v : mAllDetectors) {
-                v.setContext(context);
-                v.getDetector().beforeCheckFile(context);
-            }
-
-            if (!mSuperClassDetectors.isEmpty()) {
-                SuperclassVisitor visitor = new SuperclassVisitor(context);
-                compilationUnit.accept(visitor);
-            }
-
-            for (VisitingDetector v : mFullTreeDetectors) {
-                AstVisitor visitor = v.getVisitor();
-                compilationUnit.accept(visitor);
-            }
-
-            if (!mMethodDetectors.isEmpty() || !mResourceFieldDetectors.isEmpty() ||
-                    !mConstructorDetectors.isEmpty()) {
-                AstVisitor visitor = new DelegatingJavaVisitor(context);
-                compilationUnit.accept(visitor);
-            } else if (!mNodeTypeDetectors.isEmpty()) {
-                AstVisitor visitor = new DispatchVisitor();
-                compilationUnit.accept(visitor);
-            }
-
-            for (VisitingDetector v : mAllDetectors) {
-                v.getDetector().afterCheckFile(context);
-            }
-        } catch (RuntimeException e) {
-            if (sExceptionCount++ > MAX_REPORTED_CRASHES) {
-                // No need to keep spamming the user that a lot of the files
-                // are tripping up ECJ, they get the picture.
-                return;
-            }
-
-            if (e.getClass().getSimpleName().equals("IndexNotReadyException")) {
-                // Attempting to access PSI during startup before indices are ready; ignore these.
-                // See http://b.android.com/176644 for an example.
-                return;
-            } else if (e.getClass().getSimpleName().equals("ProcessCanceledException")) {
-                // Cancelling inspections in the IDE
-                context.getDriver().cancel();
-                return;
-            }
-
-            // Work around ECJ bugs; see https://code.google.com/p/android/issues/detail?id=172268
-            // Don't allow lint bugs to take down the whole build. TRY to log this as a
-            // lint error instead!
-            StringBuilder sb = new StringBuilder(100);
-            sb.append("Unexpected failure during lint analysis of ");
-            sb.append(context.file.getName());
-            sb.append(" (this is a bug in lint or one of the libraries it depends on)\n");
-
-            sb.append(e.getClass().getSimpleName());
-            sb.append(':');
-            StackTraceElement[] stackTrace = e.getStackTrace();
-            int count = 0;
-            for (StackTraceElement frame : stackTrace) {
-                if (count > 0) {
-                    sb.append("<-");
-                }
-
-                String className = frame.getClassName();
-                sb.append(className.substring(className.lastIndexOf('.') + 1));
-                sb.append('.').append(frame.getMethodName());
-                sb.append('(');
-                sb.append(frame.getFileName()).append(':').append(frame.getLineNumber());
-                sb.append(')');
-                count++;
-                // Only print the top 3-4 frames such that we can identify the bug
-                if (count == 4) {
-                    break;
-                }
-            }
-            Throwable throwable = null; // NOT e: this makes for very noisy logs
-            //noinspection ConstantConditions
-            context.log(throwable, sb.toString());
-        } finally {
-            if (compilationUnit != null) {
-                mParser.dispose(context, compilationUnit);
-            }
-        }
-    }
-
-    /**
-     * For testing only: returns the number of exceptions thrown during Java AST analysis
-     *
-     * @return the number of internal errors found
-     */
-    @VisibleForTesting
-    public static int getCrashCount() {
-        return sExceptionCount;
-    }
-
-    /**
-     * For testing only: clears the crash counter
-     */
-    @VisibleForTesting
-    public static void clearCrashCount() {
-        sExceptionCount = 0;
-    }
-
-    public void prepare(@NonNull List<JavaContext> contexts) {
-        mParser.prepareJavaParse(contexts);
-    }
-
-    public void dispose() {
-        mParser.dispose();
-    }
-
-    @Nullable
-    private static Set<String> getInterfaceNames(
-            @Nullable Set<String> addTo,
-            @NonNull ResolvedClass cls) {
-        Iterable<ResolvedClass> interfaces = cls.getInterfaces();
-        for (ResolvedClass resolvedInterface : interfaces) {
-            String name = resolvedInterface.getName();
-            if (addTo == null) {
-                addTo = Sets.newHashSet();
-            } else if (addTo.contains(name)) {
-                // Superclasses can explicitly implement the same interface,
-                // so keep track of visited interfaces as we traverse up the
-                // super class chain to avoid checking the same interface
-                // more than once.
-                continue;
-            }
-            addTo.add(name);
-            getInterfaceNames(addTo, resolvedInterface);
-        }
-
-        return addTo;
-    }
-
-    private static class VisitingDetector {
-        private AstVisitor mVisitor; // construct lazily, and clear out on context switch!
-        private JavaContext mContext;
-        public final Detector mDetector;
-        public final JavaScanner mJavaScanner;
-
-        public VisitingDetector(@NonNull Detector detector, @NonNull JavaScanner javaScanner) {
-            mDetector = detector;
-            mJavaScanner = javaScanner;
-        }
-
-        @NonNull
-        public Detector getDetector() {
-            return mDetector;
-        }
-
-        @NonNull
-        public JavaScanner getJavaScanner() {
-            return mJavaScanner;
-        }
-
-        public void setContext(@NonNull JavaContext context) {
-            mContext = context;
-
-            // The visitors are one-per-context, so clear them out here and construct
-            // lazily only if needed
-            mVisitor = null;
-        }
-
-        @NonNull
-        AstVisitor getVisitor() {
-            if (mVisitor == null) {
-                mVisitor = mDetector.createJavaVisitor(mContext);
-                if (mVisitor == null) {
-                    mVisitor = new ForwardingAstVisitor() {
-                    };
-                }
-            }
-            return mVisitor;
-        }
-    }
-
-    private class SuperclassVisitor extends ForwardingAstVisitor {
-        private JavaContext mContext;
-
-        public SuperclassVisitor(@NonNull JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitClassDeclaration(ClassDeclaration node) {
-            ResolvedNode resolved = mContext.resolve(node);
-            if (!(resolved instanceof ResolvedClass)) {
-                return true;
-            }
-
-            ResolvedClass resolvedClass = (ResolvedClass) resolved;
-            ResolvedClass cls = resolvedClass;
-            int depth = 0;
-            while (cls != null) {
-                List<VisitingDetector> list = mSuperClassDetectors.get(cls.getName());
-                if (list != null) {
-                    for (VisitingDetector v : list) {
-                        v.getJavaScanner().checkClass(mContext, node, node, resolvedClass);
-                    }
-                }
-
-                // Check interfaces too
-                Set<String> interfaceNames = getInterfaceNames(null, cls);
-                if (interfaceNames != null) {
-                    for (String name : interfaceNames) {
-                        list = mSuperClassDetectors.get(name);
-                        if (list != null) {
-                            for (VisitingDetector v : list) {
-                                v.getJavaScanner().checkClass(mContext, node, node,
-                                        resolvedClass);
-                            }
-                        }
-                    }
-                }
-
-                cls = cls.getSuperClass();
-                depth++;
-                if (depth == 500) {
-                    // Shouldn't happen in practice; this prevents the IDE from
-                    // hanging if the user has accidentally typed in an incorrect
-                    // super class which creates a cycle.
-                    break;
-                }
-            }
-
-            return false;
-        }
-
-        @Override
-        public boolean visitConstructorInvocation(ConstructorInvocation node) {
-            NormalTypeBody anonymous = node.astAnonymousClassBody();
-            if (anonymous != null) {
-                ResolvedNode resolved = mContext.resolve(node.astTypeReference());
-                if (!(resolved instanceof ResolvedClass)) {
-                    return true;
-                }
-
-                ResolvedClass resolvedClass = (ResolvedClass) resolved;
-                ResolvedClass cls = resolvedClass;
-                while (cls != null) {
-                    List<VisitingDetector> list = mSuperClassDetectors.get(cls.getName());
-                    if (list != null) {
-                        for (VisitingDetector v : list) {
-                            v.getJavaScanner().checkClass(mContext, null, anonymous,
-                                    resolvedClass);
-                        }
-                    }
-
-                    // Check interfaces too
-                    Set<String> interfaceNames = getInterfaceNames(null, cls);
-                    if (interfaceNames != null) {
-                        for (String name : interfaceNames) {
-                            list = mSuperClassDetectors.get(name);
-                            if (list != null) {
-                                for (VisitingDetector v : list) {
-                                    v.getJavaScanner().checkClass(mContext, null, anonymous,
-                                            resolvedClass);
-                                }
-                            }
-                        }
-                    }
-
-                    cls = cls.getSuperClass();
-                }
-            }
-
-            return true;
-        }
-
-        @Override
-        public boolean visitImportDeclaration(ImportDeclaration node) {
-            return true;
-        }
-    }
-
-    /**
-     * Generic dispatcher which visits all nodes (once) and dispatches to
-     * specific visitors for each node. Each visitor typically only wants to
-     * look at a small part of a tree, such as a method call or a class
-     * declaration, so this means we avoid visiting all "uninteresting" nodes in
-     * the tree repeatedly.
-     */
-    private class DispatchVisitor extends ForwardingAstVisitor {
-        @Override
-        public void endVisit(Node node) {
-            for (VisitingDetector v : mAllDetectors) {
-                v.getVisitor().endVisit(node);
-            }
-        }
-
-        @Override
-        public boolean visitAlternateConstructorInvocation(AlternateConstructorInvocation node) {
-            List<VisitingDetector> list =
-                    mNodeTypeDetectors.get(AlternateConstructorInvocation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAlternateConstructorInvocation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAnnotation(Annotation node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Annotation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAnnotationDeclaration(AnnotationDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(AnnotationDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAnnotationElement(AnnotationElement node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(AnnotationElement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationElement(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAnnotationMethodDeclaration(AnnotationMethodDeclaration node) {
-            List<VisitingDetector> list =
-                    mNodeTypeDetectors.get(AnnotationMethodDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationMethodDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAnnotationValueArray(AnnotationValueArray node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(AnnotationValueArray.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotationValueArray(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitArrayAccess(ArrayAccess node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ArrayAccess.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayAccess(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitArrayCreation(ArrayCreation node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ArrayCreation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayCreation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitArrayDimension(ArrayDimension node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ArrayDimension.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayDimension(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitArrayInitializer(ArrayInitializer node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ArrayInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayInitializer(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitAssert(Assert node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Assert.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAssert(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitBinaryExpression(BinaryExpression node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(BinaryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBinaryExpression(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitBlock(Block node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Block.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBlock(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitBooleanLiteral(BooleanLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(BooleanLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBooleanLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitBreak(Break node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Break.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBreak(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitCase(Case node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Case.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCase(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitCast(Cast node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Cast.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCast(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitCatch(Catch node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Catch.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCatch(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitCharLiteral(CharLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(CharLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCharLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitClassDeclaration(ClassDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ClassDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClassDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitClassLiteral(ClassLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ClassLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClassLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitComment(Comment node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Comment.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitComment(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitCompilationUnit(CompilationUnit node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(CompilationUnit.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCompilationUnit(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitConstructorDeclaration(ConstructorDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ConstructorDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitConstructorDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitConstructorInvocation(ConstructorInvocation node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ConstructorInvocation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitConstructorInvocation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitContinue(Continue node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Continue.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitContinue(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitDefault(Default node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Default.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDefault(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitDoWhile(DoWhile node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(DoWhile.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDoWhile(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitEmptyDeclaration(EmptyDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(EmptyDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEmptyDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitEmptyStatement(EmptyStatement node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(EmptyStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEmptyStatement(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitEnumConstant(EnumConstant node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(EnumConstant.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEnumConstant(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitEnumDeclaration(EnumDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(EnumDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEnumDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitEnumTypeBody(EnumTypeBody node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(EnumTypeBody.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitEnumTypeBody(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitExpressionStatement(ExpressionStatement node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ExpressionStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpressionStatement(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitFloatingPointLiteral(FloatingPointLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(FloatingPointLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitFloatingPointLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitFor(For node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(For.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitFor(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitForEach(ForEach node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ForEach.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitForEach(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitIdentifier(Identifier node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Identifier.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIdentifier(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitIf(If node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(If.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIf(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitImportDeclaration(ImportDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(ImportDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitInlineIfExpression(InlineIfExpression node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(InlineIfExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInlineIfExpression(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitInstanceInitializer(InstanceInitializer node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(InstanceInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInstanceInitializer(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitInstanceOf(InstanceOf node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(InstanceOf.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInstanceOf(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitIntegralLiteral(IntegralLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(IntegralLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIntegralLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitInterfaceDeclaration(InterfaceDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(InterfaceDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInterfaceDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitKeywordModifier(KeywordModifier node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(KeywordModifier.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitKeywordModifier(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitLabelledStatement(LabelledStatement node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(LabelledStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLabelledStatement(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitMethodDeclaration(MethodDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(MethodDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethodDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitMethodInvocation(MethodInvocation node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(MethodInvocation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethodInvocation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitModifiers(Modifiers node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Modifiers.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitModifiers(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitNormalTypeBody(NormalTypeBody node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(NormalTypeBody.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitNormalTypeBody(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitNullLiteral(NullLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(NullLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitNullLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitPackageDeclaration(PackageDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(PackageDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPackageDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitParseArtefact(Node node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Node.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitParseArtefact(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitReturn(Return node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Return.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReturn(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitSelect(Select node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Select.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSelect(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitStaticInitializer(StaticInitializer node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(StaticInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitStaticInitializer(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitStringLiteral(StringLiteral node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(StringLiteral.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitStringLiteral(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitSuper(Super node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Super.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSuper(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(SuperConstructorInvocation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSuperConstructorInvocation(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitSwitch(Switch node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Switch.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSwitch(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitSynchronized(Synchronized node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Synchronized.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSynchronized(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitThis(This node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(This.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThis(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitThrow(Throw node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Throw.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThrow(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitTry(Try node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(Try.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTry(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitTypeReference(TypeReference node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(TypeReference.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeReference(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitTypeReferencePart(TypeReferencePart node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(TypeReferencePart.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeReferencePart(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitTypeVariable(TypeVariable node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(TypeVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeVariable(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitUnaryExpression(UnaryExpression node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(UnaryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitUnaryExpression(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitVariableDeclaration(VariableDeclaration node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(VariableDeclaration.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariableDeclaration(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitVariableDefinition(VariableDefinition node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(VariableDefinition.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariableDefinition(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitVariableDefinitionEntry(VariableDefinitionEntry node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(VariableDefinitionEntry.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariableDefinitionEntry(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitVariableReference(VariableReference node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(VariableReference.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariableReference(node);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean visitWhile(While node) {
-            List<VisitingDetector> list = mNodeTypeDetectors.get(While.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitWhile(node);
-                }
-            }
-            return false;
-        }
-    }
-
-    /** Performs common AST searches for method calls and R-type-field references.
-     * Note that this is a specialized form of the {@link DispatchVisitor}. */
-    private class DelegatingJavaVisitor extends DispatchVisitor {
-        private final JavaContext mContext;
-        private final boolean mVisitResources;
-        private final boolean mVisitMethods;
-        private final boolean mVisitConstructors;
-
-        public DelegatingJavaVisitor(JavaContext context) {
-            mContext = context;
-
-            mVisitMethods = !mMethodDetectors.isEmpty();
-            mVisitConstructors = !mConstructorDetectors.isEmpty();
-            mVisitResources = !mResourceFieldDetectors.isEmpty();
-        }
-
-        @Override
-        public boolean visitSelect(Select node) {
-            if (mVisitResources) {
-                // R.type.name
-                if (node.astOperand() instanceof Select) {
-                    Select select = (Select) node.astOperand();
-                    if (select.astOperand() instanceof VariableReference) {
-                        VariableReference reference = (VariableReference) select.astOperand();
-                        if (reference.astIdentifier().astValue().equals(R_CLASS)) {
-                            String type = select.astIdentifier().astValue();
-                            String name = node.astIdentifier().astValue();
-
-                            // R -could- be referenced locally and really have been
-                            // imported as "import android.R;" in the import statements,
-                            // but this is not recommended (and in fact there's a specific
-                            // lint rule warning against it)
-                            boolean isFramework = false;
-
-                            for (VisitingDetector v : mResourceFieldDetectors) {
-                                JavaScanner detector = v.getJavaScanner();
-                                //noinspection ConstantConditions
-                                detector.visitResourceReference(mContext, v.getVisitor(),
-                                        node, type, name, isFramework);
-                            }
-
-                            return super.visitSelect(node);
-                        }
-                    }
-                }
-
-                // Arbitrary packages -- android.R.type.name, foo.bar.R.type.name
-                if (node.astIdentifier().astValue().equals(R_CLASS)) {
-                    Node parent = node.getParent();
-                    if (parent instanceof Select) {
-                        Node grandParent = parent.getParent();
-                        if (grandParent instanceof Select) {
-                            Select select = (Select) grandParent;
-                            String name = select.astIdentifier().astValue();
-                            Expression typeOperand = select.astOperand();
-                            if (typeOperand instanceof Select) {
-                                Select typeSelect = (Select) typeOperand;
-                                String type = typeSelect.astIdentifier().astValue();
-                                boolean isFramework = node.astOperand().toString().equals(
-                                        ANDROID_PKG);
-                                for (VisitingDetector v : mResourceFieldDetectors) {
-                                    JavaScanner detector = v.getJavaScanner();
-                                    detector.visitResourceReference(mContext, v.getVisitor(),
-                                            node, type, name, isFramework);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            return super.visitSelect(node);
-        }
-
-        @Override
-        public boolean visitMethodInvocation(MethodInvocation node) {
-            if (mVisitMethods) {
-                String methodName = node.astName().astValue();
-                List<VisitingDetector> list = mMethodDetectors.get(methodName);
-                if (list != null) {
-                    for (VisitingDetector v : list) {
-                        v.getJavaScanner().visitMethod(mContext, v.getVisitor(), node);
-                    }
-                }
-            }
-
-            return super.visitMethodInvocation(node);
-        }
-
-        @Override
-        public boolean visitConstructorInvocation(ConstructorInvocation node) {
-            if (mVisitConstructors) {
-                TypeReference typeReference = node.astTypeReference();
-                if (typeReference != null) {
-                    TypeReferencePart last = typeReference.astParts().last();
-                    if (last != null) {
-                        String name = last.astIdentifier().astValue();
-                        if (mConstructorSimpleNames.contains(name)) {
-                            ResolvedNode resolved = mContext.resolve(node);
-                            if (resolved instanceof ResolvedMethod) {
-                                ResolvedMethod method = (ResolvedMethod) resolved;
-                                String type = method.getContainingClass().getName();
-                                List<VisitingDetector> list = mConstructorDetectors.get(type);
-                                if (list != null) {
-                                    for (VisitingDetector v : list) {
-                                        v.getJavaScanner().visitConstructor(mContext,
-                                                v.getVisitor(), node, method);
-                                    }
-                                }
-
-                            }
-                        }
-                    }
-                }
-            }
-
-            return super.visitConstructorInvocation(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java
deleted file mode 100644
index 0b3597f..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.CLASS_FOLDER;
-import static com.android.SdkConstants.DOT_AAR;
-import static com.android.SdkConstants.DOT_JAR;
-import static com.android.SdkConstants.FD_ASSETS;
-import static com.android.SdkConstants.GEN_FOLDER;
-import static com.android.SdkConstants.LIBS_FOLDER;
-import static com.android.SdkConstants.RES_FOLDER;
-import static com.android.SdkConstants.SRC_FOLDER;
-import static com.android.tools.klint.detector.api.LintUtils.endsWith;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.AndroidArtifact;
-import com.android.builder.model.AndroidLibrary;
-import com.android.builder.model.Dependencies;
-import com.android.builder.model.Variant;
-import com.android.ide.common.repository.ResourceVisibilityLookup;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.prefs.AndroidLocation;
-import com.android.repository.api.ProgressIndicator;
-import com.android.repository.api.ProgressIndicatorAdapter;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkVersionInfo;
-import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.android.utils.XmlUtils;
-import com.google.common.annotations.Beta;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Information about the tool embedding the lint analyzer. IDEs and other tools
- * implementing lint support will extend this to integrate logging, displaying errors,
- * etc.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class LintClient {
-    private static final String PROP_BIN_DIR  = "com.android.tools.lint.bindir";  //$NON-NLS-1$
-
-    protected LintClient(@NonNull String clientName) {
-        //noinspection AssignmentToStaticFieldFromInstanceMethod
-        sClientName = clientName;
-    }
-
-    protected LintClient() {
-        //noinspection AssignmentToStaticFieldFromInstanceMethod
-        sClientName = "unknown";
-    }
-
-    /**
-     * Returns a configuration for use by the given project. The configuration
-     * provides information about which issues are enabled, any customizations
-     * to the severity of an issue, etc.
-     * <p>
-     * By default this method returns a {@link DefaultConfiguration}.
-     *
-     * @param project the project to obtain a configuration for
-     * @param driver the current driver, if any
-     * @return a configuration, never null.
-     */
-    @NonNull
-    public Configuration getConfiguration(@NonNull Project project, @Nullable LintDriver driver) {
-        return DefaultConfiguration.create(this, project, null);
-    }
-
-    /**
-     * Report the given issue. This method will only be called if the configuration
-     * provided by {@link #getConfiguration(Project,LintDriver)} has reported the corresponding
-     * issue as enabled and has not filtered out the issue with its
-     * {@link Configuration#ignore(Context,Issue,Location,String)} method.
-     * <p>
-     * @param context the context used by the detector when the issue was found
-     * @param issue the issue that was found
-     * @param severity the severity of the issue
-     * @param location the location of the issue
-     * @param message the associated user message
-     * @param format the format of the description and location descriptions
-     */
-    public abstract void report(
-            @NonNull Context context,
-            @NonNull Issue issue,
-            @NonNull Severity severity,
-            @NonNull Location location,
-            @NonNull String message,
-            @NonNull TextFormat format);
-
-    /**
-     * Send an exception or error message (with warning severity) to the log
-     *
-     * @param exception the exception, possibly null
-     * @param format the error message using {@link String#format} syntax, possibly null
-     *    (though in that case the exception should not be null)
-     * @param args any arguments for the format string
-     */
-    public void log(
-            @Nullable Throwable exception,
-            @Nullable String format,
-            @Nullable Object... args) {
-        log(Severity.WARNING, exception, format, args);
-    }
-
-    /**
-     * Send an exception or error message to the log
-     *
-     * @param severity the severity of the warning
-     * @param exception the exception, possibly null
-     * @param format the error message using {@link String#format} syntax, possibly null
-     *    (though in that case the exception should not be null)
-     * @param args any arguments for the format string
-     */
-    public abstract void log(
-            @NonNull Severity severity,
-            @Nullable Throwable exception,
-            @Nullable String format,
-            @Nullable Object... args);
-
-    /**
-     * Returns a {@link XmlParser} to use to parse XML
-     *
-     * @return a new {@link XmlParser}, or null if this client does not support
-     *         XML analysis
-     */
-    @Nullable
-    public abstract XmlParser getXmlParser();
-
-    /**
-     * Returns a {@link JavaParser} to use to parse Java
-     *
-     * @param project the project to parse, if known (this can be used to look up
-     *                the class path for type attribution etc, and it can also be used
-     *                to more efficiently process a set of files, for example to
-     *                perform type attribution for multiple units in a single pass)
-     * @return a new {@link JavaParser}, or null if this client does not
-     *         support Java analysis
-     */
-    @Nullable
-    public abstract JavaParser getJavaParser(@Nullable Project project);
-
-    /**
-     * Returns an optimal detector, if applicable. By default, just returns the
-     * original detector, but tools can replace detectors using this hook with a version
-     * that takes advantage of native capabilities of the tool.
-     *
-     * @param detectorClass the class of the detector to be replaced
-     * @return the new detector class, or just the original detector (not null)
-     */
-    @NonNull
-    public Class<? extends Detector> replaceDetector(
-            @NonNull Class<? extends Detector> detectorClass) {
-        return detectorClass;
-    }
-
-    /**
-     * Reads the given text file and returns the content as a string
-     *
-     * @param file the file to read
-     * @return the string to return, never null (will be empty if there is an
-     *         I/O error)
-     */
-    @NonNull
-    public abstract String readFile(@NonNull File file);
-
-    /**
-     * Reads the given binary file and returns the content as a byte array.
-     * By default this method will read the bytes from the file directly,
-     * but this can be customized by a client if for example I/O could be
-     * held in memory and not flushed to disk yet.
-     *
-     * @param file the file to read
-     * @return the bytes in the file, never null
-     * @throws IOException if the file does not exist, or if the file cannot be
-     *             read for some reason
-     */
-    @NonNull
-    public byte[] readBytes(@NonNull File file) throws IOException {
-        return Files.toByteArray(file);
-    }
-
-    /**
-     * Returns the list of source folders for Java source files
-     *
-     * @param project the project to look up Java source file locations for
-     * @return a list of source folders to search for .java files
-     */
-    @NonNull
-    public List<File> getJavaSourceFolders(@NonNull Project project) {
-        return getClassPath(project).getSourceFolders();
-    }
-
-    /**
-     * Returns the list of output folders for class files
-     *
-     * @param project the project to look up class file locations for
-     * @return a list of output folders to search for .class files
-     */
-    @NonNull
-    public List<File> getJavaClassFolders(@NonNull Project project) {
-        return getClassPath(project).getClassFolders();
-
-    }
-
-    /**
-     * Returns the list of Java libraries
-     *
-     * @param project         the project to look up jar dependencies for
-     * @param includeProvided If true, included provided libraries too (libraries that are not
-     *                        packaged with the app, but are provided for compilation purposes and
-     *                        are assumed to be present in the running environment)
-     * @return a list of jar dependencies containing .class files
-     */
-    @NonNull
-    public List<File> getJavaLibraries(@NonNull Project project, boolean includeProvided) {
-        return getClassPath(project).getLibraries(includeProvided);
-    }
-
-    /**
-     * Returns the list of source folders for test source files
-     *
-     * @param project the project to look up test source file locations for
-     * @return a list of source folders to search for .java files
-     */
-    @NonNull
-    public List<File> getTestSourceFolders(@NonNull Project project) {
-        return getClassPath(project).getTestSourceFolders();
-    }
-
-    /**
-     * Returns the resource folders.
-     *
-     * @param project the project to look up the resource folder for
-     * @return a list of files pointing to the resource folders, possibly empty
-     */
-    @NonNull
-    public List<File> getResourceFolders(@NonNull Project project) {
-        File res = new File(project.getDir(), RES_FOLDER);
-        if (res.exists()) {
-            return Collections.singletonList(res);
-        }
-
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the asset folders.
-     *
-     * @param project the project to look up the asset folder for
-     * @return a list of files pointing to the asset folders, possibly empty
-     */
-    @NonNull
-    public List<File> getAssetFolders(@NonNull Project project) {
-        File assets = new File(project.getDir(), FD_ASSETS);
-        if (assets.exists()) {
-            return Collections.singletonList(assets);
-        }
-
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the {@link SdkInfo} to use for the given project.
-     *
-     * @param project the project to look up an {@link SdkInfo} for
-     * @return an {@link SdkInfo} for the project
-     */
-    @NonNull
-    public SdkInfo getSdkInfo(@NonNull Project project) {
-        // By default no per-platform SDK info
-        return new DefaultSdkInfo();
-    }
-
-    /**
-     * Returns a suitable location for storing cache files. Note that the
-     * directory may not exist.
-     *
-     * @param create if true, attempt to create the cache dir if it does not
-     *            exist
-     * @return a suitable location for storing cache files, which may be null if
-     *         the create flag was false, or if for some reason the directory
-     *         could not be created
-     */
-    @Nullable
-    public File getCacheDir(boolean create) {
-        String home = System.getProperty("user.home");
-        String relative = ".android" + File.separator + "cache"; //$NON-NLS-1$ //$NON-NLS-2$
-        File dir = new File(home, relative);
-        if (create && !dir.exists()) {
-            if (!dir.mkdirs()) {
-                return null;
-            }
-        }
-        return dir;
-    }
-
-    /**
-     * Returns the File corresponding to the system property or the environment variable
-     * for {@link #PROP_BIN_DIR}.
-     * This property is typically set by the SDK/tools/lint[.bat] wrapper.
-     * It denotes the path of the wrapper on disk.
-     *
-     * @return A new File corresponding to {@link LintClient#PROP_BIN_DIR} or null.
-     */
-    @Nullable
-    private static File getLintBinDir() {
-        // First check the Java properties (e.g. set using "java -jar ... -Dname=value")
-        String path = System.getProperty(PROP_BIN_DIR);
-        if (path == null || path.isEmpty()) {
-            // If not found, check environment variables.
-            path = System.getenv(PROP_BIN_DIR);
-        }
-        if (path != null && !path.isEmpty()) {
-            File file = new File(path);
-            if (file.exists()) {
-                return file;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the File pointing to the user's SDK install area. This is generally
-     * the root directory containing the lint tool (but also platforms/ etc).
-     *
-     * @return a file pointing to the user's install area
-     */
-    @Nullable
-    public File getSdkHome() {
-        File binDir = getLintBinDir();
-        if (binDir != null) {
-            assert binDir.getName().equals("tools");
-
-            File root = binDir.getParentFile();
-            if (root != null && root.isDirectory()) {
-                return root;
-            }
-        }
-
-        String home = System.getenv("ANDROID_HOME"); //$NON-NLS-1$
-        if (home != null) {
-            return new File(home);
-        }
-
-        return null;
-    }
-
-    /**
-     * Locates an SDK resource (relative to the SDK root directory).
-     * <p>
-     * TODO: Consider switching to a {@link URL} return type instead.
-     *
-     * @param relativePath A relative path (using {@link File#separator} to
-     *            separate path components) to the given resource
-     * @return a {@link File} pointing to the resource, or null if it does not
-     *         exist
-     */
-    @Nullable
-    public File findResource(@NonNull String relativePath) {
-        File top = getSdkHome();
-        if (top == null) {
-            throw new IllegalArgumentException("Lint must be invoked with the System property "
-                   + PROP_BIN_DIR + " pointing to the ANDROID_SDK tools directory");
-        }
-
-        File file = new File(top, relativePath);
-        if (file.exists()) {
-            return file;
-        } else {
-            return null;
-        }
-    }
-
-    private Map<Project, ClassPathInfo> mProjectInfo;
-
-    /**
-     * Returns true if this project is a Gradle-based Android project
-     *
-     * @param project the project to check
-     * @return true if this is a Gradle-based project
-     */
-    public boolean isGradleProject(Project project) {
-        // This is not an accurate test; specific LintClient implementations (e.g.
-        // IDEs or a gradle-integration of lint) have more context and can perform a more accurate
-        // check
-        if (new File(project.getDir(), SdkConstants.FN_BUILD_GRADLE).exists()) {
-            return true;
-        }
-
-        File parent = project.getDir().getParentFile();
-        if (parent != null && parent.getName().equals(SdkConstants.FD_SOURCES)) {
-            File root = parent.getParentFile();
-            if (root != null && new File(root, SdkConstants.FN_BUILD_GRADLE).exists()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Information about class paths (sources, class files and libraries)
-     * usually associated with a project.
-     */
-    protected static class ClassPathInfo {
-        private final List<File> mClassFolders;
-        private final List<File> mSourceFolders;
-        private final List<File> mLibraries;
-        private final List<File> mNonProvidedLibraries;
-        private final List<File> mTestFolders;
-
-        public ClassPathInfo(
-                @NonNull List<File> sourceFolders,
-                @NonNull List<File> classFolders,
-                @NonNull List<File> libraries,
-                @NonNull List<File> nonProvidedLibraries,
-                @NonNull List<File> testFolders) {
-            mSourceFolders = sourceFolders;
-            mClassFolders = classFolders;
-            mLibraries = libraries;
-            mNonProvidedLibraries = nonProvidedLibraries;
-            mTestFolders = testFolders;
-        }
-
-        @NonNull
-        public List<File> getSourceFolders() {
-            return mSourceFolders;
-        }
-
-        @NonNull
-        public List<File> getClassFolders() {
-            return mClassFolders;
-        }
-
-        @NonNull
-        public List<File> getLibraries(boolean includeProvided) {
-            return includeProvided ? mLibraries : mNonProvidedLibraries;
-        }
-
-        public List<File> getTestSourceFolders() {
-            return mTestFolders;
-        }
-    }
-
-    /**
-     * Considers the given project as an Eclipse project and returns class path
-     * information for the project - the source folder(s), the output folder and
-     * any libraries.
-     * <p>
-     * Callers will not cache calls to this method, so if it's expensive to compute
-     * the classpath info, this method should perform its own caching.
-     *
-     * @param project the project to look up class path info for
-     * @return a class path info object, never null
-     */
-    @NonNull
-    protected ClassPathInfo getClassPath(@NonNull Project project) {
-        ClassPathInfo info;
-        if (mProjectInfo == null) {
-            mProjectInfo = Maps.newHashMap();
-            info = null;
-        } else {
-            info = mProjectInfo.get(project);
-        }
-
-        if (info == null) {
-            List<File> sources = new ArrayList<File>(2);
-            List<File> classes = new ArrayList<File>(1);
-            List<File> libraries = new ArrayList<File>();
-            // No test folders in Eclipse:
-            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=224708
-            List<File> tests = Collections.emptyList();
-
-            File projectDir = project.getDir();
-            File classpathFile = new File(projectDir, ".classpath"); //$NON-NLS-1$
-            if (classpathFile.exists()) {
-                String classpathXml = readFile(classpathFile);
-                try {
-                    Document document = XmlUtils.parseDocument(classpathXml, false);
-                    NodeList tags = document.getElementsByTagName("classpathentry"); //$NON-NLS-1$
-                    for (int i = 0, n = tags.getLength(); i < n; i++) {
-                        Element element = (Element) tags.item(i);
-                        String kind = element.getAttribute("kind"); //$NON-NLS-1$
-                        List<File> addTo = null;
-                        if (kind.equals("src")) {            //$NON-NLS-1$
-                            addTo = sources;
-                        } else if (kind.equals("output")) {  //$NON-NLS-1$
-                            addTo = classes;
-                        } else if (kind.equals("lib")) {     //$NON-NLS-1$
-                            addTo = libraries;
-                        }
-                        if (addTo != null) {
-                            String path = element.getAttribute("path"); //$NON-NLS-1$
-                            File folder = new File(projectDir, path);
-                            if (folder.exists()) {
-                                addTo.add(folder);
-                            }
-                        }
-                    }
-                } catch (Exception e) {
-                    log(null, null);
-                }
-            }
-
-            // Add in libraries that aren't specified in the .classpath file
-            File libs = new File(project.getDir(), LIBS_FOLDER);
-            if (libs.isDirectory()) {
-                File[] jars = libs.listFiles();
-                if (jars != null) {
-                    for (File jar : jars) {
-                        if (endsWith(jar.getPath(), DOT_JAR)
-                                && !libraries.contains(jar)) {
-                            libraries.add(jar);
-                        }
-                    }
-                }
-            }
-
-            if (classes.isEmpty()) {
-                File folder = new File(projectDir, CLASS_FOLDER);
-                if (folder.exists()) {
-                    classes.add(folder);
-                } else {
-                    // Maven checks
-                    folder = new File(projectDir,
-                            "target" + File.separator + "classes"); //$NON-NLS-1$ //$NON-NLS-2$
-                    if (folder.exists()) {
-                        classes.add(folder);
-
-                        // If it's maven, also correct the source path, "src" works but
-                        // it's in a more specific subfolder
-                        if (sources.isEmpty()) {
-                            File src = new File(projectDir,
-                                    "src" + File.separator     //$NON-NLS-1$
-                                    + "main" + File.separator  //$NON-NLS-1$
-                                    + "java");                 //$NON-NLS-1$
-                            if (src.exists()) {
-                                sources.add(src);
-                            } else {
-                                src = new File(projectDir, SRC_FOLDER);
-                                if (src.exists()) {
-                                    sources.add(src);
-                                }
-                            }
-
-                            File gen = new File(projectDir,
-                                    "target" + File.separator                  //$NON-NLS-1$
-                                    + "generated-sources" + File.separator     //$NON-NLS-1$
-                                    + "r");                                    //$NON-NLS-1$
-                            if (gen.exists()) {
-                                sources.add(gen);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Fallback, in case there is no Eclipse project metadata here
-            if (sources.isEmpty()) {
-                File src = new File(projectDir, SRC_FOLDER);
-                if (src.exists()) {
-                    sources.add(src);
-                }
-                File gen = new File(projectDir, GEN_FOLDER);
-                if (gen.exists()) {
-                    sources.add(gen);
-                }
-            }
-
-            info = new ClassPathInfo(sources, classes, libraries, libraries, tests);
-            mProjectInfo.put(project, info);
-        }
-
-        return info;
-    }
-
-    /**
-     * A map from directory to existing projects, or null. Used to ensure that
-     * projects are unique for a directory (in case we process a library project
-     * before its including project for example)
-     */
-    protected Map<File, Project> mDirToProject;
-
-    /**
-     * Returns a project for the given directory. This should return the same
-     * project for the same directory if called repeatedly.
-     *
-     * @param dir the directory containing the project
-     * @param referenceDir See {@link Project#getReferenceDir()}.
-     * @return a project, never null
-     */
-    @NonNull
-    public Project getProject(@NonNull File dir, @NonNull File referenceDir) {
-        if (mDirToProject == null) {
-            mDirToProject = new HashMap<File, Project>();
-        }
-
-        File canonicalDir = dir;
-        try {
-            // Attempt to use the canonical handle for the file, in case there
-            // are symlinks etc present (since when handling library projects,
-            // we also call getCanonicalFile to compute the result of appending
-            // relative paths, which can then resolve symlinks and end up with
-            // a different prefix)
-            canonicalDir = dir.getCanonicalFile();
-        } catch (IOException ioe) {
-            // pass
-        }
-
-        Project project = mDirToProject.get(canonicalDir);
-        if (project != null) {
-            return project;
-        }
-
-        project = createProject(dir, referenceDir);
-        mDirToProject.put(canonicalDir, project);
-        return project;
-    }
-
-    /**
-     * Returns the list of known projects (projects registered via
-     * {@link #getProject(File, File)}
-     *
-     * @return a collection of projects in any order
-     */
-    public Collection<Project> getKnownProjects() {
-        return mDirToProject != null ? mDirToProject.values() : Collections.<Project>emptyList();
-    }
-
-    /**
-     * Registers the given project for the given directory. This can
-     * be used when projects are initialized outside of the client itself.
-     *
-     * @param dir the directory of the project, which must be unique
-     * @param project the project
-     */
-    public void registerProject(@NonNull File dir, @NonNull Project project) {
-        File canonicalDir = dir;
-        try {
-            // Attempt to use the canonical handle for the file, in case there
-            // are symlinks etc present (since when handling library projects,
-            // we also call getCanonicalFile to compute the result of appending
-            // relative paths, which can then resolve symlinks and end up with
-            // a different prefix)
-            canonicalDir = dir.getCanonicalFile();
-        } catch (IOException ioe) {
-            // pass
-        }
-
-
-        if (mDirToProject == null) {
-            mDirToProject = new HashMap<File, Project>();
-        } else {
-            assert !mDirToProject.containsKey(dir) : dir;
-        }
-        mDirToProject.put(canonicalDir, project);
-    }
-
-    protected Set<File> mProjectDirs = Sets.newHashSet();
-
-    /**
-     * Create a project for the given directory
-     * @param dir the root directory of the project
-     * @param referenceDir See {@link Project#getReferenceDir()}.
-     * @return a new project
-     */
-    @NonNull
-    protected Project createProject(@NonNull File dir, @NonNull File referenceDir) {
-        if (mProjectDirs.contains(dir)) {
-            throw new CircularDependencyException(
-                "Circular library dependencies; check your project.properties files carefully");
-        }
-        mProjectDirs.add(dir);
-        return Project.create(this, dir, referenceDir);
-    }
-
-    /**
-     * Returns the name of the given project
-     *
-     * @param project the project to look up
-     * @return the name of the project
-     */
-    @NonNull
-    public String getProjectName(@NonNull Project project) {
-        return project.getDir().getName();
-    }
-
-    protected IAndroidTarget[] mTargets;
-
-    /**
-     * Returns all the {@link IAndroidTarget} versions installed in the user's SDK install
-     * area.
-     *
-     * @return all the installed targets
-     */
-    @NonNull
-    public IAndroidTarget[] getTargets() {
-        if (mTargets == null) {
-            AndroidSdkHandler sdkHandler = getSdk();
-            if (sdkHandler != null) {
-                ProgressIndicator logger = getRepositoryLogger();
-                Collection<IAndroidTarget> targets = sdkHandler.getAndroidTargetManager(logger)
-                        .getTargets(logger);
-                mTargets = targets.toArray(new IAndroidTarget[targets.size()]);
-            } else {
-                mTargets = new IAndroidTarget[0];
-            }
-        }
-
-        return mTargets;
-    }
-
-    protected AndroidSdkHandler mSdk;
-
-    /**
-     * Returns the SDK installation (used to look up platforms etc)
-     *
-     * @return the SDK if known
-     */
-    @Nullable
-    public AndroidSdkHandler getSdk() {
-        if (mSdk == null) {
-            File sdkHome = getSdkHome();
-            if (sdkHome != null) {
-                mSdk = AndroidSdkHandler.getInstance(sdkHome);
-            }
-        }
-
-        return mSdk;
-    }
-
-    /**
-     * Returns the compile target to use for the given project
-     *
-     * @param project the project in question
-     *
-     * @return the compile target to use to build the given project
-     */
-    @Nullable
-    public IAndroidTarget getCompileTarget(@NonNull Project project) {
-        int buildSdk = project.getBuildSdk();
-        IAndroidTarget[] targets = getTargets();
-        for (int i = targets.length - 1; i >= 0; i--) {
-            IAndroidTarget target = targets[i];
-            if (target.isPlatform() && target.getVersion().getApiLevel() == buildSdk) {
-                return target;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the highest known API level.
-     *
-     * @return the highest known API level
-     */
-    public int getHighestKnownApiLevel() {
-        int max = SdkVersionInfo.HIGHEST_KNOWN_STABLE_API;
-
-        for (IAndroidTarget target : getTargets()) {
-            if (target.isPlatform()) {
-                int api = target.getVersion().getApiLevel();
-                if (api > max && !target.getVersion().isPreview()) {
-                    max = api;
-                }
-            }
-        }
-
-        return max;
-    }
-
-    /**
-     * Returns the specific version of the build tools being used for the given project, if known
-     *
-     * @param project the project in question
-     *
-     * @return the build tools version in use by the project, or null if not known
-     */
-    @Nullable
-    public BuildToolInfo getBuildTools(@NonNull Project project) {
-        //TODO
-        //AndroidSdkHandler sdk = getSdk();
-        //// Build systems like Eclipse and ant just use the latest available
-        //// build tools, regardless of project metadata. In Gradle, this
-        //// method is overridden to use the actual build tools specified in the
-        //// project.
-        //if (sdk != null) {
-        //    IAndroidTarget compileTarget = getCompileTarget(project);
-        //    if (compileTarget != null) {
-        //        return compileTarget.getBuildToolInfo();
-        //    }
-        //    return sdk.getLatestBuildTool(getRepositoryLogger(), false);
-        //}
-
-        return null;
-    }
-
-    /**
-     * Returns the super class for the given class name, which should be in VM
-     * format (e.g. java/lang/Integer, not java.lang.Integer, and using $ rather
-     * than . for inner classes). If the super class is not known, returns null.
-     * <p>
-     * This is typically not necessary, since lint analyzes all the available
-     * classes. However, if this lint client is invoking lint in an incremental
-     * context (for example, an IDE offering incremental analysis of a single
-     * source file), then lint may not see all the classes, and the client can
-     * provide its own super class lookup.
-     *
-     * @param project the project containing the class
-     * @param name the fully qualified class name
-     * @return the corresponding super class name (in VM format), or null if not
-     *         known
-     */
-    @Nullable
-    public String getSuperClass(@NonNull Project project, @NonNull String name) {
-        assert name.indexOf('.') == -1 : "Use VM signatures, e.g. java/lang/Integer";
-
-        if ("java/lang/Object".equals(name)) {  //$NON-NLS-1$
-            return null;
-        }
-
-        String superClass = project.getSuperClassMap().get(name);
-        if (superClass != null) {
-            return superClass;
-        }
-
-        for (Project library : project.getAllLibraries()) {
-            superClass = library.getSuperClassMap().get(name);
-            if (superClass != null) {
-                return superClass;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Creates a super class map for the given project. The map maps from
-     * internal class name (e.g. java/lang/Integer, not java.lang.Integer) to its
-     * corresponding super class name. The root class, java/lang/Object, is not in the map.
-     *
-     * @param project the project to initialize the super class with; this will include
-     *                local classes as well as any local .jar libraries; not transitive
-     *                dependencies
-     * @return a map from class to its corresponding super class; never null
-     */
-    @NonNull
-    public Map<String, String> createSuperClassMap(@NonNull Project project) {
-        List<File> libraries = project.getJavaLibraries(true);
-        List<File> classFolders = project.getJavaClassFolders();
-        List<ClassEntry> classEntries = ClassEntry.fromClassPath(this, classFolders, true);
-        if (libraries.isEmpty()) {
-            return ClassEntry.createSuperClassMap(this, classEntries);
-        }
-        List<ClassEntry> libraryEntries = ClassEntry.fromClassPath(this, libraries, true);
-        return ClassEntry.createSuperClassMap(this, libraryEntries, classEntries);
-    }
-
-    /**
-     * Checks whether the given name is a subclass of the given super class. If
-     * the method does not know, it should return null, and otherwise return
-     * {@link Boolean#TRUE} or {@link Boolean#FALSE}.
-     * <p>
-     * Note that the class names are in internal VM format (java/lang/Integer,
-     * not java.lang.Integer, and using $ rather than . for inner classes).
-     *
-     * @param project the project context to look up the class in
-     * @param name the name of the class to be checked
-     * @param superClassName the name of the super class to compare to
-     * @return true if the class of the given name extends the given super class
-     */
-    @SuppressWarnings("NonBooleanMethodNameMayNotStartWithQuestion")
-    @Nullable
-    public Boolean isSubclassOf(
-            @NonNull Project project,
-            @NonNull String name,
-            @NonNull String superClassName) {
-        return null;
-    }
-
-    /**
-     * Finds any custom lint rule jars that should be included for analysis,
-     * regardless of project.
-     * <p>
-     * The default implementation locates custom lint jars in ~/.android/lint/ and
-     * in $ANDROID_LINT_JARS
-     *
-     * @return a list of rule jars (possibly empty).
-     */
-    @SuppressWarnings("MethodMayBeStatic") // Intentionally instance method so it can be overridden
-    @NonNull
-    public List<File> findGlobalRuleJars() {
-        // Look for additional detectors registered by the user, via
-        // (1) an environment variable (useful for build servers etc), and
-        // (2) via jar files in the .android/lint directory
-        List<File> files = null;
-        try {
-            String androidHome = AndroidLocation.getFolder();
-            File lint = new File(androidHome + File.separator + "lint"); //$NON-NLS-1$
-            if (lint.exists()) {
-                File[] list = lint.listFiles();
-                if (list != null) {
-                    for (File jarFile : list) {
-                        if (endsWith(jarFile.getName(), DOT_JAR)) {
-                            if (files == null) {
-                                files = new ArrayList<File>();
-                            }
-                            files.add(jarFile);
-                        }
-                    }
-                }
-            }
-        } catch (AndroidLocation.AndroidLocationException e) {
-            // Ignore -- no android dir, so no rules to load.
-        }
-
-        String lintClassPath = System.getenv("ANDROID_LINT_JARS"); //$NON-NLS-1$
-        if (lintClassPath != null && !lintClassPath.isEmpty()) {
-            String[] paths = lintClassPath.split(File.pathSeparator);
-            for (String path : paths) {
-                File jarFile = new File(path);
-                if (jarFile.exists()) {
-                    if (files == null) {
-                        files = new ArrayList<File>();
-                    } else if (files.contains(jarFile)) {
-                        continue;
-                    }
-                    files.add(jarFile);
-                }
-            }
-        }
-
-        return files != null ? files : Collections.<File>emptyList();
-    }
-
-    /**
-     * Finds any custom lint rule jars that should be included for analysis
-     * in the given project
-     *
-     * @param project the project to look up rule jars from
-     * @return a list of rule jars (possibly empty).
-     */
-    @SuppressWarnings("MethodMayBeStatic") // Intentionally instance method so it can be overridden
-    @NonNull
-    public List<File> findRuleJars(@NonNull Project project) {
-        if (project.isGradleProject()) {
-            if (project.isLibrary()) {
-                AndroidLibrary model = project.getGradleLibraryModel();
-                if (model != null) {
-                    File lintJar = model.getLintJar();
-                    if (lintJar.exists()) {
-                        return Collections.singletonList(lintJar);
-                    }
-                }
-            } else if (project.getSubset() != null) {
-                // Probably just analyzing a single file: we still want to look for custom
-                // rules applicable to the file
-                List<File> rules = null;
-                final Variant variant = project.getCurrentVariant();
-                if (variant != null) {
-                    Collection<AndroidLibrary> libraries = variant.getMainArtifact()
-                        .getDependencies().getLibraries();
-                    for (AndroidLibrary library : libraries) {
-                        File lintJar = library.getLintJar();
-                        if (lintJar.exists()) {
-                            if (rules == null) {
-                                rules = Lists.newArrayListWithExpectedSize(4);
-                            }
-                            rules.add(lintJar);
-                        }
-                    }
-                    if (rules != null) {
-                        return rules;
-                    }
-                }
-            } else if (project.getDir().getPath().endsWith(DOT_AAR)) {
-                File lintJar = new File(project.getDir(), "lint.jar"); //$NON-NLS-1$
-                if (lintJar.exists()) {
-                    return Collections.singletonList(lintJar);
-                }
-            }
-        }
-
-        return Collections.emptyList();
-    }
-
-    /**
-     * Opens a URL connection.
-     *
-     * Clients such as IDEs can override this to for example consider the user's IDE proxy
-     * settings.
-     *
-     * @param url the URL to read
-     * @return a {@link URLConnection} or null
-     * @throws IOException if any kind of IO exception occurs
-     */
-    @Nullable
-    public URLConnection openConnection(@NonNull URL url) throws IOException {
-        return url.openConnection();
-    }
-
-    /** Closes a connection previously returned by {@link #openConnection(URL)} */
-    public void closeConnection(@NonNull URLConnection connection) throws IOException {
-        if (connection instanceof HttpURLConnection) {
-            ((HttpURLConnection)connection).disconnect();
-        }
-    }
-
-    /**
-     * Returns true if the given directory is a lint project directory.
-     * By default, a project directory is the directory containing a manifest file,
-     * but in Gradle projects for example it's the root gradle directory.
-     *
-     * @param dir the directory to check
-     * @return true if the directory represents a lint project
-     */
-    @SuppressWarnings("MethodMayBeStatic") // Intentionally instance method so it can be overridden
-    public boolean isProjectDirectory(@NonNull File dir) {
-        return LintUtils.isManifestFolder(dir) || Project.isAospFrameworksRelatedProject(dir);
-    }
-
-    /**
-     * Returns whether lint should look for suppress comments. Tools that already do
-     * this on their own can return false here to avoid doing unnecessary work.
-     */
-    public boolean checkForSuppressComments() {
-        return true;
-    }
-
-    /**
-     * Adds in any custom lint rules and returns the result as a new issue registry,
-     * or the same one if no custom rules were found
-     *
-     * @param registry the main registry to add rules to
-     * @return a new registry containing the passed in rules plus any custom rules,
-     *   or the original registry if no custom rules were found
-     */
-    public IssueRegistry addCustomLintRules(@NonNull IssueRegistry registry) {
-        List<File> jarFiles = findGlobalRuleJars();
-
-        if (!jarFiles.isEmpty()) {
-            List<IssueRegistry> registries = Lists.newArrayListWithExpectedSize(jarFiles.size());
-            registries.add(registry);
-            for (File jarFile : jarFiles) {
-                try {
-                    registries.add(JarFileIssueRegistry.get(this, jarFile));
-                } catch (Throwable e) {
-                    log(e, "Could not load custom rule jar file %1$s", jarFile);
-                }
-            }
-            if (registries.size() > 1) { // the first item is the passed in registry itself
-                return new CompositeIssueRegistry(registries);
-            }
-        }
-
-        return registry;
-    }
-
-    /**
-     * Creates a {@link ClassLoader} which can load in a set of Jar files.
-     *
-     * @param urls the URLs
-     * @param parent the parent class loader
-     * @return a new class loader
-     */
-    public ClassLoader createUrlClassLoader(@NonNull URL[] urls, @NonNull ClassLoader parent) {
-        return new URLClassLoader(urls, parent);
-    }
-
-    /**
-     * Returns true if this client supports project resource repository lookup via
-     * {@link #getProjectResources(Project,boolean)}
-     *
-     * @return true if the client can provide project resources
-     */
-    public boolean supportsProjectResources() {
-        return false;
-    }
-
-    /**
-     * Returns the project resources, if available
-     *
-     * @param includeDependencies if true, include merged view of all dependencies
-     * @return the project resources, or null if not available
-     */
-    @Nullable
-    public AbstractResourceRepository getProjectResources(Project project,
-            boolean includeDependencies) {
-        return null;
-    }
-
-    /**
-     * For a lint client which supports resource items (via {@link #supportsProjectResources()})
-     * return a handle for a resource item
-     *
-     * @param item the resource item to look up a location handle for
-     * @return a corresponding handle
-     */
-    @NonNull
-    public Location.Handle createResourceItemHandle(@NonNull ResourceItem item) {
-        return new Location.ResourceItemHandle(item);
-    }
-
-    private ResourceVisibilityLookup.Provider mResourceVisibility;
-
-    /**
-     * Returns a shared {@link ResourceVisibilityLookup.Provider}
-     *
-     * @return a shared provider for looking up resource visibility
-     */
-    @NonNull
-    public ResourceVisibilityLookup.Provider getResourceVisibilityProvider() {
-        if (mResourceVisibility == null) {
-            mResourceVisibility = new ResourceVisibilityLookup.Provider();
-        }
-        return mResourceVisibility;
-    }
-
-    /**
-     * The client name returned by {@link #getClientName()} when running in
-     * Android Studio/IntelliJ IDEA
-     */
-    public static final String CLIENT_STUDIO = "studio";
-
-    /**
-     * The client name returned by {@link #getClientName()} when running in
-     * Gradle
-     */
-    public static final String CLIENT_GRADLE = "gradle";
-
-    /**
-     * The client name returned by {@link #getClientName()} when running in
-     * the CLI (command line interface) version of lint, {@code lint}
-     */
-    public static final String CLIENT_CLI = "cli";
-
-    /**
-     * The client name returned by {@link #getClientName()} when running in
-     * some unknown client
-     */
-    public static final String CLIENT_UNKNOWN = "unknown";
-
-    /** The client name. */
-    @NonNull
-    private static String sClientName = CLIENT_UNKNOWN;
-
-    /**
-     * Returns the name of the embedding client. It could be not just
-     * {@link #CLIENT_STUDIO}, {@link #CLIENT_GRADLE}, {@link #CLIENT_CLI}
-     * etc but other values too as lint is integrated in other embedding contexts.
-     *
-     * @return the name of the embedding client
-     */
-    @NonNull
-    public static String getClientName() {
-        return sClientName;
-    }
-
-    /**
-     * Returns true if the embedding client currently running lint is Android Studio
-     * (or IntelliJ IDEA)
-     *
-     * @return true if running in Android Studio / IntelliJ IDEA
-     */
-    public static boolean isStudio() {
-        return CLIENT_STUDIO.equals(sClientName);
-    }
-
-    /**
-     * Returns true if the embedding client currently running lint is Gradle
-     *
-     * @return true if running in Gradle
-     */
-    public static boolean isGradle() {
-        return CLIENT_GRADLE.equals(sClientName);
-    }
-
-    @NonNull
-    public ProgressIndicator getRepositoryLogger() {
-        return new LintClient.RepoLogger();
-    }
-
-    private static final class RepoLogger extends ProgressIndicatorAdapter {
-        // Intentionally not logging these: the SDK manager is
-        // logging events such as package.xml parsing
-        //   Parsing /path/to/sdk//build-tools/19.1.0/package.xml
-        //   Parsing /path/to/sdk//build-tools/20.0.0/package.xml
-        //   Parsing /path/to/sdk//build-tools/21.0.0/package.xml
-        // which we don't want to spam on the console.
-        // It's also warning about packages that it's encountering
-        // multiple times etc; that's not something we should include
-        // in lint command line output.
-
-        @Override
-        public void logError(@NonNull String s, @Nullable Throwable e) {
-        }
-
-        @Override
-        public void logInfo(@NonNull String s) {
-        }
-
-        @Override
-        public void logWarning(@NonNull String s, @Nullable Throwable e) {
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java
deleted file mode 100644
index a357003..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java
+++ /dev/null
@@ -1,2862 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import static com.android.SdkConstants.ATTR_IGNORE;
-import static com.android.SdkConstants.CLASS_CONSTRUCTOR;
-import static com.android.SdkConstants.CONSTRUCTOR_NAME;
-import static com.android.SdkConstants.DOT_CLASS;
-import static com.android.SdkConstants.DOT_JAR;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.SdkConstants.FD_GRADLE_WRAPPER;
-import static com.android.SdkConstants.FN_GRADLE_WRAPPER_PROPERTIES;
-import static com.android.SdkConstants.FN_LOCAL_PROPERTIES;
-import static com.android.SdkConstants.FQCN_SUPPRESS_LINT;
-import static com.android.SdkConstants.RES_FOLDER;
-import static com.android.SdkConstants.SUPPRESS_ALL;
-import static com.android.SdkConstants.SUPPRESS_LINT;
-import static com.android.SdkConstants.TOOLS_URI;
-import static com.android.ide.common.resources.configuration.FolderConfiguration.QUALIFIER_SPLITTER;
-import static com.android.tools.klint.detector.api.LintUtils.isAnonymousClass;
-import static java.io.File.separator;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.repository.ResourceVisibilityLookup;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceFolderType;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.tools.klint.client.api.LintListener.EventType;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.ResourceContext;
-import com.android.tools.klint.detector.api.ResourceXmlDetector;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiAnnotationMemberValue;
-import com.intellij.psi.PsiAnnotationParameterList;
-import com.intellij.psi.PsiArrayInitializerExpression;
-import com.intellij.psi.PsiArrayInitializerMemberValue;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiLiteral;
-import com.intellij.psi.PsiModifierList;
-import com.intellij.psi.PsiModifierListOwner;
-import com.intellij.psi.PsiNameValuePair;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.org.objectweb.asm.ClassReader;
-import org.jetbrains.org.objectweb.asm.Opcodes;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.AnnotationNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.FieldNode;
-import org.jetbrains.org.objectweb.asm.tree.InsnList;
-import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import lombok.ast.Annotation;
-import lombok.ast.AnnotationElement;
-import lombok.ast.AnnotationMethodDeclaration;
-import lombok.ast.AnnotationValue;
-import lombok.ast.ArrayInitializer;
-import lombok.ast.ConstructorDeclaration;
-import lombok.ast.Expression;
-import lombok.ast.MethodDeclaration;
-import lombok.ast.Modifiers;
-import lombok.ast.Node;
-import lombok.ast.StrictListAccessor;
-import lombok.ast.StringLiteral;
-import lombok.ast.TypeDeclaration;
-import lombok.ast.TypeReference;
-import lombok.ast.VariableDefinition;
-
-/**
- * Analyzes Android projects and files
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class LintDriver {
-    /**
-     * Max number of passes to run through the lint runner if requested by
-     * {@link #requestRepeat}
-     */
-    private static final int MAX_PHASES = 3;
-    private static final String SUPPRESS_LINT_VMSIG = '/' + SUPPRESS_LINT + ';';
-    /** Prefix used by the comment suppress mechanism in Studio/IntelliJ */
-    private static final String STUDIO_ID_PREFIX = "AndroidLint";
-
-    private final LintClient mClient;
-    private LintRequest mRequest;
-    private IssueRegistry mRegistry;
-    private volatile boolean mCanceled;
-    private EnumSet<Scope> mScope;
-    private List<? extends Detector> mApplicableDetectors;
-    private Map<Scope, List<Detector>> mScopeDetectors;
-    private List<LintListener> mListeners;
-    private int mPhase;
-    private List<Detector> mRepeatingDetectors;
-    private EnumSet<Scope> mRepeatScope;
-    private Project[] mCurrentProjects;
-    private Project mCurrentProject;
-    private boolean mAbbreviating = true;
-    private boolean mParserErrors;
-    private Map<Object,Object> mProperties;
-    /** Whether we need to look for legacy (old Lombok-based Java API) detectors */
-    private boolean mRunCompatChecks = true;
-
-    /**
-     * Creates a new {@link LintDriver}
-     *
-     * @param registry The registry containing issues to be checked
-     * @param client the tool wrapping the analyzer, such as an IDE or a CLI
-     */
-    public LintDriver(@NonNull IssueRegistry registry, @NonNull LintClient client) {
-        mRegistry = registry;
-        mClient = new LintClientWrapper(client);
-    }
-
-    /** Cancels the current lint run as soon as possible */
-    public void cancel() {
-        mCanceled = true;
-    }
-
-    /**
-     * Returns the scope for the lint job
-     *
-     * @return the scope, never null
-     */
-    @NonNull
-    public EnumSet<Scope> getScope() {
-        return mScope;
-    }
-
-    /**
-     * Sets the scope for the lint job
-     *
-     * @param scope the scope to use
-     */
-    public void setScope(@NonNull EnumSet<Scope> scope) {
-        mScope = scope;
-    }
-
-    /**
-     * Returns the lint client requesting the lint check. This may not be the same
-     * instance as the one passed in to this driver; lint uses a wrapper which performs
-     * additional validation to ensure that for example badly behaved detectors which report
-     * issues that have been disabled will get muted without the real lint client getting
-     * notified. Thus, this {@link LintClient} is suitable for use by detectors to look
-     * up a client to for example get location handles from, but tool handling code should
-     * never try to cast this client back to their original lint client. For the original
-     * lint client, use {@link LintRequest} instead.
-     *
-     * @return the client, never null
-     */
-    @NonNull
-    public LintClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns the current request, which points to the original files to be checked,
-     * the original scope, the original {@link LintClient}, as well as the release mode.
-     *
-     * @return the request
-     */
-    @NonNull
-    public LintRequest getRequest() {
-        return mRequest;
-    }
-
-    /**
-     * Records a property for later retrieval by {@link #getProperty(Object)}
-     *
-     * @param key the key to associate the value with
-     * @param value the value, or null to remove a previous binding
-     */
-    public void putProperty(@NonNull Object key, @Nullable Object value) {
-        if (mProperties == null) {
-            mProperties = Maps.newHashMap();
-        }
-        if (value == null) {
-            mProperties.remove(key);
-        } else {
-            mProperties.put(key, value);
-        }
-    }
-
-    /**
-     * Returns the property previously stored with the given key, or null
-     *
-     * @param key the key
-     * @return the value or null if not found
-     */
-    @Nullable
-    public Object getProperty(@NonNull Object key) {
-        if (mProperties != null) {
-            return mProperties.get(key);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the current phase number. The first pass is numbered 1. Only one pass
-     * will be performed, unless a {@link Detector} calls {@link #requestRepeat}.
-     *
-     * @return the current phase, usually 1
-     */
-    public int getPhase() {
-        return mPhase;
-    }
-
-    /**
-     * Returns the current {@link IssueRegistry}.
-     *
-     * @return the current {@link IssueRegistry}
-     */
-    @NonNull
-    public IssueRegistry getRegistry() {
-        return mRegistry;
-    }
-
-    /**
-     * Returns the project containing a given file, or null if not found. This searches
-     * only among the currently checked project and its library projects, not among all
-     * possible projects being scanned sequentially.
-     *
-     * @param file the file to be checked
-     * @return the corresponding project, or null if not found
-     */
-    @Nullable
-    public Project findProjectFor(@NonNull File file) {
-        if (mCurrentProjects != null) {
-            if (mCurrentProjects.length == 1) {
-                return mCurrentProjects[0];
-            }
-            String path = file.getPath();
-            for (Project project : mCurrentProjects) {
-                if (path.startsWith(project.getDir().getPath())) {
-                    return project;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets whether lint should abbreviate output when appropriate.
-     *
-     * @param abbreviating true to abbreviate output, false to include everything
-     */
-    public void setAbbreviating(boolean abbreviating) {
-        mAbbreviating = abbreviating;
-    }
-
-    /**
-     * Returns whether lint should abbreviate output when appropriate.
-     *
-     * @return true if lint should abbreviate output, false when including everything
-     */
-    public boolean isAbbreviating() {
-        return mAbbreviating;
-    }
-
-    /**
-     * Returns whether lint has encountered any files with fatal parser errors
-     * (e.g. broken source code, or even broken parsers)
-     * <p>
-     * This is useful for checks that need to make sure they've seen all data in
-     * order to be conclusive (such as an unused resource check).
-     *
-     * @return true if any files were not properly processed because they
-     *         contained parser errors
-     */
-    public boolean hasParserErrors() {
-        return mParserErrors;
-    }
-
-    /**
-     * Sets whether lint has encountered files with fatal parser errors.
-     *
-     * @see #hasParserErrors()
-     * @param hasErrors whether parser errors have been encountered
-     */
-    public void setHasParserErrors(boolean hasErrors) {
-        mParserErrors = hasErrors;
-    }
-
-    /**
-     * Returns the projects being analyzed
-     *
-     * @return the projects being analyzed
-     */
-    @NonNull
-    public List<Project> getProjects() {
-        if (mCurrentProjects != null) {
-            return Arrays.asList(mCurrentProjects);
-        }
-        return Collections.emptyList();
-    }
-
-    /**
-     * Analyze the given file (which can point to an Android project). Issues found
-     * are reported to the associated {@link LintClient}.
-     *
-     * @param files the files and directories to be analyzed
-     * @param scope the scope of the analysis; detectors with a wider scope will
-     *            not be run. If null, the scope will be inferred from the files.
-     * @deprecated use {@link #analyze(LintRequest) instead}
-     */
-    @Deprecated
-    public void analyze(@NonNull List<File> files, @Nullable EnumSet<Scope> scope) {
-        analyze(new LintRequest(mClient, files).setScope(scope));
-    }
-
-    /**
-     * Analyze the given files (which can point to Android projects or directories
-     * containing Android projects). Issues found are reported to the associated
-     * {@link LintClient}.
-     * <p>
-     * Note that the {@link LintDriver} is not multi thread safe or re-entrant;
-     * if you want to run potentially overlapping lint jobs, create a separate driver
-     * for each job.
-     *
-     * @param request the files and directories to be analyzed
-     */
-    public void analyze(@NonNull LintRequest request) {
-        try {
-            mRequest = request;
-            analyze();
-        } finally {
-            mRequest = null;
-        }
-    }
-
-    /** Runs the driver to analyze the requested files */
-    private void analyze() {
-        mCanceled = false;
-        mScope = mRequest.getScope();
-        assert mScope == null || !mScope.contains(Scope.ALL_RESOURCE_FILES) ||
-                mScope.contains(Scope.RESOURCE_FILE);
-
-        Collection<Project> projects;
-        try {
-            projects = mRequest.getProjects();
-            if (projects == null) {
-                projects = computeProjects(mRequest.getFiles());
-            }
-        } catch (CircularDependencyException e) {
-            mCurrentProject = e.getProject();
-            if (mCurrentProject != null) {
-                Location location = e.getLocation();
-                File file = location != null ? location.getFile() : mCurrentProject.getDir();
-                Context context = new Context(this, mCurrentProject, null, file);
-                context.report(IssueRegistry.LINT_ERROR, e.getLocation(), e.getMessage());
-                mCurrentProject = null;
-            }
-            return;
-        }
-        if (projects.isEmpty()) {
-            mClient.log(null, "No projects found for %1$s", mRequest.getFiles().toString());
-            return;
-        }
-        if (mCanceled) {
-            return;
-        }
-
-        if (mScope == null) {
-            mScope = Scope.infer(projects);
-        }
-
-        fireEvent(EventType.STARTING, null);
-
-        for (Project project : projects) {
-            mPhase = 1;
-
-            Project main = mRequest.getMainProject(project);
-
-            // The set of available detectors varies between projects
-            computeDetectors(project);
-
-            if (mApplicableDetectors.isEmpty()) {
-                // No detectors enabled in this project: skip it
-                continue;
-            }
-
-            checkProject(project, main);
-            if (mCanceled) {
-                break;
-            }
-
-            runExtraPhases(project, main);
-        }
-
-        fireEvent(mCanceled ? EventType.CANCELED : EventType.COMPLETED, null);
-    }
-
-    @Nullable
-    private Set<Issue> myCustomIssues;
-
-    /**
-     * Returns true if the given issue is an issue that was loaded as a custom rule
-     * (e.g. a 3rd-party library provided the detector, it's not built in)
-     *
-     * @param issue the issue to be looked up
-     * @return true if this is a custom (non-builtin) check
-     */
-    public boolean isCustomIssue(@NonNull Issue issue) {
-        return myCustomIssues != null && myCustomIssues.contains(issue);
-    }
-
-    private void registerCustomDetectors(Collection<Project> projects) {
-        // Look at the various projects, and if any of them provide a custom
-        // lint jar, "add" them (this will replace the issue registry with
-        // a CompositeIssueRegistry containing the original issue registry
-        // plus JarFileIssueRegistry instances for each lint jar
-        Set<File> jarFiles = Sets.newHashSet();
-        for (Project project : projects) {
-            jarFiles.addAll(mClient.findRuleJars(project));
-            for (Project library : project.getAllLibraries()) {
-                jarFiles.addAll(mClient.findRuleJars(library));
-            }
-        }
-
-        jarFiles.addAll(mClient.findGlobalRuleJars());
-
-        if (!jarFiles.isEmpty()) {
-            List<IssueRegistry> registries = Lists.newArrayListWithExpectedSize(jarFiles.size());
-            registries.add(mRegistry);
-            for (File jarFile : jarFiles) {
-                try {
-                    JarFileIssueRegistry registry = JarFileIssueRegistry.get(mClient, jarFile);
-                    if (registry.hasLegacyDetectors()) {
-                        mRunCompatChecks = true;
-                    }
-                    if (myCustomIssues == null) {
-                        myCustomIssues = Sets.newHashSet();
-                    }
-                    myCustomIssues.addAll(registry.getIssues());
-                    registries.add(registry);
-                } catch (Throwable e) {
-                    mClient.log(e, "Could not load custom rule jar file %1$s", jarFile);
-                }
-            }
-            if (registries.size() > 1) { // the first item is mRegistry itself
-                mRegistry = new CompositeIssueRegistry(registries);
-            }
-        }
-    }
-
-    private void runExtraPhases(@NonNull Project project, @NonNull Project main) {
-        // Did any detectors request another phase?
-        if (mRepeatingDetectors != null) {
-            // Yes. Iterate up to MAX_PHASES times.
-
-            // During the extra phases, we might be narrowing the scope, and setting it in the
-            // scope field such that detectors asking about the available scope will get the
-            // correct result. However, we need to restore it to the original scope when this
-            // is done in case there are other projects that will be checked after this, since
-            // the repeated phases is done *per project*, not after all projects have been
-            // processed.
-            EnumSet<Scope> oldScope = mScope;
-
-            do {
-                mPhase++;
-                fireEvent(EventType.NEW_PHASE,
-                        new Context(this, project, null, project.getDir()));
-
-                // Narrow the scope down to the set of scopes requested by
-                // the rules.
-                if (mRepeatScope == null) {
-                    mRepeatScope = Scope.ALL;
-                }
-                mScope = Scope.intersect(mScope, mRepeatScope);
-                if (mScope.isEmpty()) {
-                    break;
-                }
-
-                // Compute the detectors to use for this pass.
-                // Unlike the normal computeDetectors(project) call,
-                // this is going to use the existing instances, and include
-                // those that apply for the configuration.
-                computeRepeatingDetectors(mRepeatingDetectors, project);
-
-                if (mApplicableDetectors.isEmpty()) {
-                    // No detectors enabled in this project: skip it
-                    continue;
-                }
-
-                checkProject(project, main);
-                if (mCanceled) {
-                    break;
-                }
-            } while (mPhase < MAX_PHASES && mRepeatingDetectors != null);
-
-            mScope = oldScope;
-        }
-    }
-
-    private void computeRepeatingDetectors(List<Detector> detectors, Project project) {
-        // Ensure that the current visitor is recomputed
-        mCurrentFolderType = null;
-        mCurrentVisitor = null;
-        mCurrentXmlDetectors = null;
-        mCurrentBinaryDetectors = null;
-
-        // Create map from detector class to issue such that we can
-        // compute applicable issues for each detector in the list of detectors
-        // to be repeated
-        List<Issue> issues = mRegistry.getIssues();
-        Multimap<Class<? extends Detector>, Issue> issueMap =
-                ArrayListMultimap.create(issues.size(), 3);
-        for (Issue issue : issues) {
-            issueMap.put(issue.getImplementation().getDetectorClass(), issue);
-        }
-
-        Map<Class<? extends Detector>, EnumSet<Scope>> detectorToScope =
-                new HashMap<Class<? extends Detector>, EnumSet<Scope>>();
-        Map<Scope, List<Detector>> scopeToDetectors =
-                new EnumMap<Scope, List<Detector>>(Scope.class);
-
-        List<Detector> detectorList = new ArrayList<Detector>();
-        // Compute the list of detectors (narrowed down from mRepeatingDetectors),
-        // and simultaneously build up the detectorToScope map which tracks
-        // the scopes each detector is affected by (this is used to populate
-        // the mScopeDetectors map which is used during iteration).
-        Configuration configuration = project.getConfiguration(this);
-        for (Detector detector : detectors) {
-            Class<? extends Detector> detectorClass = detector.getClass();
-            Collection<Issue> detectorIssues = issueMap.get(detectorClass);
-            if (detectorIssues != null) {
-                boolean add = false;
-                for (Issue issue : detectorIssues) {
-                    // The reason we have to check whether the detector is enabled
-                    // is that this is a per-project property, so when running lint in multiple
-                    // projects, a detector enabled only in a different project could have
-                    // requested another phase, and we end up in this project checking whether
-                    // the detector is enabled here.
-                    if (!configuration.isEnabled(issue)) {
-                        continue;
-                    }
-
-                    add = true; // Include detector if any of its issues are enabled
-
-                    EnumSet<Scope> s = detectorToScope.get(detectorClass);
-                    EnumSet<Scope> issueScope = issue.getImplementation().getScope();
-                    if (s == null) {
-                        detectorToScope.put(detectorClass, issueScope);
-                    } else if (!s.containsAll(issueScope)) {
-                        EnumSet<Scope> union = EnumSet.copyOf(s);
-                        union.addAll(issueScope);
-                        detectorToScope.put(detectorClass, union);
-                    }
-                }
-
-                if (add) {
-                    detectorList.add(detector);
-                    EnumSet<Scope> union = detectorToScope.get(detector.getClass());
-                    for (Scope s : union) {
-                        List<Detector> list = scopeToDetectors.get(s);
-                        if (list == null) {
-                            list = new ArrayList<Detector>();
-                            scopeToDetectors.put(s, list);
-                        }
-                        list.add(detector);
-                    }
-                }
-            }
-        }
-
-        mApplicableDetectors = detectorList;
-        mScopeDetectors = scopeToDetectors;
-        mRepeatingDetectors = null;
-        mRepeatScope = null;
-
-        validateScopeList();
-    }
-
-    private void computeDetectors(@NonNull Project project) {
-        // Ensure that the current visitor is recomputed
-        mCurrentFolderType = null;
-        mCurrentVisitor = null;
-
-        Configuration configuration = project.getConfiguration(this);
-        mScopeDetectors = new EnumMap<Scope, List<Detector>>(Scope.class);
-        mApplicableDetectors = mRegistry.createDetectors(mClient, configuration,
-                mScope, mScopeDetectors);
-
-        validateScopeList();
-    }
-
-    /** Development diagnostics only, run with assertions on */
-    @SuppressWarnings("all") // Turn off warnings for the intentional assertion side effect below
-    private void validateScopeList() {
-        boolean assertionsEnabled = false;
-        assert assertionsEnabled = true; // Intentional side-effect
-        if (assertionsEnabled) {
-            List<Detector> resourceFileDetectors = mScopeDetectors.get(Scope.RESOURCE_FILE);
-            if (resourceFileDetectors != null) {
-                for (Detector detector : resourceFileDetectors) {
-                    // This is wrong; it should allow XmlScanner instead of ResourceXmlScanner!
-                    assert detector instanceof ResourceXmlDetector : detector;
-                }
-            }
-
-            List<Detector> manifestDetectors = mScopeDetectors.get(Scope.MANIFEST);
-            if (manifestDetectors != null) {
-                for (Detector detector : manifestDetectors) {
-                    assert detector instanceof Detector.XmlScanner : detector;
-                }
-            }
-            List<Detector> javaCodeDetectors = mScopeDetectors.get(Scope.ALL_JAVA_FILES);
-            if (javaCodeDetectors != null) {
-                for (Detector detector : javaCodeDetectors) {
-                    assert detector instanceof Detector.JavaScanner ||
-                            // TODO: Migrate all
-                            detector instanceof Detector.UastScanner ||
-                            detector instanceof Detector.JavaPsiScanner : detector;
-                }
-            }
-            List<Detector> javaFileDetectors = mScopeDetectors.get(Scope.JAVA_FILE);
-            if (javaFileDetectors != null) {
-                for (Detector detector : javaFileDetectors) {
-                    assert detector instanceof Detector.JavaScanner ||
-                            // TODO: Migrate all
-                            detector instanceof Detector.UastScanner ||
-                            detector instanceof Detector.JavaPsiScanner : detector;
-                }
-            }
-
-            List<Detector> classDetectors = mScopeDetectors.get(Scope.CLASS_FILE);
-            if (classDetectors != null) {
-                for (Detector detector : classDetectors) {
-                    assert detector instanceof Detector.ClassScanner : detector;
-                }
-            }
-
-            List<Detector> classCodeDetectors = mScopeDetectors.get(Scope.ALL_CLASS_FILES);
-            if (classCodeDetectors != null) {
-                for (Detector detector : classCodeDetectors) {
-                    assert detector instanceof Detector.ClassScanner : detector;
-                }
-            }
-
-            List<Detector> gradleDetectors = mScopeDetectors.get(Scope.GRADLE_FILE);
-            if (gradleDetectors != null) {
-                for (Detector detector : gradleDetectors) {
-                    assert detector instanceof Detector.GradleScanner : detector;
-                }
-            }
-
-            List<Detector> otherDetectors = mScopeDetectors.get(Scope.OTHER);
-            if (otherDetectors != null) {
-                for (Detector detector : otherDetectors) {
-                    assert detector instanceof Detector.OtherFileScanner : detector;
-                }
-            }
-
-            List<Detector> dirDetectors = mScopeDetectors.get(Scope.RESOURCE_FOLDER);
-            if (dirDetectors != null) {
-                for (Detector detector : dirDetectors) {
-                    assert detector instanceof Detector.ResourceFolderScanner : detector;
-                }
-            }
-
-            List<Detector> binaryDetectors = mScopeDetectors.get(Scope.BINARY_RESOURCE_FILE);
-            if (binaryDetectors != null) {
-                for (Detector detector : binaryDetectors) {
-                    assert detector instanceof Detector.BinaryResourceScanner : detector;
-                }
-            }
-        }
-    }
-
-    private void registerProjectFile(
-            @NonNull Map<File, Project> fileToProject,
-            @NonNull File file,
-            @NonNull File projectDir,
-            @NonNull File rootDir) {
-        fileToProject.put(file, mClient.getProject(projectDir, rootDir));
-    }
-
-    private Collection<Project> computeProjects(@NonNull List<File> files) {
-        // Compute list of projects
-        Map<File, Project> fileToProject = new LinkedHashMap<File, Project>();
-
-        File sharedRoot = null;
-
-        // Ensure that we have absolute paths such that if you lint
-        //  "foo bar" in "baz" we can show baz/ as the root
-        List<File> absolute = new ArrayList<File>(files.size());
-        for (File file : files) {
-            absolute.add(file.getAbsoluteFile());
-        }
-        // Always use absoluteFiles so that we can check the file's getParentFile()
-        // which is null if the file is not absolute.
-        files = absolute;
-
-        if (files.size() > 1) {
-            sharedRoot = LintUtils.getCommonParent(files);
-            if (sharedRoot != null && sharedRoot.getParentFile() == null) { // "/" ?
-                sharedRoot = null;
-            }
-        }
-
-        for (File file : files) {
-            if (file.isDirectory()) {
-                File rootDir = sharedRoot;
-                if (rootDir == null) {
-                    rootDir = file;
-                    if (files.size() > 1) {
-                        rootDir = file.getParentFile();
-                        if (rootDir == null) {
-                            rootDir = file;
-                        }
-                    }
-                }
-
-                // Figure out what to do with a directory. Note that the meaning of the
-                // directory can be ambiguous:
-                // If you pass a directory which is unknown, we don't know if we should
-                // search upwards (in case you're pointing at a deep java package folder
-                // within the project), or if you're pointing at some top level directory
-                // containing lots of projects you want to scan. We attempt to do the
-                // right thing, which is to see if you're pointing right at a project or
-                // right within it (say at the src/ or res/) folder, and if not, you're
-                // hopefully pointing at a project tree that you want to scan recursively.
-                if (mClient.isProjectDirectory(file)) {
-                    registerProjectFile(fileToProject, file, file, rootDir);
-                    continue;
-                } else {
-                    File parent = file.getParentFile();
-                    if (parent != null) {
-                        if (mClient.isProjectDirectory(parent)) {
-                            registerProjectFile(fileToProject, file, parent, parent);
-                            continue;
-                        } else {
-                            parent = parent.getParentFile();
-                            if (parent != null && mClient.isProjectDirectory(parent)) {
-                                registerProjectFile(fileToProject, file, parent, parent);
-                                continue;
-                            }
-                        }
-                    }
-
-                    // Search downwards for nested projects
-                    addProjects(file, fileToProject, rootDir);
-                }
-            } else {
-                // Pointed at a file: Search upwards for the containing project
-                File parent = file.getParentFile();
-                while (parent != null) {
-                    if (mClient.isProjectDirectory(parent)) {
-                        registerProjectFile(fileToProject, file, parent, parent);
-                        break;
-                    }
-                    parent = parent.getParentFile();
-                }
-            }
-
-            if (mCanceled) {
-                return Collections.emptySet();
-            }
-        }
-
-        for (Map.Entry<File, Project> entry : fileToProject.entrySet()) {
-            File file = entry.getKey();
-            Project project = entry.getValue();
-            if (!file.equals(project.getDir())) {
-                if (file.isDirectory()) {
-                    try {
-                        File dir = file.getCanonicalFile();
-                        if (dir.equals(project.getDir())) {
-                            continue;
-                        }
-                    } catch (IOException ioe) {
-                        // pass
-                    }
-                }
-
-                project.addFile(file);
-            }
-        }
-
-        // Partition the projects up such that we only return projects that aren't
-        // included by other projects (e.g. because they are library projects)
-
-        Collection<Project> allProjects = fileToProject.values();
-        Set<Project> roots = new HashSet<Project>(allProjects);
-        for (Project project : allProjects) {
-            roots.removeAll(project.getAllLibraries());
-        }
-
-        // Report issues for all projects that are explicitly referenced. We need to
-        // do this here, since the project initialization will mark all library
-        // projects as no-report projects by default.
-        for (Project project : allProjects) {
-            // Report issues for all projects explicitly listed or found via a directory
-            // traversal -- including library projects.
-            project.setReportIssues(true);
-        }
-
-        if (LintUtils.assertionsEnabled()) {
-            // Make sure that all the project directories are unique. This ensures
-            // that we didn't accidentally end up with different project instances
-            // for a library project discovered as a directory as well as one
-            // initialized from the library project dependency list
-            IdentityHashMap<Project, Project> projects =
-                    new IdentityHashMap<Project, Project>();
-            for (Project project : roots) {
-                projects.put(project, project);
-                for (Project library : project.getAllLibraries()) {
-                    projects.put(library, library);
-                }
-            }
-            Set<File> dirs = new HashSet<File>();
-            for (Project project : projects.keySet()) {
-                assert !dirs.contains(project.getDir());
-                dirs.add(project.getDir());
-            }
-        }
-
-        return roots;
-    }
-
-    private void addProjects(
-            @NonNull File dir,
-            @NonNull Map<File, Project> fileToProject,
-            @NonNull File rootDir) {
-        if (mCanceled) {
-            return;
-        }
-
-        if (mClient.isProjectDirectory(dir)) {
-            registerProjectFile(fileToProject, dir, dir, rootDir);
-        } else {
-            File[] files = dir.listFiles();
-            if (files != null) {
-                for (File file : files) {
-                    if (file.isDirectory()) {
-                        addProjects(file, fileToProject, rootDir);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkProject(@NonNull Project project, @NonNull Project main) {
-        File projectDir = project.getDir();
-
-        Context projectContext = new Context(this, project, null, projectDir);
-        fireEvent(EventType.SCANNING_PROJECT, projectContext);
-
-        List<Project> allLibraries = project.getAllLibraries();
-        Set<Project> allProjects = new HashSet<Project>(allLibraries.size() + 1);
-        allProjects.add(project);
-        allProjects.addAll(allLibraries);
-        mCurrentProjects = allProjects.toArray(new Project[allProjects.size()]);
-
-        mCurrentProject = project;
-
-        for (Detector check : mApplicableDetectors) {
-            check.beforeCheckProject(projectContext);
-            if (mCanceled) {
-                return;
-            }
-        }
-
-        assert mCurrentProject == project;
-        runFileDetectors(project, main);
-
-        if (!Scope.checkSingleFile(mScope)) {
-            List<Project> libraries = project.getAllLibraries();
-            for (Project library : libraries) {
-                Context libraryContext = new Context(this, library, project, projectDir);
-                fireEvent(EventType.SCANNING_LIBRARY_PROJECT, libraryContext);
-                mCurrentProject = library;
-
-                for (Detector check : mApplicableDetectors) {
-                    check.beforeCheckLibraryProject(libraryContext);
-                    if (mCanceled) {
-                        return;
-                    }
-                }
-                assert mCurrentProject == library;
-
-                runFileDetectors(library, main);
-                if (mCanceled) {
-                    return;
-                }
-
-                assert mCurrentProject == library;
-
-                for (Detector check : mApplicableDetectors) {
-                    check.afterCheckLibraryProject(libraryContext);
-                    if (mCanceled) {
-                        return;
-                    }
-                }
-            }
-        }
-
-        mCurrentProject = project;
-
-        for (Detector check : mApplicableDetectors) {
-            check.afterCheckProject(projectContext);
-            if (mCanceled) {
-                return;
-            }
-        }
-
-        if (mCanceled) {
-            mClient.report(
-                projectContext,
-                    // Must provide an issue since API guarantees that the issue parameter
-                IssueRegistry.CANCELLED,
-                Severity.INFORMATIONAL,
-                Location.create(project.getDir()),
-                "Lint canceled by user", TextFormat.RAW);
-        }
-
-        mCurrentProjects = null;
-    }
-
-    private void runFileDetectors(@NonNull Project project, @Nullable Project main) {
-        // Look up manifest information (but not for library projects)
-        if (project.isAndroidProject()) {
-            for (File manifestFile : project.getManifestFiles()) {
-                XmlParser parser = mClient.getXmlParser();
-                if (parser != null) {
-                    XmlContext context = new XmlContext(this, project, main, manifestFile, null,
-                            parser);
-                    context.document = parser.parseXml(context);
-                    if (context.document != null) {
-                        try {
-                            project.readManifest(context.document);
-
-                            if ((!project.isLibrary() || (main != null
-                                    && main.isMergingManifests()))
-                                    && mScope.contains(Scope.MANIFEST)) {
-                                List<Detector> detectors = mScopeDetectors.get(Scope.MANIFEST);
-                                if (detectors != null) {
-                                    ResourceVisitor v = new ResourceVisitor(parser, detectors,
-                                            null);
-                                    fireEvent(EventType.SCANNING_FILE, context);
-                                    v.visitFile(context, manifestFile);
-                                }
-                            }
-                        } finally {
-                          if (context.document != null) { // else: freed by XmlVisitor above
-                              parser.dispose(context, context.document);
-                          }
-                        }
-                    }
-                }
-            }
-
-            // Process both Scope.RESOURCE_FILE and Scope.ALL_RESOURCE_FILES detectors together
-            // in a single pass through the resource directories.
-            if (mScope.contains(Scope.ALL_RESOURCE_FILES)
-                    || mScope.contains(Scope.RESOURCE_FILE)
-                    || mScope.contains(Scope.RESOURCE_FOLDER)
-                    || mScope.contains(Scope.BINARY_RESOURCE_FILE)) {
-                List<Detector> dirChecks = mScopeDetectors.get(Scope.RESOURCE_FOLDER);
-                List<Detector> binaryChecks = mScopeDetectors.get(Scope.BINARY_RESOURCE_FILE);
-                List<Detector> checks = union(mScopeDetectors.get(Scope.RESOURCE_FILE),
-                        mScopeDetectors.get(Scope.ALL_RESOURCE_FILES));
-                boolean haveXmlChecks = checks != null && !checks.isEmpty();
-                List<ResourceXmlDetector> xmlDetectors;
-                if (haveXmlChecks) {
-                    xmlDetectors = new ArrayList<ResourceXmlDetector>(checks.size());
-                    for (Detector detector : checks) {
-                        if (detector instanceof ResourceXmlDetector) {
-                            xmlDetectors.add((ResourceXmlDetector) detector);
-                        }
-                    }
-                    haveXmlChecks = !xmlDetectors.isEmpty();
-                } else {
-                    xmlDetectors = Collections.emptyList();
-                }
-                if (haveXmlChecks
-                        || dirChecks != null && !dirChecks.isEmpty()
-                        || binaryChecks != null && !binaryChecks.isEmpty()) {
-                    List<File> files = project.getSubset();
-                    if (files != null) {
-                        checkIndividualResources(project, main, xmlDetectors, dirChecks,
-                                binaryChecks, files);
-                    } else {
-                        List<File> resourceFolders = project.getResourceFolders();
-                        if (!resourceFolders.isEmpty()) {
-                            for (File res : resourceFolders) {
-                                checkResFolder(project, main, res, xmlDetectors, dirChecks,
-                                        binaryChecks);
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (mCanceled) {
-                return;
-            }
-        }
-
-        if (mScope.contains(Scope.JAVA_FILE) || mScope.contains(Scope.ALL_JAVA_FILES)) {
-            List<Detector> checks = union(mScopeDetectors.get(Scope.JAVA_FILE),
-                    mScopeDetectors.get(Scope.ALL_JAVA_FILES));
-            if (checks != null && !checks.isEmpty()) {
-                List<File> files = project.getSubset();
-                if (files != null) {
-                    checkIndividualJavaFiles(project, main, checks, files);
-                } else {
-                    List<File> sourceFolders = project.getJavaSourceFolders();
-                    if (mScope.contains(Scope.TEST_SOURCES)) {
-                        List<File> testFolders = project.getTestSourceFolders();
-                        if (!testFolders.isEmpty()) {
-                            List<File> combined = Lists.newArrayListWithExpectedSize(
-                                    sourceFolders.size() + testFolders.size());
-                            combined.addAll(sourceFolders);
-                            combined.addAll(testFolders);
-                            sourceFolders = combined;
-                        }
-                    }
-
-                    checkJava(project, main, sourceFolders, checks);
-
-                }
-            }
-        }
-
-        if (mCanceled) {
-            return;
-        }
-
-        if (mScope.contains(Scope.CLASS_FILE)
-                || mScope.contains(Scope.ALL_CLASS_FILES)
-                || mScope.contains(Scope.JAVA_LIBRARIES)) {
-            checkClasses(project, main);
-        }
-
-        if (mCanceled) {
-            return;
-        }
-
-        if (mScope.contains(Scope.GRADLE_FILE)) {
-            checkBuildScripts(project, main);
-        }
-
-        if (mCanceled) {
-            return;
-        }
-
-        if (mScope.contains(Scope.OTHER)) {
-            List<Detector> checks = mScopeDetectors.get(Scope.OTHER);
-            if (checks != null) {
-                OtherFileVisitor visitor = new OtherFileVisitor(checks);
-                visitor.scan(this, project, main);
-            }
-        }
-
-        if (mCanceled) {
-            return;
-        }
-
-        if (project == main && mScope.contains(Scope.PROGUARD_FILE) &&
-                project.isAndroidProject()) {
-            checkProGuard(project, main);
-        }
-
-        if (project == main && mScope.contains(Scope.PROPERTY_FILE)) {
-            checkProperties(project, main);
-        }
-    }
-
-    private void checkBuildScripts(Project project, Project main) {
-        List<Detector> detectors = mScopeDetectors.get(Scope.GRADLE_FILE);
-        if (detectors != null) {
-            List<File> files = project.getSubset();
-            if (files == null) {
-                files = project.getGradleBuildScripts();
-            }
-            for (File file : files) {
-                Context context = new Context(this, project, main, file);
-                fireEvent(EventType.SCANNING_FILE, context);
-                for (Detector detector : detectors) {
-                    if (detector.appliesTo(context, file)) {
-                        detector.beforeCheckFile(context);
-                        detector.visitBuildScript(context, Maps.<String, Object>newHashMap());
-                        detector.afterCheckFile(context);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkProGuard(Project project, Project main) {
-        List<Detector> detectors = mScopeDetectors.get(Scope.PROGUARD_FILE);
-        if (detectors != null) {
-            List<File> files = project.getProguardFiles();
-            for (File file : files) {
-                Context context = new Context(this, project, main, file);
-                fireEvent(EventType.SCANNING_FILE, context);
-                for (Detector detector : detectors) {
-                    if (detector.appliesTo(context, file)) {
-                        detector.beforeCheckFile(context);
-                        detector.run(context);
-                        detector.afterCheckFile(context);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkProperties(Project project, Project main) {
-        List<Detector> detectors = mScopeDetectors.get(Scope.PROPERTY_FILE);
-        if (detectors != null) {
-            checkPropertyFile(project, main, detectors, FN_LOCAL_PROPERTIES);
-            checkPropertyFile(project, main, detectors, FD_GRADLE_WRAPPER + separator +
-                    FN_GRADLE_WRAPPER_PROPERTIES);
-        }
-    }
-
-    private void checkPropertyFile(Project project, Project main, List<Detector> detectors,
-            String relativePath) {
-        File file = new File(project.getDir(), relativePath);
-        if (file.exists()) {
-            Context context = new Context(this, project, main, file);
-            fireEvent(EventType.SCANNING_FILE, context);
-            for (Detector detector : detectors) {
-                if (detector.appliesTo(context, file)) {
-                    detector.beforeCheckFile(context);
-                    detector.run(context);
-                    detector.afterCheckFile(context);
-                }
-            }
-        }
-    }
-
-    /** True if execution has been canceled */
-    boolean isCanceled() {
-        return mCanceled;
-    }
-
-    /**
-     * Returns the super class for the given class name,
-     * which should be in VM format (e.g. java/lang/Integer, not java.lang.Integer).
-     * If the super class is not known, returns null. This can happen if
-     * the given class is not a known class according to the project or its
-     * libraries, for example because it refers to one of the core libraries which
-     * are not analyzed by lint.
-     *
-     * @param name the fully qualified class name
-     * @return the corresponding super class name (in VM format), or null if not known
-     */
-    @Nullable
-    public String getSuperClass(@NonNull String name) {
-        return mClient.getSuperClass(mCurrentProject, name);
-    }
-
-    /**
-     * Returns true if the given class is a subclass of the given super class.
-     *
-     * @param classNode the class to check whether it is a subclass of the given
-     *            super class name
-     * @param superClassName the fully qualified super class name (in VM format,
-     *            e.g. java/lang/Integer, not java.lang.Integer.
-     * @return true if the given class is a subclass of the given super class
-     */
-    public boolean isSubclassOf(@NonNull ClassNode classNode, @NonNull String superClassName) {
-        if (superClassName.equals(classNode.superName)) {
-            return true;
-        }
-
-        if (mCurrentProject != null) {
-            Boolean isSub = mClient.isSubclassOf(mCurrentProject, classNode.name, superClassName);
-            if (isSub != null) {
-                return isSub;
-            }
-        }
-
-        String className = classNode.name;
-        while (className != null) {
-            if (className.equals(superClassName)) {
-                return true;
-            }
-            className = getSuperClass(className);
-        }
-
-        return false;
-    }
-    @Nullable
-    private static List<Detector> union(
-            @Nullable List<Detector> list1,
-            @Nullable List<Detector> list2) {
-        if (list1 == null) {
-            return list2;
-        } else if (list2 == null) {
-            return list1;
-        } else {
-            // Use set to pick out unique detectors, since it's possible for there to be overlap,
-            // e.g. the DuplicateIdDetector registers both a cross-resource issue and a
-            // single-file issue, so it shows up on both scope lists:
-            Set<Detector> set = new HashSet<Detector>(list1.size() + list2.size());
-            set.addAll(list1);
-            set.addAll(list2);
-
-            return new ArrayList<Detector>(set);
-        }
-    }
-
-    /** Check the classes in this project (and if applicable, in any library projects */
-    private void checkClasses(Project project, Project main) {
-        List<File> files = project.getSubset();
-        if (files != null) {
-            checkIndividualClassFiles(project, main, files);
-            return;
-        }
-
-        // We need to read in all the classes up front such that we can initialize
-        // the parent chains (such that for example for a virtual dispatch, we can
-        // also check the super classes).
-
-        List<File> libraries = project.getJavaLibraries(false);
-        List<ClassEntry> libraryEntries = ClassEntry.fromClassPath(mClient, libraries, true);
-
-        List<File> classFolders = project.getJavaClassFolders();
-        List<ClassEntry> classEntries;
-        if (classFolders.isEmpty()) {
-            String message = String.format("No `.class` files were found in project \"%1$s\", "
-                    + "so none of the classfile based checks could be run. "
-                    + "Does the project need to be built first?", project.getName());
-            Location location = Location.create(project.getDir());
-            mClient.report(new Context(this, project, main, project.getDir()),
-                    IssueRegistry.LINT_ERROR,
-                    project.getConfiguration(this).getSeverity(IssueRegistry.LINT_ERROR),
-                    location, message, TextFormat.RAW);
-            classEntries = Collections.emptyList();
-        } else {
-            classEntries = ClassEntry.fromClassPath(mClient, classFolders, true);
-        }
-
-        // Actually run the detectors. Libraries should be called before the
-        // main classes.
-        runClassDetectors(Scope.JAVA_LIBRARIES, libraryEntries, project, main);
-
-        if (mCanceled) {
-            return;
-        }
-
-        runClassDetectors(Scope.CLASS_FILE, classEntries, project, main);
-        runClassDetectors(Scope.ALL_CLASS_FILES, classEntries, project, main);
-    }
-
-    private void checkIndividualClassFiles(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull List<File> files) {
-        List<File> classFiles = Lists.newArrayListWithExpectedSize(files.size());
-        List<File> classFolders = project.getJavaClassFolders();
-        if (!classFolders.isEmpty()) {
-            for (File file : files) {
-                String path = file.getPath();
-                if (file.isFile() && path.endsWith(DOT_CLASS)) {
-                    classFiles.add(file);
-                }
-            }
-        }
-
-        List<ClassEntry> entries = ClassEntry.fromClassFiles(mClient, classFiles, classFolders,
-                true);
-        if (!entries.isEmpty()) {
-            Collections.sort(entries);
-            runClassDetectors(Scope.CLASS_FILE, entries, project, main);
-        }
-    }
-
-    /**
-     * Stack of {@link ClassNode} nodes for outer classes of the currently
-     * processed class, including that class itself. Populated by
-     * {@link #runClassDetectors(Scope, List, Project, Project)} and used by
-     * {@link #getOuterClassNode(ClassNode)}
-     */
-    private Deque<ClassNode> mOuterClasses;
-
-    private void runClassDetectors(Scope scope, List<ClassEntry> entries,
-            Project project, Project main) {
-        if (mScope.contains(scope)) {
-            List<Detector> classDetectors = mScopeDetectors.get(scope);
-            if (classDetectors != null && !classDetectors.isEmpty() && !entries.isEmpty()) {
-                AsmVisitor visitor = new AsmVisitor(mClient, classDetectors);
-
-                String sourceContents = null;
-                String sourceName = "";
-                mOuterClasses = new ArrayDeque<ClassNode>();
-                ClassEntry prev = null;
-                for (ClassEntry entry : entries) {
-                    if (prev != null && prev.compareTo(entry) == 0) {
-                        // Duplicate entries for some reason: ignore
-                        continue;
-                    }
-                    prev = entry;
-
-                    ClassReader reader;
-                    ClassNode classNode;
-                    try {
-                        reader = new ClassReader(entry.bytes);
-                        classNode = new ClassNode();
-                        reader.accept(classNode, 0 /* flags */);
-                    } catch (Throwable t) {
-                        mClient.log(null, "Error processing %1$s: broken class file?",
-                                entry.path());
-                        continue;
-                    }
-
-                    ClassNode peek;
-                    while ((peek = mOuterClasses.peek()) != null) {
-                        if (classNode.name.startsWith(peek.name)) {
-                            break;
-                        } else {
-                            mOuterClasses.pop();
-                        }
-                    }
-                    mOuterClasses.push(classNode);
-
-                    if (isSuppressed(null, classNode)) {
-                        // Class was annotated with suppress all -- no need to look any further
-                        continue;
-                    }
-
-                    if (sourceContents != null) {
-                        // Attempt to reuse the source buffer if initialized
-                        // This means making sure that the source files
-                        //    foo/bar/MyClass and foo/bar/MyClass$Bar
-                        //    and foo/bar/MyClass$3 and foo/bar/MyClass$3$1 have the same prefix.
-                        String newName = classNode.name;
-                        int newRootLength = newName.indexOf('$');
-                        if (newRootLength == -1) {
-                            newRootLength = newName.length();
-                        }
-                        int oldRootLength = sourceName.indexOf('$');
-                        if (oldRootLength == -1) {
-                            oldRootLength = sourceName.length();
-                        }
-                        if (newRootLength != oldRootLength ||
-                                !sourceName.regionMatches(0, newName, 0, newRootLength)) {
-                            sourceContents = null;
-                        }
-                    }
-
-                    ClassContext context = new ClassContext(this, project, main,
-                            entry.file, entry.jarFile, entry.binDir, entry.bytes,
-                            classNode, scope == Scope.JAVA_LIBRARIES /*fromLibrary*/,
-                            sourceContents);
-
-                    try {
-                        visitor.runClassDetectors(context);
-                    } catch (Exception e) {
-                        mClient.log(e, null);
-                    }
-
-                    if (mCanceled) {
-                        return;
-                    }
-
-                    sourceContents = context.getSourceContents(false/*read*/);
-                    sourceName = classNode.name;
-                }
-
-                mOuterClasses = null;
-            }
-        }
-    }
-
-    /** Returns the outer class node of the given class node
-     * @param classNode the inner class node
-     * @return the outer class node */
-    public ClassNode getOuterClassNode(@NonNull ClassNode classNode) {
-        String outerName = classNode.outerClass;
-
-        Iterator<ClassNode> iterator = mOuterClasses.iterator();
-        while (iterator.hasNext()) {
-            ClassNode node = iterator.next();
-            if (outerName != null) {
-                if (node.name.equals(outerName)) {
-                    return node;
-                }
-            } else if (node == classNode) {
-                return iterator.hasNext() ? iterator.next() : null;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the {@link ClassNode} corresponding to the given type, if possible, or null
-     *
-     * @param type the fully qualified type, using JVM signatures (/ and $, not . as path
-     *             separators)
-     * @param flags the ASM flags to pass to the {@link ClassReader}, normally 0 but can
-     *              for example be {@link ClassReader#SKIP_CODE} and/oor
-     *              {@link ClassReader#SKIP_DEBUG}
-     * @return the class node for the type, or null
-     */
-    @Nullable
-    public ClassNode findClass(@NonNull ClassContext context, @NonNull String type, int flags) {
-        String relative = type.replace('/', File.separatorChar) + DOT_CLASS;
-        File classFile = findClassFile(context.getProject(), relative);
-        if (classFile != null) {
-            if (classFile.getPath().endsWith(DOT_JAR)) {
-                // TODO: Handle .jar files
-                return null;
-            }
-
-            try {
-                byte[] bytes = mClient.readBytes(classFile);
-                ClassReader reader = new ClassReader(bytes);
-                ClassNode classNode = new ClassNode();
-                reader.accept(classNode, flags);
-
-                return classNode;
-            } catch (Throwable t) {
-                mClient.log(null, "Error processing %1$s: broken class file?",
-                        classFile.getPath());
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private File findClassFile(@NonNull Project project, String relativePath) {
-        for (File root : mClient.getJavaClassFolders(project)) {
-            File path = new File(root, relativePath);
-            if (path.exists()) {
-                return path;
-            }
-        }
-        // Search in the libraries
-        for (File root : mClient.getJavaLibraries(project, true)) {
-            // TODO: Handle .jar files!
-            //if (root.getPath().endsWith(DOT_JAR)) {
-            //}
-
-            File path = new File(root, relativePath);
-            if (path.exists()) {
-                return path;
-            }
-        }
-
-        // Search dependent projects
-        for (Project library : project.getDirectLibraries()) {
-            File path = findClassFile(library, relativePath);
-            if (path != null) {
-                return path;
-            }
-        }
-
-        return null;
-    }
-
-    private void checkJava(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull List<File> sourceFolders,
-            @NonNull List<Detector> checks) {
-        JavaParser javaParser = mClient.getJavaParser(project);
-        if (javaParser == null) {
-            mClient.log(null, "No java parser provided to lint: not running Java checks");
-            return;
-        }
-
-        assert !checks.isEmpty();
-
-        // Gather all Java source files in a single pass; more efficient.
-        List<File> sources = new ArrayList<File>(100);
-        for (File folder : sourceFolders) {
-            gatherJavaFiles(folder, sources);
-        }
-        if (!sources.isEmpty()) {
-            List<JavaContext> contexts = Lists.newArrayListWithExpectedSize(sources.size());
-            for (File file : sources) {
-                JavaContext context = new JavaContext(this, project, main, file, javaParser);
-                contexts.add(context);
-            }
-            visitJavaFiles(checks, javaParser, contexts);
-        }
-    }
-
-    private void visitJavaFiles(@NonNull List<Detector> checks, JavaParser javaParser,
-            List<JavaContext> contexts) {
-        // Temporary: we still have some builtin checks that aren't migrated to
-        // PSI. Until that's complete, remove them from the list here
-        //List<Detector> scanners = checks;
-        List<Detector> scanners = Lists.newArrayListWithCapacity(0);
-        List<Detector> uastScanners = Lists.newArrayListWithCapacity(checks.size());
-        for (Detector detector : checks) {
-            if (detector instanceof Detector.JavaPsiScanner) {
-                scanners.add(detector);
-            } else if (detector instanceof Detector.UastScanner) {
-                uastScanners.add(detector);
-            }
-        }
-
-        if (!scanners.isEmpty()) {
-            JavaPsiVisitor visitor = new JavaPsiVisitor(javaParser, scanners);
-            visitor.prepare(contexts);
-            for (JavaContext context : contexts) {
-                fireEvent(EventType.SCANNING_FILE, context);
-                visitor.visitFile(context);
-                if (mCanceled) {
-                    return;
-                }
-            }
-
-            visitor.dispose();
-        }
-
-        if (!uastScanners.isEmpty()) {
-            final UElementVisitor uElementVisitor = new UElementVisitor(javaParser, uastScanners);
-            uElementVisitor.prepare(contexts);
-            for (final JavaContext context : contexts) {
-                fireEvent(EventType.SCANNING_FILE, context);
-                ApplicationManager.getApplication().runReadAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        uElementVisitor.visitFile(context);
-                    }
-                });
-                if (mCanceled) {
-                    return;
-                }
-            }
-            
-            uElementVisitor.dispose();
-        }
-
-        // Only if the user is using some custom lint rules that haven't been updated
-        // yet
-        //noinspection ConstantConditions
-        if (mRunCompatChecks) {
-            // Filter the checks to only those that implement JavaScanner
-            List<Detector> filtered = Lists.newArrayListWithCapacity(checks.size());
-            for (Detector detector : checks) {
-                if (detector instanceof Detector.JavaScanner) {
-                    filtered.add(detector);
-                }
-            }
-
-            if (!filtered.isEmpty()) {
-                List<String> detectorNames = Lists.newArrayListWithCapacity(filtered.size());
-                for (Detector detector : filtered) {
-                    detectorNames.add(detector.getClass().getName());
-                }
-                Collections.sort(detectorNames);
-
-                /* Let's not complain quite yet
-                String message = String.format("Lint found one or more custom checks using its "
-                        + "older Java API; these checks are still run in compatibility mode, "
-                        + "but this causes duplicated parsing, and in the next version lint "
-                        + "will no longer include this legacy mode. Make sure the following "
-                        + "lint detectors are upgraded to the new API: %1$s",
-                        Joiner.on(", ").join(detectorNames));
-                JavaContext first = contexts.get(0);
-                Project project = first.getProject();
-                Location location = Location.create(project.getDir());
-                mClient.report(first,
-                        IssueRegistry.LINT_ERROR,
-                        project.getConfiguration(this).getSeverity(IssueRegistry.LINT_ERROR),
-                        location, message, TextFormat.RAW);
-                */
-
-
-                JavaVisitor oldVisitor = new JavaVisitor(javaParser, filtered);
-
-                oldVisitor.prepare(contexts);
-                for (JavaContext context : contexts) {
-                    fireEvent(EventType.SCANNING_FILE, context);
-                    oldVisitor.visitFile(context);
-                    if (mCanceled) {
-                        return;
-                    }
-                }
-                oldVisitor.dispose();
-            }
-        }
-    }
-
-    private void checkIndividualJavaFiles(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull List<Detector> checks,
-            @NonNull List<File> files) {
-
-        JavaParser javaParser = mClient.getJavaParser(project);
-        if (javaParser == null) {
-            mClient.log(null, "No java parser provided to lint: not running Java checks");
-            return;
-        }
-
-        List<JavaContext> contexts = Lists.newArrayListWithExpectedSize(files.size());
-        for (File file : files) {
-            if (file.isFile() && file.getPath().endsWith(".kt")) {
-                contexts.add(new JavaContext(this, project, main, file, javaParser));
-            }
-        }
-
-        if (contexts.isEmpty()) {
-            return;
-        }
-
-        visitJavaFiles(checks, javaParser, contexts);
-    }
-
-    private static void gatherJavaFiles(@NonNull File dir, @NonNull List<File> result) {
-        File[] files = dir.listFiles();
-        if (files != null) {
-            for (File file : files) {
-                if (file.isFile() && file.getName().endsWith(".java")) { //$NON-NLS-1$
-                    result.add(file);
-                } else if (file.isDirectory()) {
-                    gatherJavaFiles(file, result);
-                }
-            }
-        }
-    }
-
-    private ResourceFolderType mCurrentFolderType;
-    private List<ResourceXmlDetector> mCurrentXmlDetectors;
-    private List<Detector> mCurrentBinaryDetectors;
-    private ResourceVisitor mCurrentVisitor;
-
-    @Nullable
-    private ResourceVisitor getVisitor(
-            @NonNull ResourceFolderType type,
-            @NonNull List<ResourceXmlDetector> checks,
-            @Nullable List<Detector> binaryChecks) {
-        if (type != mCurrentFolderType) {
-            mCurrentFolderType = type;
-
-            // Determine which XML resource detectors apply to the given folder type
-            List<ResourceXmlDetector> applicableXmlChecks =
-                    new ArrayList<ResourceXmlDetector>(checks.size());
-            for (ResourceXmlDetector check : checks) {
-                if (check.appliesTo(type)) {
-                    applicableXmlChecks.add(check);
-                }
-            }
-            List<Detector> applicableBinaryChecks = null;
-            if (binaryChecks != null) {
-                applicableBinaryChecks = new ArrayList<Detector>(binaryChecks.size());
-                for (Detector check : binaryChecks) {
-                    if (check.appliesTo(type)) {
-                        applicableBinaryChecks.add(check);
-                    }
-                }
-            }
-
-            // If the list of detectors hasn't changed, then just use the current visitor!
-            if (mCurrentXmlDetectors != null && mCurrentXmlDetectors.equals(applicableXmlChecks)
-                    && Objects.equal(mCurrentBinaryDetectors, applicableBinaryChecks)) {
-                return mCurrentVisitor;
-            }
-
-            mCurrentXmlDetectors = applicableXmlChecks;
-            mCurrentBinaryDetectors = applicableBinaryChecks;
-
-            if (applicableXmlChecks.isEmpty()
-                    && (applicableBinaryChecks == null || applicableBinaryChecks.isEmpty())) {
-                mCurrentVisitor = null;
-                return null;
-            }
-
-            XmlParser parser = mClient.getXmlParser();
-            if (parser != null) {
-                mCurrentVisitor = new ResourceVisitor(parser, applicableXmlChecks,
-                        applicableBinaryChecks);
-            } else {
-                mCurrentVisitor = null;
-            }
-        }
-
-        return mCurrentVisitor;
-    }
-
-    private void checkResFolder(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File res,
-            @NonNull List<ResourceXmlDetector> xmlChecks,
-            @Nullable List<Detector> dirChecks,
-            @Nullable List<Detector> binaryChecks) {
-        File[] resourceDirs = res.listFiles();
-        if (resourceDirs == null) {
-            return;
-        }
-
-        // Sort alphabetically such that we can process related folder types at the
-        // same time, and to have a defined behavior such that detectors can rely on
-        // predictable ordering, e.g. layouts are seen before menus are seen before
-        // values, etc (l < m < v).
-
-        Arrays.sort(resourceDirs);
-        for (File dir : resourceDirs) {
-            ResourceFolderType type = ResourceFolderType.getFolderType(dir.getName());
-            if (type != null) {
-                checkResourceFolder(project, main, dir, type, xmlChecks, dirChecks, binaryChecks);
-            }
-
-            if (mCanceled) {
-                return;
-            }
-        }
-    }
-
-    private void checkResourceFolder(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File dir,
-            @NonNull ResourceFolderType type,
-            @NonNull List<ResourceXmlDetector> xmlChecks,
-            @Nullable List<Detector> dirChecks,
-            @Nullable List<Detector> binaryChecks) {
-
-        // Process the resource folder
-
-        if (dirChecks != null && !dirChecks.isEmpty()) {
-            ResourceContext context = new ResourceContext(this, project, main, dir, type);
-            String folderName = dir.getName();
-            fireEvent(EventType.SCANNING_FILE, context);
-            for (Detector check : dirChecks) {
-                if (check.appliesTo(type)) {
-                    check.beforeCheckFile(context);
-                    check.checkFolder(context, folderName);
-                    check.afterCheckFile(context);
-                }
-            }
-            if (binaryChecks == null && xmlChecks.isEmpty()) {
-                return;
-            }
-        }
-
-        File[] files = dir.listFiles();
-        if (files == null || files.length <= 0) {
-            return;
-        }
-
-        ResourceVisitor visitor = getVisitor(type, xmlChecks, binaryChecks);
-        if (visitor != null) { // if not, there are no applicable rules in this folder
-            // Process files in alphabetical order, to ensure stable output
-            // (for example for the duplicate resource detector)
-            Arrays.sort(files);
-            for (File file : files) {
-                if (LintUtils.isXmlFile(file)) {
-                    XmlContext context = new XmlContext(this, project, main, file, type,
-                            visitor.getParser());
-                    fireEvent(EventType.SCANNING_FILE, context);
-                    visitor.visitFile(context, file);
-                } else if (binaryChecks != null && (LintUtils.isBitmapFile(file) ||
-                            type == ResourceFolderType.RAW)) {
-                    ResourceContext context = new ResourceContext(this, project, main, file, type);
-                    fireEvent(EventType.SCANNING_FILE, context);
-                    visitor.visitBinaryResource(context);
-                }
-                if (mCanceled) {
-                    return;
-                }
-            }
-        }
-    }
-
-    /** Checks individual resources */
-    private void checkIndividualResources(
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull List<ResourceXmlDetector> xmlDetectors,
-            @Nullable List<Detector> dirChecks,
-            @Nullable List<Detector> binaryChecks,
-            @NonNull List<File> files) {
-        for (File file : files) {
-            if (file.isDirectory()) {
-                // Is it a resource folder?
-                ResourceFolderType type = ResourceFolderType.getFolderType(file.getName());
-                if (type != null && new File(file.getParentFile(), RES_FOLDER).exists()) {
-                    // Yes.
-                    checkResourceFolder(project, main, file, type, xmlDetectors, dirChecks,
-                            binaryChecks);
-                } else if (file.getName().equals(RES_FOLDER)) { // Is it the res folder?
-                    // Yes
-                    checkResFolder(project, main, file, xmlDetectors, dirChecks, binaryChecks);
-                } else {
-                    mClient.log(null, "Unexpected folder %1$s; should be project, " +
-                            "\"res\" folder or resource folder", file.getPath());
-                }
-            } else if (file.isFile() && LintUtils.isXmlFile(file)) {
-                // Yes, find out its resource type
-                String folderName = file.getParentFile().getName();
-                ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
-                if (type != null) {
-                    ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
-                    if (visitor != null) {
-                        XmlContext context = new XmlContext(this, project, main, file, type,
-                                visitor.getParser());
-                        fireEvent(EventType.SCANNING_FILE, context);
-                        visitor.visitFile(context, file);
-                    }
-                }
-            } else if (binaryChecks != null && file.isFile() && LintUtils.isBitmapFile(file)) {
-                // Yes, find out its resource type
-                String folderName = file.getParentFile().getName();
-                ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
-                if (type != null) {
-                    ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
-                    if (visitor != null) {
-                        ResourceContext context = new ResourceContext(this, project, main, file,
-                                type);
-                        fireEvent(EventType.SCANNING_FILE, context);
-                        visitor.visitBinaryResource(context);
-                        if (mCanceled) {
-                            return;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds a listener to be notified of lint progress
-     *
-     * @param listener the listener to be added
-     */
-    public void addLintListener(@NonNull LintListener listener) {
-        if (mListeners == null) {
-            mListeners = new ArrayList<LintListener>(1);
-        }
-        mListeners.add(listener);
-    }
-
-    /**
-     * Removes a listener such that it is no longer notified of progress
-     *
-     * @param listener the listener to be removed
-     */
-    public void removeLintListener(@NonNull LintListener listener) {
-        mListeners.remove(listener);
-        if (mListeners.isEmpty()) {
-            mListeners = null;
-        }
-    }
-
-    /** Notifies listeners, if any, that the given event has occurred */
-    private void fireEvent(@NonNull LintListener.EventType type, @Nullable Context context) {
-        if (mListeners != null) {
-            for (LintListener listener : mListeners) {
-                listener.update(this, type, context);
-            }
-        }
-    }
-
-    /**
-     * Wrapper around the lint client. This sits in the middle between a
-     * detector calling for example {@link LintClient#report} and
-     * the actual embedding tool, and performs filtering etc such that detectors
-     * and lint clients don't have to make sure they check for ignored issues or
-     * filtered out warnings.
-     */
-    private class LintClientWrapper extends LintClient {
-        @NonNull
-        private final LintClient mDelegate;
-
-        public LintClientWrapper(@NonNull LintClient delegate) {
-            super(getClientName());
-            mDelegate = delegate;
-        }
-
-        @Override
-        public void report(
-                @NonNull Context context,
-                @NonNull Issue issue,
-                @NonNull Severity severity,
-                @NonNull Location location,
-                @NonNull String message,
-                @NonNull TextFormat format) {
-            //noinspection ConstantConditions
-            if (location == null) {
-                // Misbehaving third-party lint detectors
-                assert false : issue;
-                return;
-            }
-
-            assert mCurrentProject != null;
-            if (!mCurrentProject.getReportIssues()) {
-                return;
-            }
-
-            Configuration configuration = context.getConfiguration();
-            if (!configuration.isEnabled(issue)) {
-                if (issue != IssueRegistry.PARSER_ERROR && issue != IssueRegistry.LINT_ERROR) {
-                    mDelegate.log(null, "Incorrect detector reported disabled issue %1$s",
-                            issue.toString());
-                }
-                return;
-            }
-
-            if (configuration.isIgnored(context, issue, location, message)) {
-                return;
-            }
-
-            if (severity == Severity.IGNORE) {
-                return;
-            }
-
-            mDelegate.report(context, issue, severity, location, message, format);
-        }
-
-        // Everything else just delegates to the embedding lint client
-
-        @Override
-        @NonNull
-        public Configuration getConfiguration(@NonNull Project project,
-          @Nullable LintDriver driver) {
-            return mDelegate.getConfiguration(project, driver);
-        }
-
-        @Override
-        public void log(@NonNull Severity severity, @Nullable Throwable exception,
-                @Nullable String format, @Nullable Object... args) {
-            mDelegate.log(exception, format, args);
-        }
-
-        @Override
-        @NonNull
-        public String readFile(@NonNull File file) {
-            return mDelegate.readFile(file);
-        }
-
-        @Override
-        @NonNull
-        public byte[] readBytes(@NonNull File file) throws IOException {
-            return mDelegate.readBytes(file);
-        }
-
-        @Override
-        @NonNull
-        public List<File> getJavaSourceFolders(@NonNull Project project) {
-            return mDelegate.getJavaSourceFolders(project);
-        }
-
-        @Override
-        @NonNull
-        public List<File> getJavaClassFolders(@NonNull Project project) {
-            return mDelegate.getJavaClassFolders(project);
-        }
-
-        @NonNull
-        @Override
-        public List<File> getJavaLibraries(@NonNull Project project, boolean includeProvided) {
-            return mDelegate.getJavaLibraries(project, includeProvided);
-        }
-
-        @NonNull
-        @Override
-        public List<File> getTestSourceFolders(@NonNull Project project) {
-            return mDelegate.getTestSourceFolders(project);
-        }
-
-        @Override
-        public Collection<Project> getKnownProjects() {
-            return mDelegate.getKnownProjects();
-        }
-
-        @Nullable
-        @Override
-        public BuildToolInfo getBuildTools(@NonNull Project project) {
-            return mDelegate.getBuildTools(project);
-        }
-
-        @NonNull
-        @Override
-        public Map<String, String> createSuperClassMap(@NonNull Project project) {
-            return mDelegate.createSuperClassMap(project);
-        }
-
-        @NonNull
-        @Override
-        public ResourceVisibilityLookup.Provider getResourceVisibilityProvider() {
-            return mDelegate.getResourceVisibilityProvider();
-        }
-
-        @Override
-        @NonNull
-        public List<File> getResourceFolders(@NonNull Project project) {
-            return mDelegate.getResourceFolders(project);
-        }
-
-        @Override
-        @Nullable
-        public XmlParser getXmlParser() {
-            return mDelegate.getXmlParser();
-        }
-
-        @Override
-        @NonNull
-        public Class<? extends Detector> replaceDetector(
-                @NonNull Class<? extends Detector> detectorClass) {
-            return mDelegate.replaceDetector(detectorClass);
-        }
-
-        @Override
-        @NonNull
-        public SdkInfo getSdkInfo(@NonNull Project project) {
-            return mDelegate.getSdkInfo(project);
-        }
-
-        @Override
-        @NonNull
-        public Project getProject(@NonNull File dir, @NonNull File referenceDir) {
-            return mDelegate.getProject(dir, referenceDir);
-        }
-
-        @Nullable
-        @Override
-        public JavaParser getJavaParser(@Nullable Project project) {
-            return mDelegate.getJavaParser(project);
-        }
-
-        @Override
-        public File findResource(@NonNull String relativePath) {
-            return mDelegate.findResource(relativePath);
-        }
-
-        @Override
-        @Nullable
-        public File getCacheDir(boolean create) {
-            return mDelegate.getCacheDir(create);
-        }
-
-        @Override
-        @NonNull
-        protected ClassPathInfo getClassPath(@NonNull Project project) {
-            return mDelegate.getClassPath(project);
-        }
-
-        @Override
-        public void log(@Nullable Throwable exception, @Nullable String format,
-                @Nullable Object... args) {
-            mDelegate.log(exception, format, args);
-        }
-
-        @Override
-        @Nullable
-        public File getSdkHome() {
-            return mDelegate.getSdkHome();
-        }
-
-        @Override
-        @NonNull
-        public IAndroidTarget[] getTargets() {
-            return mDelegate.getTargets();
-        }
-
-        @Nullable
-        @Override
-        public AndroidSdkHandler getSdk() {
-            return mDelegate.getSdk();
-        }
-
-        @Nullable
-        @Override
-        public IAndroidTarget getCompileTarget(@NonNull Project project) {
-            return mDelegate.getCompileTarget(project);
-        }
-
-        @Override
-        public int getHighestKnownApiLevel() {
-            return mDelegate.getHighestKnownApiLevel();
-        }
-
-        @Override
-        @Nullable
-        public String getSuperClass(@NonNull Project project, @NonNull String name) {
-            return mDelegate.getSuperClass(project, name);
-        }
-
-        @Override
-        @Nullable
-        public Boolean isSubclassOf(@NonNull Project project, @NonNull String name,
-                @NonNull String superClassName) {
-            return mDelegate.isSubclassOf(project, name, superClassName);
-        }
-
-        @Override
-        @NonNull
-        public String getProjectName(@NonNull Project project) {
-            return mDelegate.getProjectName(project);
-        }
-
-        @Override
-        public boolean isGradleProject(Project project) {
-            return mDelegate.isGradleProject(project);
-        }
-
-        @NonNull
-        @Override
-        protected Project createProject(@NonNull File dir, @NonNull File referenceDir) {
-            return mDelegate.createProject(dir, referenceDir);
-        }
-
-        @NonNull
-        @Override
-        public List<File> findGlobalRuleJars() {
-            return mDelegate.findGlobalRuleJars();
-        }
-
-        @NonNull
-        @Override
-        public List<File> findRuleJars(@NonNull Project project) {
-            return mDelegate.findRuleJars(project);
-        }
-
-        @Override
-        public boolean isProjectDirectory(@NonNull File dir) {
-            return mDelegate.isProjectDirectory(dir);
-        }
-
-        @Override
-        public void registerProject(@NonNull File dir, @NonNull Project project) {
-            log(Severity.WARNING, null, "Too late to register projects");
-            mDelegate.registerProject(dir, project);
-        }
-
-        @Override
-        public IssueRegistry addCustomLintRules(@NonNull IssueRegistry registry) {
-            return mDelegate.addCustomLintRules(registry);
-        }
-
-        @NonNull
-        @Override
-        public List<File> getAssetFolders(@NonNull Project project) {
-            return mDelegate.getAssetFolders(project);
-        }
-
-        @Override
-        public ClassLoader createUrlClassLoader(@NonNull URL[] urls, @NonNull ClassLoader parent) {
-            return mDelegate.createUrlClassLoader(urls, parent);
-        }
-
-        @Override
-        public boolean checkForSuppressComments() {
-            return mDelegate.checkForSuppressComments();
-        }
-
-        @Override
-        public boolean supportsProjectResources() {
-            return mDelegate.supportsProjectResources();
-        }
-
-        @Nullable
-        @Override
-        public AbstractResourceRepository getProjectResources(Project project,
-                boolean includeDependencies) {
-            return mDelegate.getProjectResources(project, includeDependencies);
-        }
-
-        @NonNull
-        @Override
-        public Location.Handle createResourceItemHandle(@NonNull ResourceItem item) {
-            return mDelegate.createResourceItemHandle(item);
-        }
-
-        @Nullable
-        @Override
-        public URLConnection openConnection(@NonNull URL url) throws IOException {
-            return mDelegate.openConnection(url);
-        }
-
-        @Override
-        public void closeConnection(@NonNull URLConnection connection) throws IOException {
-            mDelegate.closeConnection(connection);
-        }
-    }
-
-    /**
-     * Requests another pass through the data for the given detector. This is
-     * typically done when a detector needs to do more expensive computation,
-     * but it only wants to do this once it <b>knows</b> that an error is
-     * present, or once it knows more specifically what to check for.
-     *
-     * @param detector the detector that should be included in the next pass.
-     *            Note that the lint runner may refuse to run more than a couple
-     *            of runs.
-     * @param scope the scope to be revisited. This must be a subset of the
-     *       current scope ({@link #getScope()}, and it is just a performance hint;
-     *       in particular, the detector should be prepared to be called on other
-     *       scopes as well (since they may have been requested by other detectors).
-     *       You can pall null to indicate "all".
-     */
-    public void requestRepeat(@NonNull Detector detector, @Nullable EnumSet<Scope> scope) {
-        if (mRepeatingDetectors == null) {
-            mRepeatingDetectors = new ArrayList<Detector>();
-        }
-        mRepeatingDetectors.add(detector);
-
-        if (scope != null) {
-            if (mRepeatScope == null) {
-                mRepeatScope = scope;
-            } else {
-                mRepeatScope = EnumSet.copyOf(mRepeatScope);
-                mRepeatScope.addAll(scope);
-            }
-        } else {
-            mRepeatScope = Scope.ALL;
-        }
-    }
-
-    // Unfortunately, ASMs nodes do not extend a common DOM node type with parent
-    // pointers, so we have to have multiple methods which pass in each type
-    // of node (class, method, field) to be checked.
-
-    /**
-     * Returns whether the given issue is suppressed in the given method.
-     *
-     * @param issue the issue to be checked, or null to just check for "all"
-     * @param classNode the class containing the issue
-     * @param method the method containing the issue
-     * @param instruction the instruction within the method, if any
-     * @return true if there is a suppress annotation covering the specific
-     *         issue on this method
-     */
-    public boolean isSuppressed(
-            @Nullable Issue issue,
-            @NonNull ClassNode classNode,
-            @NonNull MethodNode method,
-            @Nullable AbstractInsnNode instruction) {
-        if (method.invisibleAnnotations != null) {
-            @SuppressWarnings("unchecked")
-            List<AnnotationNode> annotations = method.invisibleAnnotations;
-            return isSuppressed(issue, annotations);
-        }
-
-        // Initializations of fields end up placed in generated methods (<init>
-        // for members and <clinit> for static fields).
-        if (instruction != null && method.name.charAt(0) == '<') {
-            AbstractInsnNode next = LintUtils.getNextInstruction(instruction);
-            if (next != null && next.getType() == AbstractInsnNode.FIELD_INSN) {
-                FieldInsnNode fieldRef = (FieldInsnNode) next;
-                FieldNode field = findField(classNode, fieldRef.owner, fieldRef.name);
-                if (field != null && isSuppressed(issue, field)) {
-                    return true;
-                }
-            } else if (classNode.outerClass != null && classNode.outerMethod == null
-                        && isAnonymousClass(classNode)) {
-                if (isSuppressed(issue, classNode)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Nullable
-    private static MethodInsnNode findConstructorInvocation(
-            @NonNull MethodNode method,
-            @NonNull String className) {
-        InsnList nodes = method.instructions;
-        for (int i = 0, n = nodes.size(); i < n; i++) {
-            AbstractInsnNode instruction = nodes.get(i);
-            if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) {
-                MethodInsnNode call = (MethodInsnNode) instruction;
-                if (className.equals(call.owner)) {
-                    return call;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private FieldNode findField(
-            @NonNull ClassNode classNode,
-            @NonNull String owner,
-            @NonNull String name) {
-        ClassNode current = classNode;
-        while (current != null) {
-            if (owner.equals(current.name)) {
-                @SuppressWarnings("rawtypes") // ASM API
-                List fieldList = current.fields;
-                for (Object f : fieldList) {
-                    FieldNode field = (FieldNode) f;
-                    if (field.name.equals(name)) {
-                        return field;
-                    }
-                }
-                return null;
-            }
-            current = getOuterClassNode(current);
-        }
-        return null;
-    }
-
-    @Nullable
-    private MethodNode findMethod(
-            @NonNull ClassNode classNode,
-            @NonNull String name,
-            boolean includeInherited) {
-        ClassNode current = classNode;
-        while (current != null) {
-            @SuppressWarnings("rawtypes") // ASM API
-            List methodList = current.methods;
-            for (Object f : methodList) {
-                MethodNode method = (MethodNode) f;
-                if (method.name.equals(name)) {
-                    return method;
-                }
-            }
-
-            if (includeInherited) {
-                current = getOuterClassNode(current);
-            } else {
-                break;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns whether the given issue is suppressed for the given field.
-     *
-     * @param issue the issue to be checked, or null to just check for "all"
-     * @param field the field potentially annotated with a suppress annotation
-     * @return true if there is a suppress annotation covering the specific
-     *         issue on this field
-     */
-    @SuppressWarnings("MethodMayBeStatic") // API; reserve need to require driver state later
-    public boolean isSuppressed(@Nullable Issue issue, @NonNull FieldNode field) {
-        if (field.invisibleAnnotations != null) {
-            @SuppressWarnings("unchecked")
-            List<AnnotationNode> annotations = field.invisibleAnnotations;
-            return isSuppressed(issue, annotations);
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns whether the given issue is suppressed in the given class.
-     *
-     * @param issue the issue to be checked, or null to just check for "all"
-     * @param classNode the class containing the issue
-     * @return true if there is a suppress annotation covering the specific
-     *         issue in this class
-     */
-    public boolean isSuppressed(@Nullable Issue issue, @NonNull ClassNode classNode) {
-        if (classNode.invisibleAnnotations != null) {
-            @SuppressWarnings("unchecked")
-            List<AnnotationNode> annotations = classNode.invisibleAnnotations;
-            return isSuppressed(issue, annotations);
-        }
-
-        if (classNode.outerClass != null && classNode.outerMethod == null
-                && isAnonymousClass(classNode)) {
-            ClassNode outer = getOuterClassNode(classNode);
-            if (outer != null) {
-                MethodNode m = findMethod(outer, CONSTRUCTOR_NAME, false);
-                if (m != null) {
-                    MethodInsnNode call = findConstructorInvocation(m, classNode.name);
-                    if (call != null) {
-                        if (isSuppressed(issue, outer, m, call)) {
-                            return true;
-                        }
-                    }
-                }
-                m = findMethod(outer, CLASS_CONSTRUCTOR, false);
-                if (m != null) {
-                    MethodInsnNode call = findConstructorInvocation(m, classNode.name);
-                    if (call != null) {
-                        if (isSuppressed(issue, outer, m, call)) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isSuppressed(@Nullable Issue issue, List<AnnotationNode> annotations) {
-        for (AnnotationNode annotation : annotations) {
-            String desc = annotation.desc;
-
-            // We could obey @SuppressWarnings("all") too, but no need to look for it
-            // because that annotation only has source retention.
-
-            if (desc.endsWith(SUPPRESS_LINT_VMSIG)) {
-                if (annotation.values != null) {
-                    for (int i = 0, n = annotation.values.size(); i < n; i += 2) {
-                        String key = (String) annotation.values.get(i);
-                        if (key.equals("value")) {   //$NON-NLS-1$
-                            Object value = annotation.values.get(i + 1);
-                            if (value instanceof String) {
-                                String id = (String) value;
-                                if (matches(issue, id)) {
-                                    return true;
-                                }
-                            } else if (value instanceof List) {
-                                @SuppressWarnings("rawtypes")
-                                List list = (List) value;
-                                for (Object v : list) {
-                                    if (v instanceof String) {
-                                        String id = (String) v;
-                                        if (matches(issue, id)) {
-                                            return true;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean matches(@Nullable Issue issue, @NonNull String id) {
-        if (id.equalsIgnoreCase(SUPPRESS_ALL)) {
-            return true;
-        }
-
-        if (issue != null) {
-            String issueId = issue.getId();
-            if (id.equalsIgnoreCase(issueId)) {
-                return true;
-            }
-            if (id.startsWith(STUDIO_ID_PREFIX)
-                && id.regionMatches(true, STUDIO_ID_PREFIX.length(), issueId, 0, issueId.length())
-                && id.substring(STUDIO_ID_PREFIX.length()).equalsIgnoreCase(issueId)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the given issue is suppressed by the given suppress string; this
-     * is typically the same as the issue id, but is allowed to not match case sensitively,
-     * and is allowed to be a comma separated list, and can be the string "all"
-     *
-     * @param issue  the issue id to match
-     * @param string the suppress string -- typically the id, or "all", or a comma separated list
-     *               of ids
-     * @return true if the issue is suppressed by the given string
-     */
-    private static boolean isSuppressed(@NonNull Issue issue, @NonNull String string) {
-        if (string.isEmpty()) {
-            return false;
-        }
-
-        if (string.indexOf(',') == -1) {
-            if (matches(issue, string)) {
-                return true;
-            }
-        } else {
-            for (String id : Splitter.on(',').trimResults().split(string)) {
-                if (matches(issue, id)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns whether the given issue is suppressed in the given parse tree node.
-     *
-     * @param context the context for the source being scanned
-     * @param issue the issue to be checked, or null to just check for "all"
-     * @param scope the AST node containing the issue
-     * @return true if there is a suppress annotation covering the specific
-     *         issue in this class
-     */
-    public boolean isSuppressed(@Nullable JavaContext context, @NonNull Issue issue,
-            @Nullable Node scope) {
-        boolean checkComments = mClient.checkForSuppressComments() &&
-                context != null && context.containsCommentSuppress();
-        while (scope != null) {
-            Class<? extends Node> type = scope.getClass();
-            // The Lombok AST uses a flat hierarchy of node type implementation classes
-            // so no need to do instanceof stuff here.
-            if (type == VariableDefinition.class) {
-                // Variable
-                VariableDefinition declaration = (VariableDefinition) scope;
-                if (isSuppressed(issue, declaration.astModifiers())) {
-                    return true;
-                }
-            } else if (type == MethodDeclaration.class) {
-                // Method
-                // Look for annotations on the method
-                MethodDeclaration declaration = (MethodDeclaration) scope;
-                if (isSuppressed(issue, declaration.astModifiers())) {
-                    return true;
-                }
-            } else if (type == ConstructorDeclaration.class) {
-                // Constructor
-                // Look for annotations on the method
-                ConstructorDeclaration declaration = (ConstructorDeclaration) scope;
-                if (isSuppressed(issue, declaration.astModifiers())) {
-                    return true;
-                }
-            } else if (TypeDeclaration.class.isAssignableFrom(type)) {
-                // Class, annotation, enum, interface
-                TypeDeclaration declaration = (TypeDeclaration) scope;
-                if (isSuppressed(issue, declaration.astModifiers())) {
-                    return true;
-                }
-            } else if (type == AnnotationMethodDeclaration.class) {
-                // Look for annotations on the method
-                AnnotationMethodDeclaration declaration = (AnnotationMethodDeclaration) scope;
-                if (isSuppressed(issue, declaration.astModifiers())) {
-                    return true;
-                }
-            }
-
-            if (checkComments && context.isSuppressedWithComment(scope, issue)) {
-                return true;
-            }
-
-            scope = scope.getParent();
-        }
-
-        return false;
-    }
-
-    public boolean isSuppressed(@Nullable JavaContext context, @NonNull Issue issue,
-            @Nullable UElement scope) {
-        boolean checkComments = mClient.checkForSuppressComments() &&
-                context != null && context.containsCommentSuppress();
-        while (scope != null) {
-            if (scope instanceof PsiModifierListOwner) {
-                PsiModifierListOwner owner = (PsiModifierListOwner) scope;
-                if (isSuppressed(issue, owner.getModifierList())) {
-                    return true;
-                }
-            }
-
-            if (checkComments && context.isSuppressedWithComment(scope, issue)) {
-                return true;
-            }
-
-            scope = scope.getUastParent();
-            if (scope instanceof PsiFile) {
-                return false;
-            }
-        }
-
-        return false;
-    }
-    
-    public boolean isSuppressed(@Nullable JavaContext context, @NonNull Issue issue,
-            @Nullable PsiElement scope) {
-        boolean checkComments = mClient.checkForSuppressComments() &&
-                context != null && context.containsCommentSuppress();
-        while (scope != null) {
-            if (scope instanceof PsiModifierListOwner) {
-                PsiModifierListOwner owner = (PsiModifierListOwner) scope;
-                if (isSuppressed(issue, owner.getModifierList())) {
-                    return true;
-                }
-            }
-
-            if (checkComments && context.isSuppressedWithComment(scope, issue)) {
-                return true;
-            }
-
-            scope = scope.getParent();
-            if (scope instanceof PsiFile) {
-                return false;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the given AST modifier has a suppress annotation for the
-     * given issue (which can be null to check for the "all" annotation)
-     *
-     * @param issue the issue to be checked
-     * @param modifiers the modifier to check
-     * @return true if the issue or all issues should be suppressed for this
-     *         modifier
-     */
-    private static boolean isSuppressed(@Nullable Issue issue, @Nullable Modifiers modifiers) {
-        if (modifiers == null) {
-            return false;
-        }
-        StrictListAccessor<Annotation, Modifiers> annotations = modifiers.astAnnotations();
-        if (annotations == null) {
-            return false;
-        }
-
-        for (Annotation annotation : annotations) {
-            TypeReference t = annotation.astAnnotationTypeReference();
-            String typeName = t.getTypeName();
-            if (typeName.endsWith(SUPPRESS_LINT)
-                    || typeName.endsWith("SuppressWarnings")) {     //$NON-NLS-1$
-                StrictListAccessor<AnnotationElement, Annotation> values =
-                        annotation.astElements();
-                if (values != null) {
-                    for (AnnotationElement element : values) {
-                        AnnotationValue valueNode = element.astValue();
-                        if (valueNode == null) {
-                            continue;
-                        }
-                        if (valueNode instanceof StringLiteral) {
-                            StringLiteral literal = (StringLiteral) valueNode;
-                            String value = literal.astValue();
-                            if (matches(issue, value)) {
-                                return true;
-                            }
-                        } else if (valueNode instanceof ArrayInitializer) {
-                            ArrayInitializer array = (ArrayInitializer) valueNode;
-                            StrictListAccessor<Expression, ArrayInitializer> expressions =
-                                    array.astExpressions();
-                            if (expressions == null) {
-                                continue;
-                            }
-                            for (Expression arrayElement : expressions) {
-                                if (arrayElement instanceof StringLiteral) {
-                                    String value = ((StringLiteral) arrayElement).astValue();
-                                    if (matches(issue, value)) {
-                                        return true;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    public static final String SUPPRESS_WARNINGS_FQCN = "java.lang.SuppressWarnings";
-
-
-    /**
-     * Returns true if the given AST modifier has a suppress annotation for the
-     * given issue (which can be null to check for the "all" annotation)
-     *
-     * @param issue the issue to be checked
-     * @param modifierList the modifier to check
-     * @return true if the issue or all issues should be suppressed for this
-     *         modifier
-     */
-    public static boolean isSuppressed(@NonNull Issue issue,
-            @Nullable PsiModifierList modifierList) {
-        if (modifierList == null) {
-            return false;
-        }
-
-        for (PsiAnnotation annotation : modifierList.getAnnotations()) {
-            String fqcn = annotation.getQualifiedName();
-            if (fqcn != null && (fqcn.equals(FQCN_SUPPRESS_LINT)
-                    || fqcn.equals(SUPPRESS_WARNINGS_FQCN)
-                    || fqcn.equals(SUPPRESS_LINT))) { // when missing imports
-                PsiAnnotationParameterList parameterList = annotation.getParameterList();
-                for (PsiNameValuePair pair : parameterList.getAttributes()) {
-                    if (isSuppressed(issue, pair.getValue())) {
-                        return true;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the annotation member value, assumed to be specified on a a SuppressWarnings
-     * or SuppressLint annotation, specifies the given id (or "all").
-     *
-     * @param issue the issue to be checked
-     * @param value     the member value to check
-     * @return true if the issue or all issues should be suppressed for this modifier
-     */
-    public static boolean isSuppressed(@NonNull Issue issue,
-            @Nullable PsiAnnotationMemberValue value) {
-        if (value instanceof PsiLiteral) {
-            PsiLiteral literal = (PsiLiteral)value;
-            Object literalValue = literal.getValue();
-            if (literalValue instanceof String) {
-                if (isSuppressed(issue, (String) literalValue)) {
-                    return true;
-                }
-            }
-        } else if (value instanceof PsiArrayInitializerMemberValue) {
-            PsiArrayInitializerMemberValue mv = (PsiArrayInitializerMemberValue)value;
-            for (PsiAnnotationMemberValue mmv : mv.getInitializers()) {
-                if (isSuppressed(issue, mmv)) {
-                    return true;
-                }
-            }
-        } else if (value instanceof PsiArrayInitializerExpression) {
-            PsiArrayInitializerExpression expression = (PsiArrayInitializerExpression) value;
-            PsiExpression[] initializers = expression.getInitializers();
-            for (PsiExpression e : initializers) {
-                if (isSuppressed(issue, e)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns whether the given issue is suppressed in the given XML DOM node.
-     *
-     * @param issue the issue to be checked, or null to just check for "all"
-     * @param node the DOM node containing the issue
-     * @return true if there is a suppress annotation covering the specific
-     *         issue in this class
-     */
-    public boolean isSuppressed(@Nullable XmlContext context, @NonNull Issue issue,
-            @Nullable org.w3c.dom.Node node) {
-        if (node instanceof Attr) {
-            node = ((Attr) node).getOwnerElement();
-        }
-        boolean checkComments = mClient.checkForSuppressComments()
-                && context != null && context.containsCommentSuppress();
-        while (node != null) {
-            if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
-                Element element = (Element) node;
-                if (element.hasAttributeNS(TOOLS_URI, ATTR_IGNORE)) {
-                    String ignore = element.getAttributeNS(TOOLS_URI, ATTR_IGNORE);
-                    if (isSuppressed(issue, ignore)) {
-                        return true;
-                    }
-                } else if (checkComments && context.isSuppressedWithComment(node, issue)) {
-                    return true;
-                }
-            }
-
-            node = node.getParentNode();
-        }
-
-        return false;
-    }
-
-    private File mCachedFolder = null;
-    private int mCachedFolderVersion = -1;
-    /** Pattern for version qualifiers */
-    private static final Pattern VERSION_PATTERN = Pattern.compile("^v(\\d+)$"); //$NON-NLS-1$
-
-    /**
-     * Returns the folder version of the given file. For example, for the file values-v14/foo.xml,
-     * it returns 14.
-     *
-     * @param resourceFile the file to be checked
-     * @return the folder version, or -1 if no specific version was specified
-     */
-    public int getResourceFolderVersion(@NonNull File resourceFile) {
-        File parent = resourceFile.getParentFile();
-        if (parent == null) {
-            return -1;
-        }
-        if (parent.equals(mCachedFolder)) {
-            return mCachedFolderVersion;
-        }
-
-        mCachedFolder = parent;
-        mCachedFolderVersion = -1;
-
-        for (String qualifier : QUALIFIER_SPLITTER.split(parent.getName())) {
-            Matcher matcher = VERSION_PATTERN.matcher(qualifier);
-            if (matcher.matches()) {
-                String group = matcher.group(1);
-                assert group != null;
-                mCachedFolderVersion = Integer.parseInt(group);
-                break;
-            }
-        }
-
-        return mCachedFolderVersion;
-    }
-
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintListener.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintListener.java
deleted file mode 100644
index 7ef4ba0..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintListener.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Context;
-import com.google.common.annotations.Beta;
-
-/**
- * Interface implemented by listeners to be notified of lint events
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public interface LintListener {
-    /** The various types of events provided to lint listeners */
-    enum EventType {
-        /** A lint check is about to begin */
-        STARTING,
-
-        /** Lint is about to check the given project, see {@link Context#getProject()} */
-        SCANNING_PROJECT,
-
-        /** Lint is about to check the given library project, see {@link Context#getProject()} */
-        SCANNING_LIBRARY_PROJECT,
-
-        /** Lint is about to check the given file, see {@link Context#file} */
-        SCANNING_FILE,
-
-        /** A new pass was initiated */
-        NEW_PHASE,
-
-        /** The lint check was canceled */
-        CANCELED,
-
-        /** The lint check is done */
-        COMPLETED,
-    }
-
-    /**
-     * Notifies listeners that the event of the given type has occurred.
-     * Additional information, such as the file being scanned, or the project
-     * being scanned, is available in the {@link Context} object (except for the
-     * {@link EventType#STARTING}, {@link EventType#CANCELED} or
-     * {@link EventType#COMPLETED} events which are fired outside of project
-     * contexts.)
-     *
-     * @param driver the driver running through the checks
-     * @param type the type of event that occurred
-     * @param context the context providing additional information
-     */
-    void update(@NonNull LintDriver driver, @NonNull EventType type,
-            @Nullable Context context);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintRequest.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintRequest.java
deleted file mode 100644
index f812591..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintRequest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.google.common.annotations.Beta;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-
-/**
- * Information about a request to run lint
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class LintRequest {
-    @NonNull
-    protected final LintClient mClient;
-
-    @NonNull
-    protected final List<File> mFiles;
-
-    @Nullable
-    protected EnumSet<Scope> mScope;
-
-    @Nullable
-    protected Boolean mReleaseMode;
-
-    @Nullable
-    protected Collection<Project> mProjects;
-
-    /**
-     * Creates a new {@linkplain LintRequest}, to be passed to a {@link LintDriver}
-     *
-     * @param client the tool wrapping the analyzer, such as an IDE or a CLI
-     * @param files the set of files to check with lint. This can reference Android projects,
-     *          or directories containing Android projects, or individual XML or Java files
-     *          (typically for incremental IDE analysis).
-     */
-    public LintRequest(@NonNull LintClient client, @NonNull List<File> files) {
-        mClient = client;
-        mFiles = files;
-    }
-
-    /**
-     * Returns the lint client requesting the lint check
-     *
-     * @return the client, never null
-     */
-    @NonNull
-    public LintClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns the set of files to check with lint. This can reference Android projects,
-     * or directories containing Android projects, or individual XML or Java files
-     * (typically for incremental IDE analysis).
-     *
-     * @return the set of files to check, should not be empty
-     */
-    @NonNull
-    public List<File> getFiles() {
-        return mFiles;
-    }
-
-    /**
-     * Sets the scope to use; lint checks which require a wider scope set
-     * will be ignored
-     *
-     * @return the scope to use, or null to use the default
-     */
-    @Nullable
-    public EnumSet<Scope> getScope() {
-        return mScope;
-    }
-
-    /**
-     * Sets the scope to use; lint checks which require a wider scope set
-     * will be ignored
-     *
-     * @param scope the scope
-     * @return this, for constructor chaining
-     */
-    @NonNull
-    public LintRequest setScope(@Nullable EnumSet<Scope> scope) {
-        mScope = scope;
-        return this;
-    }
-
-    /**
-     * Returns {@code true} if lint is invoked as part of a release mode build,
-     * {@code false}  if it is part of a debug mode build, and {@code null} if
-     * the release mode is not known
-     *
-     * @return true if this lint is running in release mode, null if not known
-     */
-    @Nullable
-    public Boolean isReleaseMode() {
-        return mReleaseMode;
-    }
-
-    /**
-     * Sets the release mode. Use {@code true} if lint is invoked as part of a
-     * release mode build, {@code false} if it is part of a debug mode build,
-     * and {@code null} if the release mode is not known
-     *
-     * @param releaseMode true if this lint is running in release mode, null if not known
-     * @return this, for constructor chaining
-     */
-    @NonNull
-    public LintRequest setReleaseMode(@Nullable Boolean releaseMode) {
-        mReleaseMode = releaseMode;
-        return this;
-    }
-
-    /**
-     * Gets the projects for the lint requests. This is optional; if not provided lint will search
-     * the {@link #getFiles()} directories and look for projects via {@link
-     * LintClient#isProjectDirectory(java.io.File)}. However, this method allows a lint client to
-     * set up all the projects ahead of time, and associate those projects with native resources
-     * (in an IDE for example, each lint project can be associated with the corresponding IDE
-     * project).
-     *
-     * @return a collection of projects, or null
-     */
-    @Nullable
-    public Collection<Project> getProjects() {
-        return mProjects;
-    }
-
-    /**
-     * Sets the projects for the lint requests. This is optional; if not provided lint will search
-     * the {@link #getFiles()} directories and look for projects via {@link
-     * LintClient#isProjectDirectory(java.io.File)}. However, this method allows a lint client to
-     * set up all the projects ahead of time, and associate those projects with native resources
-     * (in an IDE for example, each lint project can be associated with the corresponding IDE
-     * project).
-     *
-     * @param projects a collection of projects, or null
-     */
-    public void setProjects(@Nullable Collection<Project> projects) {
-        mProjects = projects;
-    }
-
-    /**
-     * Returns the project to be used as the main project during analysis. This is
-     * usually the project itself, but when you are for example analyzing a library project,
-     * it can be the app project using the library.
-     *
-     * @param project the project to look up the main project for
-     * @return the main project
-     */
-    @SuppressWarnings("MethodMayBeStatic")
-    @NonNull
-    public Project getMainProject(@NonNull Project project) {
-        return project;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/OtherFileVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/OtherFileVisitor.java
deleted file mode 100644
index f6a42f2..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/OtherFileVisitor.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.client.api;
-
-import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
-import static com.android.SdkConstants.DOT_CLASS;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.FD_ASSETS;
-import static com.android.tools.klint.detector.api.Detector.OtherFileScanner;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.utils.SdkUtils;
-import com.google.common.collect.Lists;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Visitor for "other" files: files that aren't java sources,
- * XML sources, etc -- or which should have custom handling in some
- * other way.
- */
-class OtherFileVisitor {
-    @NonNull
-    private final List<Detector> mDetectors;
-
-    @NonNull
-    private Map<Scope, List<File>> mFiles = new EnumMap<Scope, List<File>>(Scope.class);
-
-    OtherFileVisitor(@NonNull List<Detector> detectors) {
-        mDetectors = detectors;
-    }
-
-    /** Analyze other files in the given project */
-    void scan(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main) {
-        // Collect all project files
-        File projectFolder = project.getDir();
-
-        EnumSet<Scope> scopes = EnumSet.noneOf(Scope.class);
-        for (Detector detector : mDetectors) {
-            OtherFileScanner fileScanner = (OtherFileScanner) detector;
-            EnumSet<Scope> applicable = fileScanner.getApplicableFiles();
-            if (applicable.contains(Scope.OTHER)) {
-                scopes = Scope.ALL;
-                break;
-            }
-            scopes.addAll(applicable);
-        }
-
-        List<File> subset = project.getSubset();
-
-        if (scopes.contains(Scope.RESOURCE_FILE)) {
-            if (subset != null && !subset.isEmpty()) {
-                List<File> files = new ArrayList<File>(subset.size());
-                for (File file : subset) {
-                    if (SdkUtils.endsWith(file.getPath(), DOT_XML) &&
-                            !file.getName().equals(ANDROID_MANIFEST_XML)) {
-                        files.add(file);
-                    }
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.RESOURCE_FILE, files);
-                }
-            } else {
-                List<File> files = Lists.newArrayListWithExpectedSize(100);
-                for (File res : project.getResourceFolders()) {
-                    collectFiles(files, res);
-                }
-                File assets = new File(projectFolder, FD_ASSETS);
-                if (assets.exists()) {
-                    collectFiles(files, assets);
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.RESOURCE_FILE, files);
-                }
-            }
-        }
-
-        if (scopes.contains(Scope.JAVA_FILE)) {
-            if (subset != null && !subset.isEmpty()) {
-                List<File> files = new ArrayList<File>(subset.size());
-                for (File file : subset) {
-                    if (file.getPath().endsWith(".kt")) {
-                        files.add(file);
-                    }
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.JAVA_FILE, files);
-                }
-            } else {
-                List<File> files = Lists.newArrayListWithExpectedSize(100);
-                for (File srcFolder : project.getJavaSourceFolders()) {
-                    collectFiles(files, srcFolder);
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.JAVA_FILE, files);
-                }
-            }
-        }
-
-        if (scopes.contains(Scope.CLASS_FILE)) {
-            if (subset != null && !subset.isEmpty()) {
-                List<File> files = new ArrayList<File>(subset.size());
-                for (File file : subset) {
-                    if (file.getPath().endsWith(DOT_CLASS)) {
-                        files.add(file);
-                    }
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.CLASS_FILE, files);
-                }
-            } else {
-                List<File> files = Lists.newArrayListWithExpectedSize(100);
-                for (File classFolder : project.getJavaClassFolders()) {
-                    collectFiles(files, classFolder);
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.CLASS_FILE, files);
-                }
-            }
-        }
-
-        if (scopes.contains(Scope.MANIFEST)) {
-            if (subset != null && !subset.isEmpty()) {
-                List<File> files = new ArrayList<File>(subset.size());
-                for (File file : subset) {
-                    if (file.getName().equals(ANDROID_MANIFEST_XML)) {
-                        files.add(file);
-                    }
-                }
-                if (!files.isEmpty()) {
-                    mFiles.put(Scope.MANIFEST, files);
-                }
-            } else {
-                List<File> manifestFiles = project.getManifestFiles();
-                if (manifestFiles != null) {
-                    mFiles.put(Scope.MANIFEST, manifestFiles);
-                }
-            }
-        }
-
-        for (Map.Entry<Scope, List<File>> entry : mFiles.entrySet()) {
-            Scope scope = entry.getKey();
-            List<File> files = entry.getValue();
-            List<Detector> applicable = new ArrayList<Detector>(mDetectors.size());
-            for (Detector detector : mDetectors) {
-                OtherFileScanner fileScanner = (OtherFileScanner) detector;
-                EnumSet<Scope> appliesTo = fileScanner.getApplicableFiles();
-                if (appliesTo.contains(Scope.OTHER) || appliesTo.contains(scope)) {
-                    applicable.add(detector);
-                }
-            }
-            if (!applicable.isEmpty()) {
-                for (File file : files) {
-                    Context context = new Context(driver, project, main, file);
-                    for (Detector detector : applicable) {
-                        detector.beforeCheckFile(context);
-                        detector.run(context);
-                        detector.afterCheckFile(context);
-                    }
-                    if (driver.isCanceled()) {
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-    private static void collectFiles(List<File> files, File file) {
-        if (file.isDirectory()) {
-            File[] children = file.listFiles();
-            if (children != null) {
-                for (File child : children) {
-                    collectFiles(files, child);
-                }
-            }
-        } else {
-            files.add(file);
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ResourceVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ResourceVisitor.java
deleted file mode 100644
index 5ea1008..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/ResourceVisitor.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.ResourceContext;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.annotations.Beta;
-
-import org.w3c.dom.Attr;
-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.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.RandomAccess;
-
-/**
- * Specialized visitor for running detectors on resources: typically XML documents,
- * but also binary resources.
- * <p>
- * It operates in two phases:
- * <ol>
- *   <li> First, it computes a set of maps where it generates a map from each
- *        significant element name, and each significant attribute name, to a list
- *        of detectors to consult for that element or attribute name.
- *        The set of element names or attribute names (or both) that a detector
- *        is interested in is provided by the detectors themselves.
- *   <li> Second, it iterates over the document a single time. For each element and
- *        attribute it looks up the list of interested detectors, and runs them.
- * </ol>
- * It also notifies all the detectors before and after the document is processed
- * such that they can do pre- and post-processing.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-class ResourceVisitor {
-    private final Map<String, List<Detector.XmlScanner>> mElementToCheck =
-            new HashMap<String, List<Detector.XmlScanner>>();
-    private final Map<String, List<Detector.XmlScanner>> mAttributeToCheck =
-            new HashMap<String, List<Detector.XmlScanner>>();
-    private final List<Detector.XmlScanner> mDocumentDetectors =
-            new ArrayList<Detector.XmlScanner>();
-    private final List<Detector.XmlScanner> mAllElementDetectors =
-            new ArrayList<Detector.XmlScanner>();
-    private final List<Detector.XmlScanner> mAllAttributeDetectors =
-            new ArrayList<Detector.XmlScanner>();
-    private final List<? extends Detector> mAllDetectors;
-    private final List<? extends Detector> mBinaryDetectors;
-    private final XmlParser mParser;
-
-    // Really want this:
-    //<T extends List<Detector> & Detector.XmlScanner> XmlVisitor(IDomParser parser,
-    //    T xmlDetectors) {
-    // but it makes client code tricky and ugly.
-    ResourceVisitor(
-            @NonNull XmlParser parser,
-            @NonNull List<? extends Detector> xmlDetectors,
-            @Nullable List<Detector> binaryDetectors) {
-        mParser = parser;
-        mAllDetectors = xmlDetectors;
-        mBinaryDetectors = binaryDetectors;
-
-        // TODO: Check appliesTo() for files, and find a quick way to enable/disable
-        // rules when running through a full project!
-        for (Detector detector : xmlDetectors) {
-            Detector.XmlScanner xmlDetector = (XmlScanner) detector;
-            Collection<String> attributes = xmlDetector.getApplicableAttributes();
-            if (attributes == XmlScanner.ALL) {
-                mAllAttributeDetectors.add(xmlDetector);
-            }  else if (attributes != null) {
-                for (String attribute : attributes) {
-                    List<Detector.XmlScanner> list = mAttributeToCheck.get(attribute);
-                    if (list == null) {
-                        list = new ArrayList<Detector.XmlScanner>();
-                        mAttributeToCheck.put(attribute, list);
-                    }
-                    list.add(xmlDetector);
-                }
-            }
-            Collection<String> elements = xmlDetector.getApplicableElements();
-            if (elements == XmlScanner.ALL) {
-                mAllElementDetectors.add(xmlDetector);
-            } else if (elements != null) {
-                for (String element : elements) {
-                    List<Detector.XmlScanner> list = mElementToCheck.get(element);
-                    if (list == null) {
-                        list = new ArrayList<Detector.XmlScanner>();
-                        mElementToCheck.put(element, list);
-                    }
-                    list.add(xmlDetector);
-                }
-            }
-
-            if ((attributes == null || (attributes.isEmpty()
-                    && attributes != XmlScanner.ALL))
-                  && (elements == null || (elements.isEmpty()
-                  && elements != XmlScanner.ALL))) {
-                mDocumentDetectors.add(xmlDetector);
-            }
-        }
-    }
-
-    void visitFile(@NonNull XmlContext context, @NonNull File file) {
-        assert LintUtils.isXmlFile(file);
-
-        try {
-            if (context.document == null) {
-                context.document = mParser.parseXml(context);
-                if (context.document == null) {
-                    // No need to log this; the parser should be reporting
-                    // a full warning (such as IssueRegistry#PARSER_ERROR)
-                    // with details, location, etc.
-                    return;
-                }
-                if (context.document.getDocumentElement() == null) {
-                    // Ignore empty documents
-                    return;
-                }
-            }
-
-            for (Detector check : mAllDetectors) {
-                check.beforeCheckFile(context);
-            }
-
-            for (Detector.XmlScanner check : mDocumentDetectors) {
-                check.visitDocument(context, context.document);
-            }
-
-            if (!mElementToCheck.isEmpty() || !mAttributeToCheck.isEmpty()
-                    || !mAllAttributeDetectors.isEmpty() || !mAllElementDetectors.isEmpty()) {
-                visitElement(context, context.document.getDocumentElement());
-            }
-
-            for (Detector check : mAllDetectors) {
-                check.afterCheckFile(context);
-            }
-        } finally {
-            if (context.document != null) {
-                mParser.dispose(context, context.document);
-                context.document = null;
-            }
-        }
-    }
-
-    private void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        List<Detector.XmlScanner> elementChecks = mElementToCheck.get(element.getTagName());
-        if (elementChecks != null) {
-            assert elementChecks instanceof RandomAccess;
-            for (XmlScanner check : elementChecks) {
-                check.visitElement(context, element);
-            }
-        }
-        if (!mAllElementDetectors.isEmpty()) {
-            for (XmlScanner check : mAllElementDetectors) {
-                check.visitElement(context, element);
-            }
-        }
-
-        if (!mAttributeToCheck.isEmpty() || !mAllAttributeDetectors.isEmpty()) {
-            NamedNodeMap attributes = element.getAttributes();
-            for (int i = 0, n = attributes.getLength(); i < n; i++) {
-                Attr attribute = (Attr) attributes.item(i);
-                String name = attribute.getLocalName();
-                if (name == null) {
-                    name = attribute.getName();
-                }
-                List<Detector.XmlScanner> list = mAttributeToCheck.get(name);
-                if (list != null) {
-                    for (XmlScanner check : list) {
-                        check.visitAttribute(context, attribute);
-                    }
-                }
-                if (!mAllAttributeDetectors.isEmpty()) {
-                    for (XmlScanner check : mAllAttributeDetectors) {
-                        check.visitAttribute(context, attribute);
-                    }
-                }
-            }
-        }
-
-        // Visit children
-        NodeList childNodes = element.getChildNodes();
-        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                visitElement(context, (Element) child);
-            }
-        }
-
-        // Post hooks
-        if (elementChecks != null) {
-            for (XmlScanner check : elementChecks) {
-                check.visitElementAfter(context, element);
-            }
-        }
-        if (!mAllElementDetectors.isEmpty()) {
-            for (XmlScanner check : mAllElementDetectors) {
-                check.visitElementAfter(context, element);
-            }
-        }
-    }
-
-    @NonNull
-    public XmlParser getParser() {
-        return mParser;
-    }
-
-    public void visitBinaryResource(@NonNull ResourceContext context) {
-        if (mBinaryDetectors == null) {
-            return;
-        }
-        for (Detector check : mBinaryDetectors) {
-            check.beforeCheckFile(context);
-            check.checkBinaryResource(context);
-            check.afterCheckFile(context);
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkInfo.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkInfo.java
deleted file mode 100644
index e109d00c..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkInfo.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.annotations.Beta;
-
-/**
- * Information about SDKs
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class SdkInfo {
-    /**
-     * Returns true if the given child view is the same class or a sub class of
-     * the given parent view class
-     *
-     * @param parentViewFqcn the fully qualified class name of the parent view
-     * @param childViewFqcn the fully qualified class name of the child view
-     * @return true if the child view is a sub view of (or the same class as)
-     *         the parent view
-     */
-    public boolean isSubViewOf(@NonNull String parentViewFqcn, @NonNull String childViewFqcn) {
-        while (!childViewFqcn.equals("android.view.View")) { //$NON-NLS-1$
-            if (parentViewFqcn.equals(childViewFqcn)) {
-                return true;
-            }
-            String parent = getParentViewClass(childViewFqcn);
-            if (parent == null) {
-                // Unknown view - err on the side of caution
-                return true;
-            }
-            childViewFqcn = parent;
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Returns the fully qualified name of the parent view, or null if the view
-     * is the root android.view.View class.
-     *
-     * @param fqcn the fully qualified class name of the view
-     * @return the fully qualified class name of the parent view, or null
-     */
-    @Nullable
-    public abstract String getParentViewClass(@NonNull String fqcn);
-
-    /**
-     * Returns the class name of the parent view, or null if the view is the
-     * root android.view.View class. This is the same as the
-     * {@link #getParentViewClass(String)} but without the package.
-     *
-     * @param name the view class name to look up the parent for (not including
-     *            package)
-     * @return the view name of the parent
-     */
-    @Nullable
-    public abstract String getParentViewName(@NonNull String name);
-
-    /**
-     * Returns true if the given widget name is a layout
-     *
-     * @param tag the XML tag for the view
-     * @return true if the given tag corresponds to a layout
-     */
-    public boolean isLayout(@NonNull String tag) {
-        return tag.endsWith("Layout"); //$NON-NLS-1$
-    }
-
-    // TODO: Add access to resource resolution here.
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UElementVisitor.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UElementVisitor.java
deleted file mode 100644
index f518bae..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UElementVisitor.java
+++ /dev/null
@@ -1,1088 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Detector.UastScanner;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.StandardFileSystems;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.*;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-
-/**
- * Specialized visitor for running detectors on a Java AST.
- * It operates in three phases:
- * <ol>
- *   <li> First, it computes a set of maps where it generates a map from each
- *        significant AST attribute (such as method call names) to a list
- *        of detectors to consult whenever that attribute is encountered.
- *        Examples of "attributes" are method names, Android resource identifiers,
- *        and general AST node types such as "cast" nodes etc. These are
- *        defined on the {@link JavaPsiScanner} interface.
- *   <li> Second, it iterates over the document a single time, delegating to
- *        the detectors found at each relevant AST attribute.
- *   <li> Finally, it calls the remaining visitors (those that need to process a
- *        whole document on their own).
- * </ol>
- * It also notifies all the detectors before and after the document is processed
- * such that they can do pre- and post-processing.
- */
-public class UElementVisitor {
-    /** Default size of lists holding detectors of the same type for a given node type */
-    private static final int SAME_TYPE_COUNT = 8;
-
-    private final Map<String, List<VisitingDetector>> mMethodDetectors =
-            Maps.newHashMapWithExpectedSize(80);
-    private final Map<String, List<VisitingDetector>> mConstructorDetectors =
-            Maps.newHashMapWithExpectedSize(12);
-    private final Map<String, List<VisitingDetector>> mReferenceDetectors =
-            Maps.newHashMapWithExpectedSize(10);
-    private Set<String> mConstructorSimpleNames;
-    private final List<VisitingDetector> mResourceFieldDetectors =
-            new ArrayList<VisitingDetector>();
-    private final List<VisitingDetector> mAllDetectors;
-    private final List<VisitingDetector> mFullTreeDetectors;
-    private final Map<Class<? extends UElement>, List<VisitingDetector>> mNodePsiTypeDetectors =
-            new HashMap<Class<? extends UElement>, List<VisitingDetector>>(16);
-    private final JavaParser mParser;
-    private final Map<String, List<VisitingDetector>> mSuperClassDetectors =
-            new HashMap<String, List<VisitingDetector>>();
-
-    /**
-     * Number of fatal exceptions (internal errors, usually from ECJ) we've
-     * encountered; we don't log each and every one to avoid massive log spam
-     * in code which triggers this condition
-     */
-    private static int sExceptionCount;
-    /** Max number of logs to include */
-    private static final int MAX_REPORTED_CRASHES = 20;
-
-    UElementVisitor(@NonNull JavaParser parser, @NonNull List<Detector> detectors) {
-        mParser = parser;
-        mAllDetectors = new ArrayList<VisitingDetector>(detectors.size());
-        mFullTreeDetectors = new ArrayList<VisitingDetector>(detectors.size());
-
-        for (Detector detector : detectors) {
-            UastScanner uastScanner = (UastScanner) detector;
-            VisitingDetector v = new VisitingDetector(detector, uastScanner);
-            mAllDetectors.add(v);
-
-            List<String> names = detector.getApplicableMethodNames();
-            if (names != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert names != XmlScanner.ALL;
-
-                for (String name : names) {
-                    List<VisitingDetector> list = mMethodDetectors.get(name);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mMethodDetectors.put(name, list);
-                    }
-                    list.add(v);
-                }
-            }
-            
-            List<String> applicableSuperClasses = detector.applicableSuperClasses();
-            if (applicableSuperClasses != null) {
-                for (String fqn : applicableSuperClasses) {
-                    List<VisitingDetector> list = mSuperClassDetectors.get(fqn);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mSuperClassDetectors.put(fqn, list);
-                    }
-                    list.add(v);
-                }
-                continue;
-            }
-
-            List<Class<? extends UElement>> nodePsiTypes = detector.getApplicableUastTypes();
-            if (nodePsiTypes != null) {
-                for (Class<? extends UElement> type : nodePsiTypes) {
-                    List<VisitingDetector> list = mNodePsiTypeDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mNodePsiTypeDetectors.put(type, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> types = detector.getApplicableConstructorTypes();
-            if (types != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert types != XmlScanner.ALL;
-                if (mConstructorSimpleNames == null) {
-                    mConstructorSimpleNames = Sets.newHashSet();
-                }
-                for (String type : types) {
-                    List<VisitingDetector> list = mConstructorDetectors.get(type);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mConstructorDetectors.put(type, list);
-                        mConstructorSimpleNames.add(type.substring(type.lastIndexOf('.')+1));
-                    }
-                    list.add(v);
-                }
-            }
-
-            List<String> referenceNames = detector.getApplicableReferenceNames();
-            if (referenceNames != null) {
-                // not supported in Java visitors; adding a method invocation node is trivial
-                // for that case.
-                assert referenceNames != XmlScanner.ALL;
-
-                for (String name : referenceNames) {
-                    List<VisitingDetector> list = mReferenceDetectors.get(name);
-                    if (list == null) {
-                        list = new ArrayList<VisitingDetector>(SAME_TYPE_COUNT);
-                        mReferenceDetectors.put(name, list);
-                    }
-                    list.add(v);
-                }
-            }
-
-            if (detector.appliesToResourceRefs()) {
-                mResourceFieldDetectors.add(v);
-            } else if ((referenceNames == null || referenceNames.isEmpty())
-                    && (nodePsiTypes == null || nodePsiTypes.isEmpty())
-                    && (types == null || types.isEmpty())) {
-                mFullTreeDetectors.add(v);
-            }
-        }
-    }
-
-    void visitFile(@NonNull final JavaContext context) {
-        try {
-            Project ideaProject = context.getParser().getIdeaProject();
-            if (ideaProject == null) {
-                return;
-            }
-
-            VirtualFile virtualFile = StandardFileSystems.local()
-                    .findFileByPath(context.file.getAbsolutePath());
-            if (virtualFile == null) {
-                return;
-            }
-
-            PsiFile psiFile = PsiManager.getInstance(ideaProject).findFile(virtualFile);
-            if (psiFile == null) {
-                return;
-            }
-
-            UElement uElement = context.getUastContext().convertElementWithParent(psiFile, UFile.class);
-            if (!(uElement instanceof UFile)) {
-                // No need to log this; the parser should be reporting
-                // a full warning (such as IssueRegistry#PARSER_ERROR)
-                // with details, location, etc.
-                return;
-            }
-
-            final UFile uFile = (UFile) uElement;
-            
-            try {
-                context.setUFile(uFile);
-
-                mParser.runReadAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        for (VisitingDetector v : mAllDetectors) {
-                            v.setContext(context);
-                            v.getDetector().beforeCheckFile(context);
-                        }
-                    }
-                });
-
-                if (!mSuperClassDetectors.isEmpty()) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            SuperclassPsiVisitor visitor = new SuperclassPsiVisitor(context);
-                            uFile.accept(visitor);
-                        }
-                    });
-                }
-
-                for (final VisitingDetector v : mFullTreeDetectors) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            UastVisitor visitor = v.getVisitor();
-                            ProgressManager.checkCanceled();
-                            uFile.accept(visitor);
-                        }
-                    });
-                }
-
-                if (!mMethodDetectors.isEmpty()
-                        || !mResourceFieldDetectors.isEmpty()
-                        || !mConstructorDetectors.isEmpty()
-                        || !mReferenceDetectors.isEmpty()) {
-                    mParser.runReadAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            // TODO: Do we need to break this one up into finer grain
-                            // locking units
-                            UastVisitor visitor = new DelegatingPsiVisitor(context);
-                            uFile.accept(visitor);
-                        }
-                    });
-                } else {
-                    if (!mNodePsiTypeDetectors.isEmpty()) {
-                        mParser.runReadAction(new Runnable() {
-                            @Override
-                            public void run() {
-                                // TODO: Do we need to break this one up into finer grain
-                                // locking units
-                                UastVisitor visitor = new DispatchPsiVisitor();
-                                uFile.accept(visitor);
-                            }
-                        });
-                    }
-                }
-
-                mParser.runReadAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        for (VisitingDetector v : mAllDetectors) {
-                            ProgressManager.checkCanceled();
-                            v.getDetector().afterCheckFile(context);
-                        }
-                    }
-                });
-            } finally {
-                mParser.dispose(context, uFile);
-                context.setUFile(null);
-            }
-        } catch (ProcessCanceledException ignore) {
-            // Cancelling inspections in the IDE
-        } catch (RuntimeException e) {
-            if (sExceptionCount++ > MAX_REPORTED_CRASHES) {
-                // No need to keep spamming the user that a lot of the files
-                // are tripping up ECJ, they get the picture.
-                return;
-            }
-
-            if (e.getClass().getSimpleName().equals("IndexNotReadyException")) {
-                // Attempting to access PSI during startup before indices are ready; ignore these.
-                // See http://b.android.com/176644 for an example.
-                return;
-            }
-
-            // Work around ECJ bugs; see https://code.google.com/p/android/issues/detail?id=172268
-            // Don't allow lint bugs to take down the whole build. TRY to log this as a
-            // lint error instead!
-            StringBuilder sb = new StringBuilder(100);
-            sb.append("Unexpected failure during lint analysis of ");
-            sb.append(context.file.getName());
-            sb.append(" (this is a bug in lint or one of the libraries it depends on)\n");
-
-            sb.append(e.getClass().getSimpleName());
-            sb.append(':');
-            StackTraceElement[] stackTrace = e.getStackTrace();
-            int count = 0;
-            for (StackTraceElement frame : stackTrace) {
-                if (count > 0) {
-                    sb.append("<-");
-                }
-
-                String className = frame.getClassName();
-                sb.append(className.substring(className.lastIndexOf('.') + 1));
-                sb.append('.').append(frame.getMethodName());
-                sb.append('(');
-                sb.append(frame.getFileName()).append(':').append(frame.getLineNumber());
-                sb.append(')');
-                count++;
-                // Only print the top 3-4 frames such that we can identify the bug
-                if (count == 4) {
-                    break;
-                }
-            }
-            Throwable throwable = null; // NOT e: this makes for very noisy logs
-            //noinspection ConstantConditions
-            context.log(throwable, sb.toString());
-        }
-    }
-
-    /**
-     * For testing only: returns the number of exceptions thrown during Java AST analysis
-     *
-     * @return the number of internal errors found
-     */
-    @VisibleForTesting
-    public static int getCrashCount() {
-        return sExceptionCount;
-    }
-
-    /**
-     * For testing only: clears the crash counter
-     */
-    @VisibleForTesting
-    public static void clearCrashCount() {
-        sExceptionCount = 0;
-    }
-
-    public void prepare(@NonNull List<JavaContext> contexts) {
-        mParser.prepareJavaParse(contexts);
-    }
-
-    public void dispose() {
-        mParser.dispose();
-    }
-
-    @Nullable
-    private static Set<String> getInterfaceNames(
-            @Nullable Set<String> addTo,
-            @NonNull PsiClass cls) {
-        for (PsiClass resolvedInterface : cls.getInterfaces()) {
-            String name = resolvedInterface.getQualifiedName();
-            if (addTo == null) {
-                addTo = Sets.newHashSet();
-            } else if (addTo.contains(name)) {
-                // Superclasses can explicitly implement the same interface,
-                // so keep track of visited interfaces as we traverse up the
-                // super class chain to avoid checking the same interface
-                // more than once.
-                continue;
-            }
-            addTo.add(name);
-            getInterfaceNames(addTo, resolvedInterface);
-        }
-
-        return addTo;
-    }
-
-    private static class VisitingDetector {
-        private UastVisitor mVisitor;
-        private JavaContext mContext;
-        public final Detector mDetector;
-        public final UastScanner mUastScanner;
-
-        public VisitingDetector(@NonNull Detector detector, @NonNull UastScanner uastScanner) {
-            mDetector = detector;
-            mUastScanner = uastScanner;
-        }
-
-        @NonNull
-        public Detector getDetector() {
-            return mDetector;
-        }
-
-        @Nullable
-        public UastScanner getUastScanner() {
-            return mUastScanner;
-        }
-
-        public void setContext(@NonNull JavaContext context) {
-            mContext = context;
-
-            // The visitors are one-per-context, so clear them out here and construct
-            // lazily only if needed
-            mVisitor = null;
-        }
-
-        @NonNull
-        UastVisitor getVisitor() {
-            if (mVisitor == null) {
-                mVisitor = mDetector.createUastVisitor(mContext);
-                if (mVisitor == null) {
-                    mVisitor = new AbstractUastVisitor() {};
-                }
-            }
-            return mVisitor;
-        }
-    }
-
-    private class SuperclassPsiVisitor extends AbstractUastVisitor {
-        private JavaContext mContext;
-
-        public SuperclassPsiVisitor(@NonNull JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitClass(UClass node) {
-            boolean result = super.visitClass(node);
-            checkClass(node);
-            return result;
-        }
-
-        private void checkClass(@NonNull UClass node) {
-            ProgressManager.checkCanceled();
-
-            if (node instanceof PsiTypeParameter) {
-                // Not included: explained in javadoc for JavaPsiScanner#checkClass
-                return;
-            }
-
-            UClass cls = node;
-            int depth = 0;
-            while (cls != null) {
-                List<VisitingDetector> list = mSuperClassDetectors.get(cls.getQualifiedName());
-                if (list != null) {
-                    for (VisitingDetector v : list) {
-                        UastScanner uastScanner = v.getUastScanner();
-                        if (uastScanner != null) {
-                            uastScanner.checkClass(mContext, node);
-                        }
-                    }
-                }
-
-                // Check interfaces too
-                Set<String> interfaceNames = getInterfaceNames(null, cls);
-                if (interfaceNames != null) {
-                    for (String name : interfaceNames) {
-                        list = mSuperClassDetectors.get(name);
-                        if (list != null) {
-                            for (VisitingDetector v : list) {
-                                UastScanner javaPsiScanner = v.getUastScanner();
-                                if (javaPsiScanner != null) {
-                                    javaPsiScanner.checkClass(mContext, node);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                cls = cls.getSuperClass();
-                depth++;
-                if (depth == 500) {
-                    // Shouldn't happen in practice; this prevents the IDE from
-                    // hanging if the user has accidentally typed in an incorrect
-                    // super class which creates a cycle.
-                    break;
-                }
-            }
-        }
-    }
-
-    private class DispatchPsiVisitor extends AbstractUastVisitor {
-
-        @Override
-        public boolean visitAnnotation(UAnnotation node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UAnnotation.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitAnnotation(node);
-                }
-            }
-            return super.visitAnnotation(node);
-        }
-        
-        @Override
-        public boolean visitCatchClause(UCatchClause node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UCatchClause.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCatchClause(node);
-                }
-            }
-            return super.visitCatchClause(node);
-        }
-
-        @Override
-        public boolean visitMethod(UMethod node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UMethod.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitMethod(node);
-                }
-            }
-            return super.visitMethod(node);
-        }
-
-        @Override
-        public boolean visitVariable(UVariable node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UVariable.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitVariable(node);
-                }
-            }
-            return super.visitVariable(node);
-        }
-
-        @Override
-        public boolean visitFile(UFile node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UFile.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitFile(node);
-                }
-            }
-            return super.visitFile(node);
-        }
-
-        @Override
-        public boolean visitImportStatement(UImportStatement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UImportStatement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitImportStatement(node);
-                }
-            }
-            return super.visitImportStatement(node);
-        }
-
-        @Override
-        public boolean visitElement(UElement node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UElement.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitElement(node);
-                }
-            }
-            return super.visitElement(node);
-        }
-
-        @Override
-        public boolean visitClass(UClass node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UClass.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClass(node);
-                }
-            }
-            return super.visitClass(node);
-        }
-
-        @Override
-        public boolean visitInitializer(UClassInitializer node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UClassInitializer.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitInitializer(node);
-                }
-            }
-            return super.visitInitializer(node);
-        }
-
-        @Override
-        public boolean visitLabeledExpression(ULabeledExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(ULabeledExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLabeledExpression(node);
-                }
-            }
-            return super.visitLabeledExpression(node);
-        }
-        
-        @Override
-        public boolean visitBlockExpression(UBlockExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UBlockExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBlockExpression(node);
-                }
-            }
-            return super.visitBlockExpression(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UCallExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCallExpression(node);
-                }
-            }
-            return super.visitCallExpression(node);
-        }
-
-        @Override
-        public boolean visitBinaryExpression(UBinaryExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UBinaryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBinaryExpression(node);
-                }
-            }
-            return super.visitBinaryExpression(node);
-        }
-
-        @Override
-        public boolean visitBinaryExpressionWithType(UBinaryExpressionWithType node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UBinaryExpressionWithType.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBinaryExpressionWithType(node);
-                }
-            }
-            return super.visitBinaryExpressionWithType(node);
-        }
-
-        @Override
-        public boolean visitParenthesizedExpression(UParenthesizedExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UParenthesizedExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitParenthesizedExpression(node);
-                }
-            }
-            return super.visitParenthesizedExpression(node);
-        }
-
-        @Override
-        public boolean visitUnaryExpression(UUnaryExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UUnaryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitUnaryExpression(node);
-                }
-            }
-            return super.visitUnaryExpression(node);
-        }
-
-        @Override
-        public boolean visitPrefixExpression(UPrefixExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UPrefixExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPrefixExpression(node);
-                }
-            }
-            return super.visitPrefixExpression(node);
-        }
-
-        @Override
-        public boolean visitPostfixExpression(UPostfixExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UPostfixExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitPostfixExpression(node);
-                }
-            }
-            return super.visitPostfixExpression(node);
-        }
-
-        @Override
-        public boolean visitIfExpression(UIfExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UIfExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitIfExpression(node);
-                }
-            }
-            return super.visitIfExpression(node);
-        }
-
-        @Override
-        public boolean visitSwitchExpression(USwitchExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(USwitchExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSwitchExpression(node);
-                }
-            }
-            return super.visitSwitchExpression(node);
-        }
-
-        @Override
-        public boolean visitSwitchClauseExpression(USwitchClauseExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(USwitchClauseExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSwitchClauseExpression(node);
-                }
-            }
-            return super.visitSwitchClauseExpression(node);
-        }
-
-        @Override
-        public boolean visitWhileExpression(UWhileExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UWhileExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitWhileExpression(node);
-                }
-            }
-            return super.visitWhileExpression(node);
-        }
-
-        @Override
-        public boolean visitDoWhileExpression(UDoWhileExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UDoWhileExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDoWhileExpression(node);
-                }
-            }
-            return super.visitDoWhileExpression(node);
-        }
-
-        @Override
-        public boolean visitForExpression(UForExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UForExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitForExpression(node);
-                }
-            }
-            return super.visitForExpression(node);
-        }
-
-        @Override
-        public boolean visitForEachExpression(UForEachExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UForEachExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitForEachExpression(node);
-                }
-            }
-            return super.visitForEachExpression(node);
-        }
-
-        @Override
-        public boolean visitTryExpression(UTryExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UTryExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTryExpression(node);
-                }
-            }
-            return super.visitTryExpression(node);
-        }
-
-        @Override
-        public boolean visitLiteralExpression(ULiteralExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(ULiteralExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLiteralExpression(node);
-                }
-            }
-            return super.visitLiteralExpression(node);
-        }
-
-        @Override
-        public boolean visitThisExpression(UThisExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UThisExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThisExpression(node);
-                }
-            }
-            return super.visitThisExpression(node);
-        }
-
-        @Override
-        public boolean visitSuperExpression(USuperExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(USuperExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSuperExpression(node);
-                }
-            }
-            return super.visitSuperExpression(node);
-        }
-
-        @Override
-        public boolean visitReturnExpression(UReturnExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UReturnExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitReturnExpression(node);
-                }
-            }
-            return super.visitReturnExpression(node);
-        }
-
-        @Override
-        public boolean visitBreakExpression(UBreakExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UBreakExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitBreakExpression(node);
-                }
-            }
-            return super.visitBreakExpression(node);
-        }
-
-        @Override
-        public boolean visitContinueExpression(UContinueExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UContinueExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitContinueExpression(node);
-                }
-            }
-            return super.visitContinueExpression(node);
-        }
-
-        @Override
-        public boolean visitThrowExpression(UThrowExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UThrowExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitThrowExpression(node);
-                }
-            }
-            return super.visitThrowExpression(node);
-        }
-
-        @Override
-        public boolean visitArrayAccessExpression(UArrayAccessExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UArrayAccessExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitArrayAccessExpression(node);
-                }
-            }
-            return super.visitArrayAccessExpression(node);
-        }
-
-        @Override
-        public boolean visitCallableReferenceExpression(UCallableReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UCallableReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitCallableReferenceExpression(node);
-                }
-            }
-            return super.visitCallableReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitClassLiteralExpression(UClassLiteralExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UClassLiteralExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitClassLiteralExpression(node);
-                }
-            }
-            return super.visitClassLiteralExpression(node);
-        }
-
-        @Override
-        public boolean visitLambdaExpression(ULambdaExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(ULambdaExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitLambdaExpression(node);
-                }
-            }
-            return super.visitLambdaExpression(node);
-        }
-
-        @Override
-        public boolean visitObjectLiteralExpression(UObjectLiteralExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UObjectLiteralExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitObjectLiteralExpression(node);
-                }
-            }
-            return super.visitObjectLiteralExpression(node);
-        }
-
-        @Override
-        public boolean visitExpressionList(UExpressionList node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UExpressionList.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitExpressionList(node);
-                }
-            }
-            return super.visitExpressionList(node);
-        }
-
-        @Override
-        public boolean visitTypeReferenceExpression(UTypeReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UTypeReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitTypeReferenceExpression(node);
-                }
-            }
-            return super.visitTypeReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(USimpleNameReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitSimpleNameReferenceExpression(node);
-                }
-            }
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitQualifiedReferenceExpression(UQualifiedReferenceExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UQualifiedReferenceExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitQualifiedReferenceExpression(node);
-                }
-            }
-            return super.visitQualifiedReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitDeclarationsExpression(UDeclarationsExpression node) {
-            List<VisitingDetector> list = mNodePsiTypeDetectors.get(UDeclarationsExpression.class);
-            if (list != null) {
-                for (VisitingDetector v : list) {
-                    v.getVisitor().visitDeclarationsExpression(node);
-                }
-            }
-            return super.visitDeclarationsExpression(node);
-        }
-    }
-
-    /** Performs common AST searches for method calls and R-type-field references.
-     * Note that this is a specialized form of the {@link DispatchPsiVisitor}. */
-    private class DelegatingPsiVisitor extends DispatchPsiVisitor {
-        private final JavaContext mContext;
-        private final boolean mVisitResources;
-        private final boolean mVisitMethods;
-        private final boolean mVisitConstructors;
-        private final boolean mVisitReferences;
-
-        DelegatingPsiVisitor(JavaContext context) {
-            mContext = context;
-
-            mVisitMethods = !mMethodDetectors.isEmpty();
-            mVisitConstructors = !mConstructorDetectors.isEmpty();
-            mVisitResources = !mResourceFieldDetectors.isEmpty();
-            mVisitReferences = !mReferenceDetectors.isEmpty();
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            if (mVisitReferences || mVisitResources) {
-                ProgressManager.checkCanceled();
-            }
-
-            if (mVisitReferences) {
-                List<VisitingDetector> list = mReferenceDetectors.get(node.getIdentifier());
-                if (list != null) {
-                    PsiElement referenced = node.resolve();
-                    if (referenced != null) {
-                        for (VisitingDetector v : list) {
-                            UastScanner uastScanner = v.getUastScanner();
-                            if (uastScanner != null) {
-                                uastScanner.visitReference(mContext, v.getVisitor(),
-                                        node, referenced);
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (mVisitResources) {
-                AndroidReference androidReference = UastLintUtils.toAndroidReferenceViaResolve(node);
-                if (androidReference != null) {
-                    for (VisitingDetector v : mResourceFieldDetectors) {
-                        UastScanner uastScanner = v.getUastScanner();
-                        if (uastScanner != null) {
-                            uastScanner.visitResourceReference(mContext, v.getVisitor(),
-                                    androidReference.node,
-                                    androidReference.getType(),
-                                    androidReference.getName(),
-                                    androidReference.getPackage().equals(ANDROID_PKG));
-                        }
-                    }
-                }
-            }
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            boolean result = super.visitCallExpression(node);
-
-            ProgressManager.checkCanceled();
-
-            if (UastExpressionUtils.isMethodCall(node)) {
-                visitMethodCallExpression(node);
-            } else if (UastExpressionUtils.isConstructorCall(node)) {
-                visitNewExpression(node);
-            }
-
-            return result;
-        }
-
-        private void visitMethodCallExpression(UCallExpression node) {
-            if (mVisitMethods) {
-                String methodName = node.getMethodName();
-                if (methodName != null) {
-                    List<VisitingDetector> list = mMethodDetectors.get(methodName);
-                    if (list != null) {
-                        PsiMethod function = node.resolve();
-                        if (function != null) {
-                            for (VisitingDetector v : list) {
-                                UastScanner scanner = v.getUastScanner();
-                                if (scanner != null) {
-                                    scanner.visitMethod(mContext, v.getVisitor(), node,
-                                            mContext.getUastContext().getMethod(function));
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private void visitNewExpression(UCallExpression node) {
-            if (mVisitConstructors) {
-                PsiMethod resolvedConstructor = node.resolve();
-                if (resolvedConstructor == null) {
-                    return;
-                }
-                
-                PsiClass resolvedClass = resolvedConstructor.getContainingClass();
-                if (resolvedClass != null) {
-                    List<VisitingDetector> list = mConstructorDetectors.get(
-                            resolvedClass.getQualifiedName());
-                    if (list != null) {
-                        for (VisitingDetector v : list) {
-                            UastScanner javaPsiScanner = v.getUastScanner();
-                            if (javaPsiScanner != null) {
-                                javaPsiScanner.visitConstructor(mContext,
-                                        v.getVisitor(), node, 
-                                        mContext.getUastContext().getMethod(resolvedConstructor));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java
deleted file mode 100644
index 84922d2..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * 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.klint.client.api;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.google.common.base.Joiner;
-import com.intellij.psi.*;
-
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.java.JavaAbstractUExpression;
-import org.jetbrains.uast.java.JavaUDeclarationsExpression;
-
-import java.util.Collections;
-import java.util.List;
-
-public class UastLintUtils {
-    @Nullable
-    public static String getQualifiedName(PsiElement element) {
-        if (element instanceof PsiClass) {
-            return ((PsiClass) element).getQualifiedName();
-        } else if (element instanceof PsiMethod) {
-            PsiClass containingClass = ((PsiMethod) element).getContainingClass();
-            if (containingClass == null) {
-                return null;
-            }
-            String containingClassFqName = getQualifiedName(containingClass);
-            if (containingClassFqName == null) {
-                return null;
-            }
-            return containingClassFqName + "." + ((PsiMethod) element).getName();
-        } else if (element instanceof PsiField) {
-            PsiClass containingClass = ((PsiField) element).getContainingClass();
-            if (containingClass == null) {
-                return null;
-            }
-            String containingClassFqName = getQualifiedName(containingClass);
-            if (containingClassFqName == null) {
-                return null;
-            }
-            return containingClassFqName + "." + ((PsiField) element).getName();
-        } else {
-            return null;
-        }
-    }
-
-    @Nullable
-    public static PsiElement resolve(ExternalReferenceExpression expression, UElement context) {
-        UDeclaration declaration = UastUtils.getParentOfType(context, UDeclaration.class);
-        if (declaration == null) {
-            return null;
-        }
-
-        return expression.resolve(declaration.getPsi());
-    }
-
-    @NonNull
-    public static String getClassName(PsiClassType type) {
-        PsiClass psiClass = type.resolve();
-        if (psiClass == null) {
-            return type.getClassName();
-        } else {
-            return getClassName(psiClass);
-        }
-    }
-    
-    @NonNull
-    public static String getClassName(PsiClass psiClass) {
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append(psiClass.getName());
-        psiClass = psiClass.getContainingClass();
-        while (psiClass != null) {
-            stringBuilder.insert(0, psiClass.getName() + ".");
-            psiClass = psiClass.getContainingClass();
-        }
-        return stringBuilder.toString();
-    }
-    
-    @Nullable
-    public static UExpression findLastAssignment(
-            @NonNull PsiVariable variable,
-            @NonNull UElement call,
-            @NonNull JavaContext context) {
-        UElement lastAssignment = null;
-        
-        if (variable instanceof UVariable) {
-            variable = ((UVariable) variable).getPsi();
-        }
-        
-        if (!variable.hasModifierProperty(PsiModifier.FINAL) &&
-                (variable instanceof PsiLocalVariable || variable instanceof PsiParameter)) {
-            UMethod containingFunction = UastUtils.getContainingUMethod(call);
-            if (containingFunction != null) {
-                ConstantEvaluator.LastAssignmentFinder finder =
-                        new ConstantEvaluator.LastAssignmentFinder(variable, call, context, null, -1);
-                containingFunction.accept(finder);
-                lastAssignment = finder.getLastAssignment();
-            }
-        } else {
-            lastAssignment = context.getUastContext().getInitializerBody(variable);
-        }
-
-        if (lastAssignment instanceof UExpression) {
-            return (UExpression) lastAssignment;
-        }
-
-        return null;
-    }
-    
-    @Nullable
-    public static String getReferenceName(UReferenceExpression expression) {
-        if (expression instanceof USimpleNameReferenceExpression) {
-            return ((USimpleNameReferenceExpression) expression).getIdentifier();
-        } else if (expression instanceof UQualifiedReferenceExpression) {
-            UExpression selector = ((UQualifiedReferenceExpression) expression).getSelector();
-            if (selector instanceof USimpleNameReferenceExpression) {
-                return ((USimpleNameReferenceExpression) selector).getIdentifier();
-            }
-        }
-        
-        return null;
-    } 
-    
-    @Nullable
-    public static Object findLastValue(
-            @NonNull PsiVariable variable,
-            @NonNull UElement call,
-            @NonNull JavaContext context,
-            @NonNull ConstantEvaluator evaluator) {
-        Object value = null;
-        
-        if (!variable.hasModifierProperty(PsiModifier.FINAL) &&
-                (variable instanceof PsiLocalVariable || variable instanceof PsiParameter)) {
-            UMethod containingFunction = UastUtils.getContainingUMethod(call);
-            if (containingFunction != null) {
-                ConstantEvaluator.LastAssignmentFinder
-                        finder = new ConstantEvaluator.LastAssignmentFinder(
-                        variable, call, context, evaluator, 1);
-                containingFunction.getUastBody().accept(finder);
-                value = finder.getCurrentValue();
-            }
-        } else {
-            UExpression initializer = context.getUastContext().getInitializerBody(variable);
-            if (initializer != null) {
-                value = initializer.evaluate();
-            }
-        }
-
-        return value;
-    }
-
-    @Nullable
-    private static AndroidReference toAndroidReference(UQualifiedReferenceExpression expression) {
-        List<String> path = UastUtils.asQualifiedPath(expression);
-        
-        String packageNameFromResolved = null;
-
-        PsiClass containingClass = UastUtils.getContainingClass(expression.resolve());
-        if (containingClass != null) {
-            String containingClassFqName = containingClass.getQualifiedName();
-            
-            if (containingClassFqName != null) {
-                int i = containingClassFqName.lastIndexOf(".R.");
-                if (i >= 0) {
-                    packageNameFromResolved = containingClassFqName.substring(0, i);
-                }
-            }
-        }
-
-        if (path == null) {
-            return null;
-        }
-
-        int size = path.size();
-        if (size < 3) {
-            return null;
-        }
-
-        String r = path.get(size - 3);
-        if (!r.equals(SdkConstants.R_CLASS)) {
-            return null;
-        }
-
-        String packageName = packageNameFromResolved != null
-                ? packageNameFromResolved
-                : Joiner.on('.').join(path.subList(0, size - 3));
-
-        String type = path.get(size - 2);
-        String name = path.get(size - 1);
-
-        ResourceType resourceType = null;
-        for (ResourceType value : ResourceType.values()) {
-            if (value.getName().equals(type)) {
-                resourceType = value;
-                break;
-            }
-        }
-
-        if (resourceType == null) {
-            return null;
-        }
-
-        return new AndroidReference(expression, packageName, resourceType, name);
-    }
-
-
-    @Nullable
-    public static AndroidReference toAndroidReferenceViaResolve(UElement element) {
-        if (element instanceof UQualifiedReferenceExpression
-                && element instanceof JavaAbstractUExpression) {
-            AndroidReference ref = toAndroidReference((UQualifiedReferenceExpression) element);
-            if (ref != null) {
-                return ref;
-            }
-        }
-
-        PsiElement declaration;
-        if (element instanceof UVariable) {
-            declaration = ((UVariable) element).getPsi();
-        } else if (element instanceof UResolvable) {
-            declaration = ((UResolvable) element).resolve();
-        } else {
-            return null;
-        }
-        
-        if (declaration == null && element instanceof USimpleNameReferenceExpression 
-                && element instanceof JavaAbstractUExpression) {
-            // R class can't be resolved in tests so we need to use heuristics to calc the reference 
-            UExpression maybeQualified = UastUtils.getQualifiedParentOrThis((UExpression) element);
-            if (maybeQualified instanceof UQualifiedReferenceExpression) {
-                AndroidReference ref = toAndroidReference(
-                        (UQualifiedReferenceExpression) maybeQualified);
-                if (ref != null) {
-                    return ref;
-                }
-            }
-        }
-        
-        if (!(declaration instanceof PsiVariable)) {
-            return null;
-        }
-        
-        PsiVariable variable = (PsiVariable) declaration;
-        if (!(variable instanceof PsiField) 
-                || variable.getType() != PsiType.INT
-                || !variable.hasModifierProperty(PsiModifier.STATIC) 
-                || !variable.hasModifierProperty(PsiModifier.FINAL)) {
-            return null;
-        }
-        
-        PsiClass resTypeClass = ((PsiField) variable).getContainingClass();
-        if (resTypeClass == null || !resTypeClass.hasModifierProperty(PsiModifier.STATIC)) {
-            return null;
-        }
-        
-        PsiClass rClass = resTypeClass.getContainingClass();
-        if (rClass == null || rClass.getContainingClass() != null || !"R".equals(rClass.getName())) {
-            return null;
-        }
-        
-        String packageName = ((PsiJavaFile) rClass.getContainingFile()).getPackageName();
-        if (packageName.isEmpty()) {
-            return null;
-        }
-
-        String resourceTypeName = resTypeClass.getName();
-        ResourceType resourceType = null;
-        for (ResourceType value : ResourceType.values()) {
-            if (value.getName().equals(resourceTypeName)) {
-                resourceType = value;
-                break;
-            }
-        }
-
-        if (resourceType == null) {
-            return null;
-        }
-
-        String resourceName = variable.getName();
-
-        UExpression node;
-        if (element instanceof UExpression) {
-            node = (UExpression) element;
-        } else if (element instanceof UVariable) {
-            node = new JavaUDeclarationsExpression(
-                    null, Collections.singletonList(((UVariable) element)));
-        } else {
-            throw new IllegalArgumentException("element must be an expression or an UVariable");
-        }
-
-        return new AndroidReference(node, packageName, resourceType, resourceName);
-    }
-
-    public static boolean areIdentifiersEqual(UExpression first, UExpression second) {
-        String firstIdentifier = getIdentifier(first);
-        String secondIdentifier = getIdentifier(second);
-        return firstIdentifier != null && secondIdentifier != null
-                && firstIdentifier.equals(secondIdentifier);
-    }
-
-    @Nullable
-    public static String getIdentifier(UExpression expression) {
-        if (expression instanceof ULiteralExpression) {
-            expression.asRenderString();
-        } else if (expression instanceof USimpleNameReferenceExpression) {
-            return ((USimpleNameReferenceExpression) expression).getIdentifier();
-        } else if (expression instanceof UQualifiedReferenceExpression) {
-            UQualifiedReferenceExpression qualified = (UQualifiedReferenceExpression) expression;
-            String receiverIdentifier = getIdentifier(qualified.getReceiver());
-            String selectorIdentifier = getIdentifier(qualified.getSelector());
-            if (receiverIdentifier == null || selectorIdentifier == null) {
-                return null;
-            }
-            return receiverIdentifier + "." + selectorIdentifier;
-        }
-
-        return null;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/XmlParser.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/XmlParser.java
deleted file mode 100644
index 4a50c67..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/XmlParser.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.annotations.Beta;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-/**
- * A wrapper for an XML parser. This allows tools integrating lint to map directly
- * to builtin services, such as already-parsed data structures in XML editors.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class XmlParser {
-    /**
-     * Parse the file pointed to by the given context and return as a Document
-     *
-     * @param context the context pointing to the file to be parsed, typically
-     *            via {@link Context#getContents()} but the file handle (
-     *            {@link Context#file} can also be used to map to an existing
-     *            editor buffer in the surrounding tool, etc)
-     * @return the parsed DOM document, or null if parsing fails
-     */
-    @Nullable
-    public abstract Document parseXml(@NonNull XmlContext context);
-
-    /**
-     * Returns a {@link Location} for the given DOM node
-     *
-     * @param context information about the file being parsed
-     * @param node the node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public abstract Location getLocation(@NonNull XmlContext context, @NonNull Node node);
-
-    /**
-     * Returns a {@link Location} for the given DOM node. Like
-     * {@link #getLocation(XmlContext, Node)}, but allows a position range that
-     * is a subset of the node range.
-     *
-     * @param context information about the file being parsed
-     * @param node the node to create a location for
-     * @param start the starting position within the node, inclusive
-     * @param end the ending position within the node, exclusive
-     * @return a location for the given node
-     */
-    @NonNull
-    public abstract Location getLocation(@NonNull XmlContext context, @NonNull Node node,
-            int start, int end);
-
-    /**
-     * Returns a {@link Location} for the given DOM node
-     *
-     * @param context information about the file being parsed
-     * @param node the node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public abstract Location getNameLocation(@NonNull XmlContext context, @NonNull Node node);
-
-    /**
-     * Returns a {@link Location} for the given DOM node
-     *
-     * @param context information about the file being parsed
-     * @param node the node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public abstract Location getValueLocation(@NonNull XmlContext context, @NonNull Attr node);
-
-    /**
-     * Creates a light-weight handle to a location for the given node. It can be
-     * turned into a full fledged location by
-     * {@link com.android.tools.lint.detector.api.Location.Handle#resolve()}.
-     *
-     * @param context the context providing the node
-     * @param node the node (element or attribute) to create a location handle
-     *            for
-     * @return a location handle
-     */
-    @NonNull
-    public abstract Location.Handle createLocationHandle(@NonNull XmlContext context,
-            @NonNull Node node);
-
-    /**
-     * Dispose any data structures held for the given context.
-     * @param context information about the file previously parsed
-     * @param document the document that was parsed and is now being disposed
-     */
-    public void dispose(@NonNull XmlContext context, @NonNull Document document) {
-    }
-
-    /**
-     * Returns the start offset of the given node, or -1 if not known
-     *
-     * @param context the context providing the node
-     * @param node the node (element or attribute) to create a location handle
-     *            for
-     * @return the start offset, or -1 if not known
-     */
-    public abstract int getNodeStartOffset(@NonNull XmlContext context, @NonNull Node node);
-
-    /**
-     * Returns the end offset of the given node, or -1 if not known
-     *
-     * @param context the context providing the node
-     * @param node the node (element or attribute) to create a location handle
-     *            for
-     * @return the end offset, or -1 if not known
-     */
-    public abstract int getNodeEndOffset(@NonNull XmlContext context, @NonNull Node node);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Category.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Category.java
deleted file mode 100644
index 8bcb56a..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Category.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.annotations.Beta;
-
-/**
- * A category is a container for related issues.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public final class Category implements Comparable<Category> {
-    private final String mName;
-    private final int mPriority;
-    private final Category mParent;
-
-    /**
-     * Creates a new {@link Category}.
-     *
-     * @param parent the name of a parent category, or null
-     * @param name the name of the category
-     * @param priority a sorting priority, with higher being more important
-     */
-    private Category(
-            @Nullable Category parent,
-            @NonNull String name,
-            int priority) {
-        mParent = parent;
-        mName = name;
-        mPriority = priority;
-    }
-
-    /**
-     * Creates a new top level {@link Category} with the given sorting priority.
-     *
-     * @param name the name of the category
-     * @param priority a sorting priority, with higher being more important
-     * @return a new category
-     */
-    @NonNull
-    public static Category create(@NonNull String name, int priority) {
-        return new Category(null, name, priority);
-    }
-
-    /**
-     * Creates a new top level {@link Category} with the given sorting priority.
-     *
-     * @param parent the name of a parent category, or null
-     * @param name the name of the category
-     * @param priority a sorting priority, with higher being more important
-     * @return a new category
-     */
-    @NonNull
-    public static Category create(@Nullable Category parent, @NonNull String name, int priority) {
-        return new Category(parent, name, priority);
-    }
-
-    /**
-     * Returns the parent category, or null if this is a top level category
-     *
-     * @return the parent category, or null if this is a top level category
-     */
-    public Category getParent() {
-        return mParent;
-    }
-
-    /**
-     * Returns the name of this category
-     *
-     * @return the name of this category
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Returns a full name for this category. For a top level category, this is just
-     * the {@link #getName()} value, but for nested categories it will include the parent
-     * names as well.
-     *
-     * @return a full name for this category
-     */
-    public String getFullName() {
-        if (mParent != null) {
-            return mParent.getFullName() + ':' + mName;
-        } else {
-            return mName;
-        }
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        Category category = (Category) o;
-
-        //noinspection SimplifiableIfStatement
-        if (!mName.equals(category.mName)) {
-            return false;
-        }
-        return mParent != null ? mParent.equals(category.mParent) : category.mParent == null;
-
-    }
-
-    @Override
-    public String toString() {
-        return getFullName();
-    }
-
-    @Override
-    public int hashCode() {
-        return mName.hashCode();
-    }
-
-    @Override
-    public int compareTo(@NonNull Category other) {
-        if (other.mPriority == mPriority) {
-            if (mParent == other) {
-                return 1;
-            } else if (other.mParent == this) {
-                return -1;
-            }
-        }
-
-        int delta = other.mPriority - mPriority;
-        if (delta != 0) {
-            return delta;
-        }
-
-        return mName.compareTo(other.mName);
-    }
-
-    /** Issues related to running lint itself */
-    public static final Category LINT = create("Lint", 110);
-
-    /** Issues related to correctness */
-    public static final Category CORRECTNESS = create("Correctness", 100);
-
-    /** Issues related to security */
-    public static final Category SECURITY = create("Security", 90);
-
-    /** Issues related to performance */
-    public static final Category PERFORMANCE = create("Performance", 80);
-
-    /** Issues related to usability */
-    public static final Category USABILITY = create("Usability", 70);
-
-    /** Issues related to accessibility */
-    public static final Category A11Y = create("Accessibility", 60);
-
-    /** Issues related to internationalization */
-    public static final Category I18N = create("Internationalization", 50);
-
-    // Sub categories
-
-    /** Issues related to icons */
-    public static final Category ICONS = create(USABILITY, "Icons", 73);
-
-    /** Issues related to typography */
-    public static final Category TYPOGRAPHY = create(USABILITY, "Typography", 76);
-
-    /** Issues related to messages/strings */
-    public static final Category MESSAGES = create(CORRECTNESS, "Messages", 95);
-
-    /** Issues related to right to left and bidirectional text support */
-    public static final Category RTL = create(I18N, "Bidirectional Text", 40);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ClassContext.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ClassContext.java
deleted file mode 100644
index 07759bd..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ClassContext.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.SdkConstants.CONSTRUCTOR_NAME;
-import static com.android.SdkConstants.DOT_CLASS;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.tools.klint.detector.api.Location.SearchDirection.BACKWARD;
-import static com.android.tools.klint.detector.api.Location.SearchDirection.EOL_BACKWARD;
-import static com.android.tools.klint.detector.api.Location.SearchDirection.FORWARD;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.detector.api.Location.SearchDirection;
-import com.android.tools.klint.detector.api.Location.SearchHints;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Splitter;
-
-import org.jetbrains.org.objectweb.asm.Type;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.FieldNode;
-import org.jetbrains.org.objectweb.asm.tree.LineNumberNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * A {@link Context} used when checking .class files.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class ClassContext extends Context {
-    private final File mBinDir;
-    /** The class file DOM root node */
-    private final ClassNode mClassNode;
-    /** The class file byte data */
-    private final byte[] mBytes;
-    /** The source file, if known/found */
-    private File mSourceFile;
-    /** The contents of the source file, if source file is known/found */
-    private String mSourceContents;
-    /** Whether we've searched for the source file (used to avoid repeated failed searches) */
-    private boolean mSearchedForSource;
-    /** If the file is a relative path within a jar file, this is the jar file, otherwise null */
-    private final File mJarFile;
-    /** Whether this class is part of a library (rather than corresponding to one of the
-     * source files in this project */
-    private final boolean mFromLibrary;
-
-    /**
-     * Construct a new {@link ClassContext}
-     *
-     * @param driver the driver running through the checks
-     * @param project the project containing the file being checked
-     * @param main the main project if this project is a library project, or
-     *            null if this is not a library project. The main project is the
-     *            root project of all library projects, not necessarily the
-     *            directly including project.
-     * @param file the file being checked
-     * @param jarFile If the file is a relative path within a jar file, this is
-     *            the jar file, otherwise null
-     * @param binDir the root binary directory containing this .class file.
-     * @param bytes the bytecode raw data
-     * @param classNode the bytecode object model
-     * @param fromLibrary whether this class is from a library rather than part
-     *            of this project
-     * @param sourceContents initial contents of the Java source, if known, or
-     *            null
-     */
-    public ClassContext(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File file,
-            @Nullable File jarFile,
-            @NonNull File binDir,
-            @NonNull byte[] bytes,
-            @NonNull ClassNode classNode,
-            boolean fromLibrary,
-            @Nullable String sourceContents) {
-        super(driver, project, main, file);
-        mJarFile = jarFile;
-        mBinDir = binDir;
-        mBytes = bytes;
-        mClassNode = classNode;
-        mFromLibrary = fromLibrary;
-        mSourceContents = sourceContents;
-    }
-
-    /**
-     * Returns the raw bytecode data for this class file
-     *
-     * @return the byte array containing the bytecode data
-     */
-    @NonNull
-    public byte[] getBytecode() {
-        return mBytes;
-    }
-
-    /**
-     * Returns the bytecode object model
-     *
-     * @return the bytecode object model, never null
-     */
-    @NonNull
-    public ClassNode getClassNode() {
-        return mClassNode;
-    }
-
-    /**
-     * Returns the jar file, if any. If this is null, the .class file is a real file
-     * on disk, otherwise it represents a relative path within the jar file.
-     *
-     * @return the jar file, or null
-     */
-    @Nullable
-    public File getJarFile() {
-        return mJarFile;
-    }
-
-    /**
-     * Returns whether this class is part of a library (not this project).
-     *
-     * @return true if this class is part of a library
-     */
-    public boolean isFromClassLibrary() {
-        return mFromLibrary;
-    }
-
-    /**
-     * Returns the source file for this class file, if possible.
-     *
-     * @return the source file, or null
-     */
-    @Nullable
-    public File getSourceFile() {
-        if (mSourceFile == null && !mSearchedForSource) {
-            mSearchedForSource = true;
-
-            String source = mClassNode.sourceFile;
-            if (source == null) {
-                source = file.getName();
-                if (source.endsWith(DOT_CLASS)) {
-                    source = source.substring(0, source.length() - DOT_CLASS.length()) + ".kt";
-                }
-                int index = source.indexOf('$');
-                if (index != -1) {
-                    source = source.substring(0, index) + ".kt";
-                }
-            }
-            if (source != null) {
-                if (mJarFile != null) {
-                    String relative = file.getParent() + File.separator + source;
-                    List<File> sources = getProject().getJavaSourceFolders();
-                    for (File dir : sources) {
-                        File sourceFile = new File(dir, relative);
-                        if (sourceFile.exists()) {
-                            mSourceFile = sourceFile;
-                            break;
-                        }
-                    }
-                } else {
-                    // Determine package
-                    String topPath = mBinDir.getPath();
-                    String parentPath = file.getParentFile().getPath();
-                    if (parentPath.startsWith(topPath)) {
-                        int start = topPath.length() + 1;
-                        String relative = start > parentPath.length() ? // default package?
-                                "" : parentPath.substring(start);
-                        List<File> sources = getProject().getJavaSourceFolders();
-                        for (File dir : sources) {
-                            File sourceFile = new File(dir, relative + File.separator + source);
-                            if (sourceFile.exists()) {
-                                mSourceFile = sourceFile;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return mSourceFile;
-    }
-
-    /**
-     * Returns the contents of the source file for this class file, if found.
-     *
-     * @return the source contents, or ""
-     */
-    @NonNull
-    public String getSourceContents() {
-        if (mSourceContents == null) {
-            File sourceFile = getSourceFile();
-            if (sourceFile != null) {
-                mSourceContents = getClient().readFile(mSourceFile);
-            }
-
-            if (mSourceContents == null) {
-                mSourceContents = "";
-            }
-        }
-
-        return mSourceContents;
-    }
-
-    /**
-     * Returns the contents of the source file for this class file, if found. If
-     * {@code read} is false, do not read the source contents if it has not
-     * already been read. (This is primarily intended for the lint
-     * infrastructure; most client code would call {@link #getSourceContents()}
-     * .)
-     *
-     * @param read whether to read the source contents if it has not already
-     *            been initialized
-     * @return the source contents, which will never be null if {@code read} is
-     *         true, or null if {@code read} is false and the source contents
-     *         hasn't already been read.
-     */
-    @Nullable
-    public String getSourceContents(boolean read) {
-        if (read) {
-            return getSourceContents();
-        } else {
-            return mSourceContents;
-        }
-    }
-
-    /**
-     * Returns a location for the given source line number in this class file's
-     * source file, if available.
-     *
-     * @param line the line number (1-based, which is what ASM uses)
-     * @param patternStart optional pattern to search for in the source for
-     *            range start
-     * @param patternEnd optional pattern to search for in the source for range
-     *            end
-     * @param hints additional hints about the pattern search (provided
-     *            {@code patternStart} is non null)
-     * @return a location, never null
-     */
-    @NonNull
-    public Location getLocationForLine(int line, @Nullable String patternStart,
-            @Nullable String patternEnd, @Nullable SearchHints hints) {
-        File sourceFile = getSourceFile();
-        if (sourceFile != null) {
-            // ASM line numbers are 1-based, and lint line numbers are 0-based
-            if (line != -1) {
-                return Location.create(sourceFile, getSourceContents(), line - 1,
-                        patternStart, patternEnd, hints);
-            } else {
-                return Location.create(sourceFile);
-            }
-        }
-
-        return Location.create(file);
-    }
-
-    /**
-     * Reports an issue.
-     * <p>
-     * Detectors should only call this method if an error applies to the whole class
-     * scope and there is no specific method or field that applies to the error.
-     * If so, use
-     * {@link #report(Issue, MethodNode, AbstractInsnNode, Location, String)} or
-     * {@link #report(Issue, FieldNode, Location, String)}, such that
-     * suppress annotations are checked.
-     *
-     * @param issue the issue to report
-     * @param location the location of the issue, or null if not known
-     * @param message the message for this warning
-     */
-    @Override
-    public void report(
-            @NonNull Issue issue,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (mDriver.isSuppressed(issue, mClassNode)) {
-            return;
-        }
-        ClassNode curr = mClassNode;
-        while (curr != null) {
-            ClassNode prev = curr;
-            curr = mDriver.getOuterClassNode(curr);
-            if (curr != null) {
-                if (prev.outerMethod != null) {
-                    @SuppressWarnings("rawtypes") // ASM API
-                    List methods = curr.methods;
-                    for (Object m : methods) {
-                        MethodNode method = (MethodNode) m;
-                        if (method.name.equals(prev.outerMethod)
-                                && method.desc.equals(prev.outerMethodDesc)) {
-                            // Found the outer method for this anonymous class; continue
-                            // reporting on it (which will also work its way up the parent
-                            // class hierarchy)
-                            if (method != null && mDriver.isSuppressed(issue, mClassNode, method,
-                                    null)) {
-                                return;
-                            }
-                            break;
-                        }
-                    }
-                }
-                if (mDriver.isSuppressed(issue, curr)) {
-                    return;
-                }
-            }
-        }
-
-        super.report(issue, location, message);
-    }
-
-    // Unfortunately, ASMs nodes do not extend a common DOM node type with parent
-    // pointers, so we have to have multiple methods which pass in each type
-    // of node (class, method, field) to be checked.
-
-    /**
-     * Reports an issue applicable to a given method node.
-     *
-     * @param issue the issue to report
-     * @param method the method scope the error applies to. The lint
-     *            infrastructure will check whether there are suppress
-     *            annotations on this method (or its enclosing class) and if so
-     *            suppress the warning without involving the client.
-     * @param instruction the instruction within the method the error applies
-     *            to. You cannot place annotations on individual method
-     *            instructions (for example, annotations on local variables are
-     *            allowed, but are not kept in the .class file). However, this
-     *            instruction is needed to handle suppressing errors on field
-     *            initializations; in that case, the errors may be reported in
-     *            the {@code <clinit>} method, but the annotation is found not
-     *            on that method but for the {@link FieldNode}'s.
-     * @param location the location of the issue, or null if not known
-     * @param message the message for this warning
-     */
-    public void report(
-            @NonNull Issue issue,
-            @Nullable MethodNode method,
-            @Nullable AbstractInsnNode instruction,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (method != null && mDriver.isSuppressed(issue, mClassNode, method, instruction)) {
-            return;
-        }
-        report(issue, location, message); // also checks the class node
-    }
-
-    /**
-     * Reports an issue applicable to a given method node.
-     *
-     * @param issue the issue to report
-     * @param field the scope the error applies to. The lint infrastructure
-     *    will check whether there are suppress annotations on this field (or its enclosing
-     *    class) and if so suppress the warning without involving the client.
-     * @param location the location of the issue, or null if not known
-     * @param message the message for this warning
-     */
-    public void report(
-            @NonNull Issue issue,
-            @Nullable FieldNode field,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (field != null && mDriver.isSuppressed(issue, field)) {
-            return;
-        }
-        report(issue, location, message); // also checks the class node
-    }
-
-    /**
-     * Report an error.
-     * Like {@link #report(Issue, MethodNode, AbstractInsnNode, Location, String)} but with
-     * a now-unused data parameter at the end.
-     *
-     * @deprecated Use {@link #report(Issue, FieldNode, Location, String)} instead;
-     *    this method is here for custom rule compatibility
-     */
-    @SuppressWarnings("UnusedDeclaration") // Potentially used by external existing custom rules
-    @Deprecated
-    public void report(
-            @NonNull Issue issue,
-            @Nullable MethodNode method,
-            @Nullable AbstractInsnNode instruction,
-            @NonNull Location location,
-            @NonNull String message,
-            @SuppressWarnings("UnusedParameters") @Nullable Object data) {
-        report(issue, method, instruction, location, message);
-    }
-
-    /**
-     * Report an error.
-     * Like {@link #report(Issue, FieldNode, Location, String)} but with
-     * a now-unused data parameter at the end.
-     *
-     * @deprecated Use {@link #report(Issue, FieldNode, Location, String)} instead;
-     *    this method is here for custom rule compatibility
-     */
-    @SuppressWarnings("UnusedDeclaration") // Potentially used by external existing custom rules
-    @Deprecated
-    public void report(
-            @NonNull Issue issue,
-            @Nullable FieldNode field,
-            @NonNull Location location,
-            @NonNull String message,
-            @SuppressWarnings("UnusedParameters") @Nullable Object data) {
-        report(issue, field, location, message);
-    }
-
-    /**
-     * Finds the line number closest to the given node
-     *
-     * @param node the instruction node to get a line number for
-     * @return the closest line number, or -1 if not known
-     */
-    public static int findLineNumber(@NonNull AbstractInsnNode node) {
-        AbstractInsnNode curr = node;
-
-        // First search backwards
-        while (curr != null) {
-            if (curr.getType() == AbstractInsnNode.LINE) {
-                return ((LineNumberNode) curr).line;
-            }
-            curr = curr.getPrevious();
-        }
-
-        // Then search forwards
-        curr = node;
-        while (curr != null) {
-            if (curr.getType() == AbstractInsnNode.LINE) {
-                return ((LineNumberNode) curr).line;
-            }
-            curr = curr.getNext();
-        }
-
-        return -1;
-    }
-
-    /**
-     * Finds the line number closest to the given method declaration
-     *
-     * @param node the method node to get a line number for
-     * @return the closest line number, or -1 if not known
-     */
-    public static int findLineNumber(@NonNull MethodNode node) {
-        if (node.instructions != null && node.instructions.size() > 0) {
-            return findLineNumber(node.instructions.get(0));
-        }
-
-        return -1;
-    }
-
-    /**
-     * Finds the line number closest to the given class declaration
-     *
-     * @param node the method node to get a line number for
-     * @return the closest line number, or -1 if not known
-     */
-    public static int findLineNumber(@NonNull ClassNode node) {
-        if (node.methods != null && !node.methods.isEmpty()) {
-            MethodNode firstMethod = getFirstRealMethod(node);
-            if (firstMethod != null) {
-                return findLineNumber(firstMethod);
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns a location for the given {@link ClassNode}, where class node is
-     * either the top level class, or an inner class, in the current context.
-     *
-     * @param classNode the class in the current context
-     * @return a location pointing to the class declaration, or as close to it
-     *         as possible
-     */
-    @NonNull
-    public Location getLocation(@NonNull ClassNode classNode) {
-        // Attempt to find a proper location for this class. This is tricky
-        // since classes do not have line number entries in the class file; we need
-        // to find a method, look up the corresponding line number then search
-        // around it for a suitable tag, such as the class name.
-        String pattern;
-        if (isAnonymousClass(classNode.name)) {
-            pattern = classNode.superName;
-        } else {
-            pattern = classNode.name;
-        }
-        int index = pattern.lastIndexOf('$');
-        if (index != -1) {
-            pattern = pattern.substring(index + 1);
-        }
-        index = pattern.lastIndexOf('/');
-        if (index != -1) {
-            pattern = pattern.substring(index + 1);
-        }
-
-        return getLocationForLine(findLineNumber(classNode), pattern, null,
-                SearchHints.create(BACKWARD).matchJavaSymbol());
-    }
-
-    @Nullable
-    private static MethodNode getFirstRealMethod(@NonNull ClassNode classNode) {
-        // Return the first method in the class for line number purposes. Skip <init>,
-        // since it's typically not located near the real source of the method.
-        if (classNode.methods != null) {
-            @SuppressWarnings("rawtypes") // ASM API
-            List methods = classNode.methods;
-            for (Object m : methods) {
-                MethodNode method = (MethodNode) m;
-                if (method.name.charAt(0) != '<') {
-                    return method;
-                }
-            }
-
-            if (!classNode.methods.isEmpty()) {
-                return (MethodNode) classNode.methods.get(0);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a location for the given {@link MethodNode}.
-     *
-     * @param methodNode the class in the current context
-     * @param classNode the class containing the method
-     * @return a location pointing to the class declaration, or as close to it
-     *         as possible
-     */
-    @NonNull
-    public Location getLocation(@NonNull MethodNode methodNode,
-            @NonNull ClassNode classNode) {
-        // Attempt to find a proper location for this class. This is tricky
-        // since classes do not have line number entries in the class file; we need
-        // to find a method, look up the corresponding line number then search
-        // around it for a suitable tag, such as the class name.
-        String pattern;
-        SearchDirection searchMode;
-        if (methodNode.name.equals(CONSTRUCTOR_NAME)) {
-            searchMode = EOL_BACKWARD;
-            if (isAnonymousClass(classNode.name)) {
-                pattern = classNode.superName.substring(classNode.superName.lastIndexOf('/') + 1);
-            } else {
-                pattern = classNode.name.substring(classNode.name.lastIndexOf('$') + 1);
-            }
-        } else {
-            searchMode = BACKWARD;
-            pattern = methodNode.name;
-        }
-
-        return getLocationForLine(findLineNumber(methodNode), pattern, null,
-                SearchHints.create(searchMode).matchJavaSymbol());
-    }
-
-    /**
-     * Returns a location for the given {@link AbstractInsnNode}.
-     *
-     * @param instruction the instruction to look up the location for
-     * @return a location pointing to the instruction, or as close to it
-     *         as possible
-     */
-    @NonNull
-    public Location getLocation(@NonNull AbstractInsnNode instruction) {
-        SearchHints hints = SearchHints.create(FORWARD).matchJavaSymbol();
-        String pattern = null;
-        if (instruction instanceof MethodInsnNode) {
-            MethodInsnNode call = (MethodInsnNode) instruction;
-            if (call.name.equals(CONSTRUCTOR_NAME)) {
-                pattern = call.owner;
-                hints = hints.matchConstructor();
-            } else {
-                pattern = call.name;
-            }
-            int index = pattern.lastIndexOf('$');
-            if (index != -1) {
-                pattern = pattern.substring(index + 1);
-            }
-            index = pattern.lastIndexOf('/');
-            if (index != -1) {
-                pattern = pattern.substring(index + 1);
-            }
-        }
-
-        int line = findLineNumber(instruction);
-        return getLocationForLine(line, pattern, null, hints);
-    }
-
-    private static boolean isAnonymousClass(@NonNull String fqcn) {
-        int lastIndex = fqcn.lastIndexOf('$');
-        if (lastIndex != -1 && lastIndex < fqcn.length() - 1) {
-            if (Character.isDigit(fqcn.charAt(lastIndex + 1))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Converts from a VM owner name (such as foo/bar/Foo$Baz) to a
-     * fully qualified class name (such as foo.bar.Foo.Baz).
-     *
-     * @param owner the owner name to convert
-     * @return the corresponding fully qualified class name
-     */
-    @NonNull
-    public static String getFqcn(@NonNull String owner) {
-        return owner.replace('/', '.').replace('$','.');
-    }
-
-    /**
-     * Computes a user-readable type signature from the given class owner, name
-     * and description. For example, for owner="foo/bar/Foo$Baz", name="foo",
-     * description="(I)V", it returns "void foo.bar.Foo.Bar#foo(int)".
-     *
-     * @param owner the class name
-     * @param name the method name
-     * @param desc the method description
-     * @return a user-readable string
-     */
-    public static String createSignature(String owner, String name, String desc) {
-        StringBuilder sb = new StringBuilder(100);
-
-        if (desc != null) {
-            Type returnType = Type.getReturnType(desc);
-            sb.append(getTypeString(returnType));
-            sb.append(' ');
-        }
-
-        if (owner != null) {
-            sb.append(getFqcn(owner));
-        }
-        if (name != null) {
-            sb.append('#');
-            sb.append(name);
-            if (desc != null) {
-                Type[] argumentTypes = Type.getArgumentTypes(desc);
-                if (argumentTypes != null && argumentTypes.length > 0) {
-                    sb.append('(');
-                    boolean first = true;
-                    for (Type type : argumentTypes) {
-                        if (first) {
-                            first = false;
-                        } else {
-                            sb.append(", ");
-                        }
-                        sb.append(getTypeString(type));
-                    }
-                    sb.append(')');
-                }
-            }
-        }
-
-        return sb.toString();
-    }
-
-    private static String getTypeString(Type type) {
-        String s = type.getClassName();
-        if (s.startsWith("java.lang.")) {           //$NON-NLS-1$
-            s = s.substring("java.lang.".length()); //$NON-NLS-1$
-        }
-
-        return s;
-    }
-
-    /**
-     * Computes the internal class name of the given fully qualified class name.
-     * For example, it converts foo.bar.Foo.Bar into foo/bar/Foo$Bar
-     *
-     * @param fqcn the fully qualified class name
-     * @return the internal class name
-     */
-    @NonNull
-    public static String getInternalName(@NonNull String fqcn) {
-        if (fqcn.indexOf('.') == -1) {
-            return fqcn;
-        }
-
-        int index = fqcn.indexOf('<');
-        if(index != -1) {
-            fqcn = fqcn.substring(0, index);
-        }
-
-        // If class name contains $, it's not an ambiguous inner class name.
-        if (fqcn.indexOf('$') != -1) {
-            return fqcn.replace('.', '/');
-        }
-        // Let's assume that components that start with Caps are class names.
-        StringBuilder sb = new StringBuilder(fqcn.length());
-        String prev = null;
-        for (String part : Splitter.on('.').split(fqcn)) {
-            if (prev != null && !prev.isEmpty()) {
-                if (Character.isUpperCase(prev.charAt(0))) {
-                    sb.append('$');
-                } else {
-                    sb.append('/');
-                }
-            }
-            sb.append(part);
-            prev = part;
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java
deleted file mode 100644
index 99a602c..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.detector.api;
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_BOOLEAN;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_BYTE;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_CHAR;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_DOUBLE;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_FLOAT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_INT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_LONG;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_OBJECT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_SHORT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-import static com.android.tools.klint.detector.api.JavaContext.getParentOfType;
-import static org.jetbrains.uast.UastBinaryExpressionWithTypeKind.TYPE_CAST;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaParser.ResolvedField;
-import com.android.tools.klint.client.api.JavaParser.ResolvedNode;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.google.common.collect.Lists;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.PsiArrayInitializerExpression;
-import com.intellij.psi.PsiArrayType;
-import com.intellij.psi.PsiAssignmentExpression;
-import com.intellij.psi.PsiBinaryExpression;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiConditionalExpression;
-import com.intellij.psi.PsiDeclarationStatement;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiExpressionStatement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiLiteral;
-import com.intellij.psi.PsiLocalVariable;
-import com.intellij.psi.PsiNewExpression;
-import com.intellij.psi.PsiParenthesizedExpression;
-import com.intellij.psi.PsiPrefixExpression;
-import com.intellij.psi.PsiPrimitiveType;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiReferenceExpression;
-import com.intellij.psi.PsiStatement;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiTypeCastExpression;
-import com.intellij.psi.PsiTypeElement;
-import com.intellij.psi.PsiVariable;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiTreeUtil;
-
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import lombok.ast.ArrayCreation;
-import lombok.ast.ArrayInitializer;
-import lombok.ast.BinaryExpression;
-import lombok.ast.BinaryOperator;
-import lombok.ast.BooleanLiteral;
-import lombok.ast.Cast;
-import lombok.ast.CharLiteral;
-import lombok.ast.Expression;
-import lombok.ast.ExpressionStatement;
-import lombok.ast.FloatingPointLiteral;
-import lombok.ast.InlineIfExpression;
-import lombok.ast.IntegralLiteral;
-import lombok.ast.Node;
-import lombok.ast.NullLiteral;
-import lombok.ast.Select;
-import lombok.ast.Statement;
-import lombok.ast.StrictListAccessor;
-import lombok.ast.StringLiteral;
-import lombok.ast.TypeReference;
-import lombok.ast.UnaryExpression;
-import lombok.ast.UnaryOperator;
-import lombok.ast.VariableDeclaration;
-import lombok.ast.VariableDefinition;
-import lombok.ast.VariableDefinitionEntry;
-import lombok.ast.VariableReference;
-
-/** Evaluates constant expressions */
-public class ConstantEvaluator {
-    private final JavaContext mContext;
-    private boolean mAllowUnknown;
-
-    /**
-     * Creates a new constant evaluator
-     *
-     * @param context the context to use to resolve field references, if any
-     */
-    public ConstantEvaluator(@Nullable JavaContext context) {
-        mContext = context;
-    }
-
-    /**
-     * Whether we allow computing values where some terms are unknown. For example, the expression
-     * {@code "foo" + x + "bar"} would return {@code null} without and {@code "foobar"} with.
-     *
-     * @return this for constructor chaining
-     */
-    public ConstantEvaluator allowUnknowns() {
-        mAllowUnknown = true;
-        return this;
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any
-     *
-     * @param node the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     * @deprecated Use {@link #evaluate(PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public Object evaluate(@NonNull Node node) {
-        if (node instanceof NullLiteral) {
-            return null;
-        } else if (node instanceof BooleanLiteral) {
-            return ((BooleanLiteral)node).astValue();
-        } else if (node instanceof StringLiteral) {
-            StringLiteral string = (StringLiteral) node;
-            return string.astValue();
-        } else if (node instanceof CharLiteral) {
-            return ((CharLiteral)node).astValue();
-        } else if (node instanceof IntegralLiteral) {
-            IntegralLiteral literal = (IntegralLiteral) node;
-            // Don't combine to ?: since that will promote astIntValue to a long
-            if (literal.astMarkedAsLong()) {
-                return literal.astLongValue();
-            } else {
-                return literal.astIntValue();
-            }
-        } else if (node instanceof FloatingPointLiteral) {
-            FloatingPointLiteral literal = (FloatingPointLiteral) node;
-            // Don't combine to ?: since that will promote astFloatValue to a double
-            if (literal.astMarkedAsFloat()) {
-                return literal.astFloatValue();
-            } else {
-                return literal.astDoubleValue();
-            }
-        } else if (node instanceof UnaryExpression) {
-            UnaryOperator operator = ((UnaryExpression) node).astOperator();
-            Object operand = evaluate(((UnaryExpression) node).astOperand());
-            if (operand == null) {
-                return null;
-            }
-            switch (operator) {
-                case LOGICAL_NOT:
-                    if (operand instanceof Boolean) {
-                        return !(Boolean) operand;
-                    }
-                    break;
-                case UNARY_PLUS:
-                    return operand;
-                case BINARY_NOT:
-                    if (operand instanceof Integer) {
-                        return ~(Integer) operand;
-                    } else if (operand instanceof Long) {
-                        return ~(Long) operand;
-                    } else if (operand instanceof Short) {
-                        return ~(Short) operand;
-                    } else if (operand instanceof Character) {
-                        return ~(Character) operand;
-                    } else if (operand instanceof Byte) {
-                        return ~(Byte) operand;
-                    }
-                    break;
-                case UNARY_MINUS:
-                    if (operand instanceof Integer) {
-                        return -(Integer) operand;
-                    } else if (operand instanceof Long) {
-                        return -(Long) operand;
-                    } else if (operand instanceof Double) {
-                        return -(Double) operand;
-                    } else if (operand instanceof Float) {
-                        return -(Float) operand;
-                    } else if (operand instanceof Short) {
-                        return -(Short) operand;
-                    } else if (operand instanceof Character) {
-                        return -(Character) operand;
-                    } else if (operand instanceof Byte) {
-                        return -(Byte) operand;
-                    }
-                    break;
-            }
-        } else if (node instanceof InlineIfExpression) {
-            InlineIfExpression expression = (InlineIfExpression) node;
-            Object known = evaluate(expression.astCondition());
-            if (known == Boolean.TRUE && expression.astIfTrue() != null) {
-                return evaluate(expression.astIfTrue());
-            } else if (known == Boolean.FALSE && expression.astIfFalse() != null) {
-                return evaluate(expression.astIfFalse());
-            }
-        } else if (node instanceof BinaryExpression) {
-            BinaryOperator operator = ((BinaryExpression) node).astOperator();
-            Object operandLeft = evaluate(((BinaryExpression) node).astLeft());
-            Object operandRight = evaluate(((BinaryExpression) node).astRight());
-            if (operandLeft == null || operandRight == null) {
-                if (mAllowUnknown) {
-                    if (operandLeft == null) {
-                        return operandRight;
-                    } else {
-                        return operandLeft;
-                    }
-                }
-                return null;
-            }
-            if (operandLeft instanceof String && operandRight instanceof String) {
-                if (operator == BinaryOperator.PLUS) {
-                    return operandLeft.toString() + operandRight.toString();
-                }
-                return null;
-            } else if (operandLeft instanceof Boolean && operandRight instanceof Boolean) {
-                boolean left = (Boolean) operandLeft;
-                boolean right = (Boolean) operandRight;
-                switch (operator) {
-                    case LOGICAL_OR:
-                        return left || right;
-                    case LOGICAL_AND:
-                        return left && right;
-                    case BITWISE_OR:
-                        return left | right;
-                    case BITWISE_XOR:
-                        return left ^ right;
-                    case BITWISE_AND:
-                        return left & right;
-                    case EQUALS:
-                        return left == right;
-                    case NOT_EQUALS:
-                        return left != right;
-                }
-            } else if (operandLeft instanceof Number && operandRight instanceof Number) {
-                Number left = (Number) operandLeft;
-                Number right = (Number) operandRight;
-                boolean isInteger =
-                        !(left instanceof Float || left instanceof Double
-                                || right instanceof Float || right instanceof Double);
-                boolean isWide =
-                        isInteger ? (left instanceof Long || right instanceof Long)
-                                : (left instanceof Double || right instanceof Double);
-
-                switch (operator) {
-                    case BITWISE_OR:
-                        if (isWide) {
-                            return left.longValue() | right.longValue();
-                        } else {
-                            return left.intValue() | right.intValue();
-                        }
-                    case BITWISE_XOR:
-                        if (isWide) {
-                            return left.longValue() ^ right.longValue();
-                        } else {
-                            return left.intValue() ^ right.intValue();
-                        }
-                    case BITWISE_AND:
-                        if (isWide) {
-                            return left.longValue() & right.longValue();
-                        } else {
-                            return left.intValue() & right.intValue();
-                        }
-                    case EQUALS:
-                        if (isInteger) {
-                            return left.longValue() == right.longValue();
-                        } else {
-                            return left.doubleValue() == right.doubleValue();
-                        }
-                    case NOT_EQUALS:
-                        if (isInteger) {
-                            return left.longValue() != right.longValue();
-                        } else {
-                            return left.doubleValue() != right.doubleValue();
-                        }
-                    case GREATER:
-                        if (isInteger) {
-                            return left.longValue() > right.longValue();
-                        } else {
-                            return left.doubleValue() > right.doubleValue();
-                        }
-                    case GREATER_OR_EQUAL:
-                        if (isInteger) {
-                            return left.longValue() >= right.longValue();
-                        } else {
-                            return left.doubleValue() >= right.doubleValue();
-                        }
-                    case LESS:
-                        if (isInteger) {
-                            return left.longValue() < right.longValue();
-                        } else {
-                            return left.doubleValue() < right.doubleValue();
-                        }
-                    case LESS_OR_EQUAL:
-                        if (isInteger) {
-                            return left.longValue() <= right.longValue();
-                        } else {
-                            return left.doubleValue() <= right.doubleValue();
-                        }
-                    case SHIFT_LEFT:
-                        if (isWide) {
-                            return left.longValue() << right.intValue();
-                        } else {
-                            return left.intValue() << right.intValue();
-                        }
-                    case SHIFT_RIGHT:
-                        if (isWide) {
-                            return left.longValue() >> right.intValue();
-                        } else {
-                            return left.intValue() >> right.intValue();
-                        }
-                    case BITWISE_SHIFT_RIGHT:
-                        if (isWide) {
-                            return left.longValue() >>> right.intValue();
-                        } else {
-                            return left.intValue() >>> right.intValue();
-                        }
-                    case PLUS:
-                        if (isInteger) {
-                            if (isWide) {
-                                return left.longValue() + right.longValue();
-                            } else {
-                                return left.intValue() + right.intValue();
-                            }
-                        } else {
-                            if (isWide) {
-                                return left.doubleValue() + right.doubleValue();
-                            } else {
-                                return left.floatValue() + right.floatValue();
-                            }
-                        }
-                    case MINUS:
-                        if (isInteger) {
-                            if (isWide) {
-                                return left.longValue() - right.longValue();
-                            } else {
-                                return left.intValue() - right.intValue();
-                            }
-                        } else {
-                            if (isWide) {
-                                return left.doubleValue() - right.doubleValue();
-                            } else {
-                                return left.floatValue() - right.floatValue();
-                            }
-                        }
-                    case MULTIPLY:
-                        if (isInteger) {
-                            if (isWide) {
-                                return left.longValue() * right.longValue();
-                            } else {
-                                return left.intValue() * right.intValue();
-                            }
-                        } else {
-                            if (isWide) {
-                                return left.doubleValue() * right.doubleValue();
-                            } else {
-                                return left.floatValue() * right.floatValue();
-                            }
-                        }
-                    case DIVIDE:
-                        if (isInteger) {
-                            if (isWide) {
-                                return left.longValue() / right.longValue();
-                            } else {
-                                return left.intValue() / right.intValue();
-                            }
-                        } else {
-                            if (isWide) {
-                                return left.doubleValue() / right.doubleValue();
-                            } else {
-                                return left.floatValue() / right.floatValue();
-                            }
-                        }
-                    case REMAINDER:
-                        if (isInteger) {
-                            if (isWide) {
-                                return left.longValue() % right.longValue();
-                            } else {
-                                return left.intValue() % right.intValue();
-                            }
-                        } else {
-                            if (isWide) {
-                                return left.doubleValue() % right.doubleValue();
-                            } else {
-                                return left.floatValue() % right.floatValue();
-                            }
-                        }
-                    default:
-                        return null;
-                }
-            }
-        } else if (node instanceof Cast) {
-            Cast cast = (Cast)node;
-            Object operandValue = evaluate(cast.astOperand());
-            if (operandValue instanceof Number) {
-                Number number = (Number)operandValue;
-                String typeName = cast.astTypeReference().getTypeName();
-                if (typeName.equals("float")) {
-                    return number.floatValue();
-                } else if (typeName.equals("double")) {
-                    return number.doubleValue();
-                } else if (typeName.equals("int")) {
-                    return number.intValue();
-                } else if (typeName.equals("long")) {
-                    return number.longValue();
-                } else if (typeName.equals("short")) {
-                    return number.shortValue();
-                } else if (typeName.equals("byte")) {
-                    return number.byteValue();
-                }
-            }
-            return operandValue;
-        } else if (mContext != null && (node instanceof VariableReference ||
-                node instanceof Select)) {
-            ResolvedNode resolved = mContext.resolve(node);
-            if (resolved instanceof ResolvedField) {
-                ResolvedField field = (ResolvedField) resolved;
-                Object value = field.getValue();
-                if (value != null) {
-                    return value;
-                }
-                Node astNode = field.findAstNode();
-                if (astNode instanceof VariableDeclaration) {
-                    VariableDeclaration declaration = (VariableDeclaration) astNode;
-                    VariableDefinition definition = declaration.astDefinition();
-                    if (definition != null && definition.astModifiers().isFinal()) {
-                        StrictListAccessor<VariableDefinitionEntry, VariableDefinition> variables =
-                                definition.astVariables();
-                        if (variables.size() == 1) {
-                            VariableDefinitionEntry first = variables.first();
-                            if (first.astInitializer() != null) {
-                                return evaluate(first.astInitializer());
-                            }
-                        }
-                    }
-                }
-                return null;
-            } else if (node instanceof VariableReference) {
-                Statement statement = getParentOfType(node, Statement.class, false);
-                if (statement != null) {
-                    ListIterator<Node> iterator = statement.getParent().getChildren().listIterator();
-                    while (iterator.hasNext()) {
-                        if (iterator.next() == statement) {
-                            if (iterator.hasPrevious()) { // should always be true
-                                iterator.previous();
-                            }
-                            break;
-                        }
-                    }
-
-                    String targetName = ((VariableReference)node).astIdentifier().astValue();
-                    while (iterator.hasPrevious()) {
-                        Node previous = iterator.previous();
-                        if (previous instanceof VariableDeclaration) {
-                            VariableDeclaration declaration = (VariableDeclaration) previous;
-                            VariableDefinition definition = declaration.astDefinition();
-                            for (VariableDefinitionEntry entry : definition
-                                    .astVariables()) {
-                                if (entry.astInitializer() != null
-                                        && entry.astName().astValue().equals(targetName)) {
-                                    return evaluate(entry.astInitializer());
-                                }
-                            }
-                        } else if (previous instanceof ExpressionStatement) {
-                            ExpressionStatement expressionStatement = (ExpressionStatement) previous;
-                            Expression expression = expressionStatement.astExpression();
-                            if (expression instanceof BinaryExpression &&
-                                    ((BinaryExpression) expression).astOperator()
-                                            == BinaryOperator.ASSIGN) {
-                                BinaryExpression binaryExpression = (BinaryExpression) expression;
-                                if (targetName.equals(binaryExpression.astLeft().toString())) {
-                                    return evaluate(binaryExpression.astRight());
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        } else if (node instanceof ArrayCreation) {
-            ArrayCreation creation = (ArrayCreation) node;
-            ArrayInitializer initializer = creation.astInitializer();
-            if (initializer != null) {
-                TypeReference typeReference = creation.astComponentTypeReference();
-                StrictListAccessor<Expression, ArrayInitializer> expressions = initializer
-                        .astExpressions();
-                List<Object> values = Lists.newArrayListWithExpectedSize(expressions.size());
-                Class<?> commonType = null;
-                for (Expression expression : expressions) {
-                    Object value = evaluate(expression);
-                    if (value != null) {
-                        values.add(value);
-                        if (commonType == null) {
-                            commonType = value.getClass();
-                        } else {
-                            while (!commonType.isAssignableFrom(value.getClass())) {
-                                commonType = commonType.getSuperclass();
-                            }
-                        }
-                    } else if (!mAllowUnknown) {
-                        // Inconclusive
-                        return null;
-                    }
-                }
-                if (!values.isEmpty()) {
-                    Object o = Array.newInstance(commonType, values.size());
-                    return values.toArray((Object[]) o);
-                } else if (mContext != null) {
-                    ResolvedNode type = mContext.resolve(typeReference);
-                    System.out.println(type);
-                    // TODO: return new array of this type
-                }
-            } else {
-                // something like "new byte[3]" but with no initializer.
-                String type = creation.astComponentTypeReference().toString();
-                // TODO: Look up the size and only if small, use it. E.g. if it was byte[3]
-                // we could return a byte[3] array, but if it's say byte[1024*1024] we don't
-                // want to do that.
-                int size = 0;
-                if (TYPE_BYTE.equals(type)) {
-                    return new byte[size];
-                }
-                if (TYPE_BOOLEAN.equals(type)) {
-                    return new boolean[size];
-                }
-                if (TYPE_INT.equals(type)) {
-                    return new int[size];
-                }
-                if (TYPE_LONG.equals(type)) {
-                    return new long[size];
-                }
-                if (TYPE_CHAR.equals(type)) {
-                    return new char[size];
-                }
-                if (TYPE_FLOAT.equals(type)) {
-                    return new float[size];
-                }
-                if (TYPE_DOUBLE.equals(type)) {
-                    return new double[size];
-                }
-                if (TYPE_STRING.equals(type)) {
-                    //noinspection SSBasedInspection
-                    return new String[size];
-                }
-                if (TYPE_SHORT.equals(type)) {
-                    return new short[size];
-                }
-                if (TYPE_OBJECT.equals(type)) {
-                    //noinspection SSBasedInspection
-                    return new Object[size];
-                }
-            }
-        }
-
-        // TODO: Check for MethodInvocation and perform some common operations -
-        // Math.* methods, String utility methods like notNullize, etc
-
-        return null;
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any
-     *
-     * @param node the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    @Nullable
-    public Object evaluate(@Nullable UElement node) {
-        if (node == null) {
-            return null;
-        }
-
-        if (node instanceof ULiteralExpression) {
-            return ((ULiteralExpression) node).getValue();
-        } else if (node instanceof UPrefixExpression) {
-            UastPrefixOperator operator = ((UPrefixExpression) node).getOperator();
-            Object operand = evaluate(((UPrefixExpression) node).getOperand());
-            if (operand == null) {
-                return null;
-            }
-            if (operator == UastPrefixOperator.LOGICAL_NOT) {
-                if (operand instanceof Boolean) {
-                    return !(Boolean) operand;
-                }
-            } else if (operator == UastPrefixOperator.UNARY_PLUS) {
-                return operand;
-            } else if (operator == UastPrefixOperator.BITWISE_NOT) {
-                if (operand instanceof Integer) {
-                    return ~(Integer) operand;
-                } else if (operand instanceof Long) {
-                    return ~(Long) operand;
-                } else if (operand instanceof Short) {
-                    return ~(Short) operand;
-                } else if (operand instanceof Character) {
-                    return ~(Character) operand;
-                } else if (operand instanceof Byte) {
-                    return ~(Byte) operand;
-                }
-            } else if (operator == UastPrefixOperator.UNARY_MINUS) {
-                if (operand instanceof Integer) {
-                    return -(Integer) operand;
-                } else if (operand instanceof Long) {
-                    return -(Long) operand;
-                } else if (operand instanceof Double) {
-                    return -(Double) operand;
-                } else if (operand instanceof Float) {
-                    return -(Float) operand;
-                } else if (operand instanceof Short) {
-                    return -(Short) operand;
-                } else if (operand instanceof Character) {
-                    return -(Character) operand;
-                } else if (operand instanceof Byte) {
-                    return -(Byte) operand;
-                }
-            }
-        } else if (node instanceof UIfExpression
-                && ((UIfExpression) node).getExpressionType() != null) {
-            UIfExpression expression = (UIfExpression) node;
-            Object known = evaluate(expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return evaluate(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return evaluate(expression.getElseExpression());
-            }
-        } else if (node instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) node;
-            UExpression expression = parenthesizedExpression.getExpression();
-            return evaluate(expression);
-        } else if (node instanceof UBinaryExpression) {
-            UastBinaryOperator operator = ((UBinaryExpression) node).getOperator();
-            Object operandLeft = evaluate(((UBinaryExpression) node).getLeftOperand());
-            Object operandRight = evaluate(((UBinaryExpression) node).getRightOperand());
-            if (operandLeft == null || operandRight == null) {
-                if (mAllowUnknown) {
-                    if (operandLeft == null) {
-                        return operandRight;
-                    } else {
-                        return operandLeft;
-                    }
-                }
-                return null;
-            }
-            if (operandLeft instanceof String && operandRight instanceof String) {
-                if (operator == UastBinaryOperator.PLUS) {
-                    return operandLeft.toString() + operandRight.toString();
-                }
-                return null;
-            } else if (operandLeft instanceof Boolean && operandRight instanceof Boolean) {
-                boolean left = (Boolean) operandLeft;
-                boolean right = (Boolean) operandRight;
-                if (operator == UastBinaryOperator.LOGICAL_OR) {
-                    return left || right;
-                } else if (operator == UastBinaryOperator.LOGICAL_AND) {
-                    return left && right;
-                } else if (operator == UastBinaryOperator.BITWISE_OR) {
-                    return left | right;
-                } else if (operator == UastBinaryOperator.BITWISE_XOR) {
-                    return left ^ right;
-                } else if (operator == UastBinaryOperator.BITWISE_AND) {
-                    return left & right;
-                } else if (operator == UastBinaryOperator.IDENTITY_EQUALS
-                        || operator == UastBinaryOperator.EQUALS) {
-                    return left == right;
-                } else if (operator == UastBinaryOperator.IDENTITY_NOT_EQUALS
-                        || operator == UastBinaryOperator.NOT_EQUALS) {
-                    return left != right;
-                }
-            } else if (operandLeft instanceof Number && operandRight instanceof Number) {
-                Number left = (Number) operandLeft;
-                Number right = (Number) operandRight;
-                boolean isInteger =
-                        !(left instanceof Float || left instanceof Double
-                                || right instanceof Float || right instanceof Double);
-                boolean isWide =
-                        isInteger ? (left instanceof Long || right instanceof Long)
-                                : (left instanceof Double || right instanceof Double);
-
-                if (operator == UastBinaryOperator.BITWISE_OR) {
-                    if (isWide) {
-                        return left.longValue() | right.longValue();
-                    } else {
-                        return left.intValue() | right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.BITWISE_XOR) {
-                    if (isWide) {
-                        return left.longValue() ^ right.longValue();
-                    } else {
-                        return left.intValue() ^ right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.BITWISE_AND) {
-                    if (isWide) {
-                        return left.longValue() & right.longValue();
-                    } else {
-                        return left.intValue() & right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.EQUALS
-                        || operator == UastBinaryOperator.IDENTITY_EQUALS) {
-                    if (isInteger) {
-                        return left.longValue() == right.longValue();
-                    } else {
-                        return left.doubleValue() == right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.NOT_EQUALS
-                        || operator == UastBinaryOperator.IDENTITY_NOT_EQUALS) {
-                    if (isInteger) {
-                        return left.longValue() != right.longValue();
-                    } else {
-                        return left.doubleValue() != right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.GREATER) {
-                    if (isInteger) {
-                        return left.longValue() > right.longValue();
-                    } else {
-                        return left.doubleValue() > right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.GREATER_OR_EQUALS) {
-                    if (isInteger) {
-                        return left.longValue() >= right.longValue();
-                    } else {
-                        return left.doubleValue() >= right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.LESS) {
-                    if (isInteger) {
-                        return left.longValue() < right.longValue();
-                    } else {
-                        return left.doubleValue() < right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.LESS_OR_EQUALS) {
-                    if (isInteger) {
-                        return left.longValue() <= right.longValue();
-                    } else {
-                        return left.doubleValue() <= right.doubleValue();
-                    }
-                } else if (operator == UastBinaryOperator.SHIFT_LEFT) {
-                    if (isWide) {
-                        return left.longValue() << right.intValue();
-                    } else {
-                        return left.intValue() << right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.SHIFT_RIGHT) {
-                    if (isWide) {
-                        return left.longValue() >> right.intValue();
-                    } else {
-                        return left.intValue() >> right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.UNSIGNED_SHIFT_RIGHT) {
-                    if (isWide) {
-                        return left.longValue() >>> right.intValue();
-                    } else {
-                        return left.intValue() >>> right.intValue();
-                    }
-                } else if (operator == UastBinaryOperator.PLUS) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() + right.longValue();
-                        } else {
-                            return left.intValue() + right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() + right.doubleValue();
-                        } else {
-                            return left.floatValue() + right.floatValue();
-                        }
-                    }
-                } else if (operator == UastBinaryOperator.MINUS) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() - right.longValue();
-                        } else {
-                            return left.intValue() - right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() - right.doubleValue();
-                        } else {
-                            return left.floatValue() - right.floatValue();
-                        }
-                    }
-                } else if (operator == UastBinaryOperator.MULTIPLY) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() * right.longValue();
-                        } else {
-                            return left.intValue() * right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() * right.doubleValue();
-                        } else {
-                            return left.floatValue() * right.floatValue();
-                        }
-                    }
-                } else if (operator == UastBinaryOperator.DIV) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() / right.longValue();
-                        } else {
-                            return left.intValue() / right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() / right.doubleValue();
-                        } else {
-                            return left.floatValue() / right.floatValue();
-                        }
-                    }
-                } else if (operator == UastBinaryOperator.MOD) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() % right.longValue();
-                        } else {
-                            return left.intValue() % right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() % right.doubleValue();
-                        } else {
-                            return left.floatValue() % right.floatValue();
-                        }
-                    }
-                } else {
-                    return null;
-                }
-            }
-        } else if (node instanceof UBinaryExpressionWithType &&
-                ((UBinaryExpressionWithType) node).getOperationKind() == TYPE_CAST) {
-            UBinaryExpressionWithType cast = (UBinaryExpressionWithType) node;
-            Object operandValue = evaluate(cast.getOperand());
-            if (operandValue instanceof Number) {
-                Number number = (Number) operandValue;
-                PsiType type = cast.getType();
-                if (PsiType.FLOAT.equals(type)) {
-                    return number.floatValue();
-                } else if (PsiType.DOUBLE.equals(type)) {
-                    return number.doubleValue();
-                } else if (PsiType.INT.equals(type)) {
-                    return number.intValue();
-                } else if (PsiType.LONG.equals(type)) {
-                    return number.longValue();
-                } else if (PsiType.SHORT.equals(type)) {
-                    return number.shortValue();
-                } else if (PsiType.BYTE.equals(type)) {
-                    return number.byteValue();
-                }
-            }
-            return operandValue;
-        } else if (node instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) node).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                Object value = UastLintUtils.findLastValue(variable, node, mContext, this);
-
-                if (value != null) {
-                    return value;
-                }
-                if (variable.getInitializer() != null) {
-                    return evaluate(variable.getInitializer());
-                }
-                return null;
-            }
-        } else if (UastExpressionUtils.isNewArrayWithDimensions((UExpression) node)) {
-            UCallExpression call = (UCallExpression) node;
-            PsiType arrayType = call.getExpressionType();
-            if (arrayType instanceof PsiArrayType) {
-                PsiType componentType = ((PsiArrayType) arrayType).getComponentType();
-                // Single-dimension array
-                if (!(componentType instanceof PsiArrayType)
-                        && call.getValueArgumentCount() == 1) {
-                    Object lengthObj = evaluate(call.getValueArguments().get(0));
-                    if (lengthObj instanceof Number) {
-                        int length = ((Number) lengthObj).intValue();
-                        if (length > 30) {
-                            length = 30;
-                        }
-                        if (componentType == PsiType.BOOLEAN) {
-                            return new boolean[length];
-                        } else if (isObjectType(componentType)) {
-                            return new Object[length];
-                        } else if (componentType == PsiType.CHAR) {
-                            return new char[length];
-                        } else if (componentType == PsiType.BYTE) {
-                            return new byte[length];
-                        } else if (componentType == PsiType.DOUBLE) {
-                            return new double[length];
-                        } else if (componentType == PsiType.FLOAT) {
-                            return new float[length];
-                        } else if (componentType == PsiType.INT) {
-                            return new int[length];
-                        } else if (componentType == PsiType.SHORT) {
-                            return new short[length];
-                        } else if (componentType == PsiType.LONG) {
-                            return new long[length];
-                        } else if (isStringType(componentType)) {
-                            return new String[length];
-                        }
-                    }
-                }
-            }
-        } else if (UastExpressionUtils.isNewArrayWithInitializer(node)) {
-            UCallExpression call = (UCallExpression) node;
-            PsiType arrayType = call.getExpressionType();
-            if (arrayType instanceof PsiArrayType) {
-                PsiType componentType = ((PsiArrayType) arrayType).getComponentType();
-                // Single-dimension array
-                if (!(componentType instanceof PsiArrayType)) {
-                    int length = call.getValueArgumentCount();
-                    List<Object> evaluatedArgs = new ArrayList<Object>(length);
-                    for (UExpression arg : call.getValueArguments()) {
-                        Object evaluatedArg = evaluate(arg);
-                        if (!mAllowUnknown && evaluatedArg == null) {
-                            // Inconclusive
-                            return null;
-                        }
-                        evaluatedArgs.add(evaluatedArg);
-                    }
-
-                    if (componentType == PsiType.BOOLEAN) {
-                        boolean[] arr = new boolean[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Boolean) {
-                                arr[i] = (Boolean) o;
-                            }
-                        }
-                        return arr;
-                    } else if (isObjectType(componentType)) {
-                        Object[] arr = new Object[length];
-                        for (int i = 0; i < length; ++i) {
-                            arr[i] = evaluatedArgs.get(i);
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.CHAR)) {
-                        char[] arr = new char[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Character) {
-                                arr[i] = (Character) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.BYTE)) {
-                        byte[] arr = new byte[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Byte) {
-                                arr[i] = (Byte) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.DOUBLE)) {
-                        double[] arr = new double[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Double) {
-                                arr[i] = (Double) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.FLOAT)) {
-                        float[] arr = new float[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Float) {
-                                arr[i] = (Float) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.INT)) {
-                        int[] arr = new int[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Integer) {
-                                arr[i] = (Integer) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.SHORT)) {
-                        short[] arr = new short[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Short) {
-                                arr[i] = (Short) o;
-                            }
-                        }
-                        return arr;
-                    } else if (componentType.equals(PsiType.LONG)) {
-                        long[] arr = new long[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof Long) {
-                                arr[i] = (Long) o;
-                            }
-                        }
-                        return arr;
-                    } else if (isStringType(componentType)) {
-                        String[] arr = new String[length];
-                        for (int i = 0; i < length; ++i) {
-                            Object o = evaluatedArgs.get(i);
-                            if (o instanceof String) {
-                                arr[i] = (String) o;
-                            }
-                        }
-                        return arr;
-                    }
-                }
-            }
-        }
-
-        if (node instanceof UExpression) {
-            Object evaluated = ((UExpression) node).evaluate();
-            if (evaluated != null) {
-                return evaluated;
-            }
-        }
-
-        // TODO: Check for MethodInvocation and perform some common operations -
-        // Math.* methods, String utility methods like notNullize, etc
-
-        return null;
-    }
-    
-    private static boolean isStringType(PsiType type) {
-        if (!(type instanceof PsiClassType)) {
-            return false;
-        }
-        
-        PsiClass resolvedClass = ((PsiClassType) type).resolve();
-        return resolvedClass != null && TYPE_STRING.equals(resolvedClass.getQualifiedName());
-    }
-
-    private static boolean isObjectType(PsiType type) {
-        if (!(type instanceof PsiClassType)) {
-            return false;
-        }
-
-        PsiClass resolvedClass = ((PsiClassType) type).resolve();
-        return resolvedClass != null && TYPE_OBJECT.equals(resolvedClass.getQualifiedName());
-    }
-
-    public static class LastAssignmentFinder extends AbstractUastVisitor {
-        private final PsiVariable mVariable;
-        private final UElement mEndAt;
-
-        private final ConstantEvaluator mConstantEvaluator;
-
-        private boolean mDone = false;
-        private int mCurrentLevel = 0;
-        private int mVariableLevel = -1;
-        private Object mCurrentValue;
-        private UElement mLastAssignment;
-
-        public LastAssignmentFinder(
-                @NonNull PsiVariable variable,
-                @NonNull UElement endAt,
-                @NonNull JavaContext context,
-                @Nullable ConstantEvaluator constantEvaluator,
-                int variableLevel) {
-            mVariable = variable;
-            mEndAt = endAt;
-            UExpression initializer = context.getUastContext().getInitializerBody(variable);
-            mLastAssignment = initializer;
-            mConstantEvaluator = constantEvaluator;
-            if (initializer != null && constantEvaluator != null) {
-                mCurrentValue = constantEvaluator.evaluate(initializer);
-            }
-            this.mVariableLevel = variableLevel;
-        }
-
-        @Nullable
-        public Object getCurrentValue() {
-            return mCurrentValue;
-        }
-
-        @Nullable
-        public UElement getLastAssignment() {
-            return mLastAssignment;
-        }
-
-        @Override
-        public boolean visitElement(UElement node) {
-            if (elementHasLevel(node)) {
-                mCurrentLevel++;
-            }
-            if (node.equals(mEndAt)) {
-                mDone = true;
-            }
-            return mDone || super.visitElement(node);
-        }
-
-        @Override
-        public boolean visitVariable(UVariable node) {
-            if (mVariableLevel < 0 && node.getPsi().isEquivalentTo(mVariable)) {
-                mVariableLevel = mCurrentLevel;
-            }
-
-            return super.visitVariable(node);
-        }
-
-        @Override
-        public void afterVisitBinaryExpression(UBinaryExpression node) {
-            if (!mDone
-                && node.getOperator() instanceof UastBinaryOperator.AssignOperator
-                && mVariableLevel >= 0) {
-                UExpression leftOperand = node.getLeftOperand();
-                UastBinaryOperator operator = node.getOperator();
-
-                if (!(operator instanceof UastBinaryOperator.AssignOperator)
-                    || !(leftOperand instanceof UResolvable)) {
-                    return;
-                }
-
-                PsiElement resolved = ((UResolvable) leftOperand).resolve();
-                if (!mVariable.equals(resolved)) {
-                    return;
-                }
-
-                // Last assignment is unknown if we see an assignment inside
-                // some conditional or loop statement.
-                if (mCurrentLevel > mVariableLevel + 1) {
-                    mLastAssignment = null;
-                    mCurrentValue = null;
-                    return;
-                }
-
-                UExpression rightOperand = node.getRightOperand();
-                ConstantEvaluator constantEvaluator = mConstantEvaluator;
-
-                mCurrentValue = (constantEvaluator != null)
-                                ? constantEvaluator.evaluate(rightOperand)
-                                : null;
-                mLastAssignment = rightOperand;
-            }
-
-            super.afterVisitBinaryExpression(node);
-        }
-
-        @Override
-        public void afterVisitElement(UElement node) {
-            if (elementHasLevel(node)) {
-                mCurrentLevel--;
-            }
-            super.afterVisitElement(node);
-        }
-
-        private static boolean elementHasLevel(UElement node) {
-            return !(node instanceof UBlockExpression
-                     || node instanceof UDeclarationsExpression);
-        }
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any
-     *
-     * @param node the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    @Nullable
-    public Object evaluate(@Nullable PsiElement node) {
-        if (node == null) {
-            return null;
-        }
-        if (node instanceof PsiLiteral) {
-            return ((PsiLiteral)node).getValue();
-        } else if (node instanceof PsiPrefixExpression) {
-            IElementType operator = ((PsiPrefixExpression) node).getOperationTokenType();
-            Object operand = evaluate(((PsiPrefixExpression) node).getOperand());
-            if (operand == null) {
-                return null;
-            }
-            if (operator == JavaTokenType.EXCL) {
-                if (operand instanceof Boolean) {
-                    return !(Boolean) operand;
-                }
-            } else if (operator == JavaTokenType.PLUS) {
-                return operand;
-            } else if (operator == JavaTokenType.TILDE) {
-                if (operand instanceof Integer) {
-                    return ~(Integer) operand;
-                } else if (operand instanceof Long) {
-                    return ~(Long) operand;
-                } else if (operand instanceof Short) {
-                    return ~(Short) operand;
-                } else if (operand instanceof Character) {
-                    return ~(Character) operand;
-                } else if (operand instanceof Byte) {
-                    return ~(Byte) operand;
-                }
-            } else if (operator == JavaTokenType.MINUS) {
-                if (operand instanceof Integer) {
-                    return -(Integer) operand;
-                } else if (operand instanceof Long) {
-                    return -(Long) operand;
-                } else if (operand instanceof Double) {
-                    return -(Double) operand;
-                } else if (operand instanceof Float) {
-                    return -(Float) operand;
-                } else if (operand instanceof Short) {
-                    return -(Short) operand;
-                } else if (operand instanceof Character) {
-                    return -(Character) operand;
-                } else if (operand instanceof Byte) {
-                    return -(Byte) operand;
-                }
-            }
-        } else if (node instanceof PsiConditionalExpression) {
-            PsiConditionalExpression expression = (PsiConditionalExpression) node;
-            Object known = evaluate(expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return evaluate(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return evaluate(expression.getElseExpression());
-            }
-        } else if (node instanceof PsiParenthesizedExpression) {
-            PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) node;
-            PsiExpression expression = parenthesizedExpression.getExpression();
-            if (expression != null) {
-                return evaluate(expression);
-            }
-        } else if (node instanceof PsiBinaryExpression) {
-            IElementType operator = ((PsiBinaryExpression) node).getOperationTokenType();
-            Object operandLeft = evaluate(((PsiBinaryExpression) node).getLOperand());
-            Object operandRight = evaluate(((PsiBinaryExpression) node).getROperand());
-            if (operandLeft == null || operandRight == null) {
-                if (mAllowUnknown) {
-                    if (operandLeft == null) {
-                        return operandRight;
-                    } else {
-                        return operandLeft;
-                    }
-                }
-                return null;
-            }
-            if (operandLeft instanceof String && operandRight instanceof String) {
-                if (operator == JavaTokenType.PLUS) {
-                    return operandLeft.toString() + operandRight.toString();
-                }
-                return null;
-            } else if (operandLeft instanceof Boolean && operandRight instanceof Boolean) {
-                boolean left = (Boolean) operandLeft;
-                boolean right = (Boolean) operandRight;
-                if (operator == JavaTokenType.OROR) {
-                    return left || right;
-                } else if (operator == JavaTokenType.ANDAND) {
-                    return left && right;
-                } else if (operator == JavaTokenType.OR) {
-                    return left | right;
-                } else if (operator == JavaTokenType.XOR) {
-                    return left ^ right;
-                } else if (operator == JavaTokenType.AND) {
-                    return left & right;
-                } else if (operator == JavaTokenType.EQEQ) {
-                    return left == right;
-                } else if (operator == JavaTokenType.NE) {
-                    return left != right;
-                }
-            } else if (operandLeft instanceof Number && operandRight instanceof Number) {
-                Number left = (Number) operandLeft;
-                Number right = (Number) operandRight;
-                boolean isInteger =
-                        !(left instanceof Float || left instanceof Double
-                                || right instanceof Float || right instanceof Double);
-                boolean isWide =
-                        isInteger ? (left instanceof Long || right instanceof Long)
-                                : (left instanceof Double || right instanceof Double);
-
-                if (operator == JavaTokenType.OR) {
-                    if (isWide) {
-                        return left.longValue() | right.longValue();
-                    } else {
-                        return left.intValue() | right.intValue();
-                    }
-                } else if (operator == JavaTokenType.XOR) {
-                    if (isWide) {
-                        return left.longValue() ^ right.longValue();
-                    } else {
-                        return left.intValue() ^ right.intValue();
-                    }
-                } else if (operator == JavaTokenType.AND) {
-                    if (isWide) {
-                        return left.longValue() & right.longValue();
-                    } else {
-                        return left.intValue() & right.intValue();
-                    }
-                } else if (operator == JavaTokenType.EQEQ) {
-                    if (isInteger) {
-                        return left.longValue() == right.longValue();
-                    } else {
-                        return left.doubleValue() == right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.NE) {
-                    if (isInteger) {
-                        return left.longValue() != right.longValue();
-                    } else {
-                        return left.doubleValue() != right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.GT) {
-                    if (isInteger) {
-                        return left.longValue() > right.longValue();
-                    } else {
-                        return left.doubleValue() > right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.GE) {
-                    if (isInteger) {
-                        return left.longValue() >= right.longValue();
-                    } else {
-                        return left.doubleValue() >= right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.LT) {
-                    if (isInteger) {
-                        return left.longValue() < right.longValue();
-                    } else {
-                        return left.doubleValue() < right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.LE) {
-                    if (isInteger) {
-                        return left.longValue() <= right.longValue();
-                    } else {
-                        return left.doubleValue() <= right.doubleValue();
-                    }
-                } else if (operator == JavaTokenType.LTLT) {
-                    if (isWide) {
-                        return left.longValue() << right.intValue();
-                    } else {
-                        return left.intValue() << right.intValue();
-                    }
-                } else if (operator == JavaTokenType.GTGT) {
-                    if (isWide) {
-                        return left.longValue() >> right.intValue();
-                    } else {
-                        return left.intValue() >> right.intValue();
-                    }
-                } else if (operator == JavaTokenType.GTGTGT) {
-                    if (isWide) {
-                        return left.longValue() >>> right.intValue();
-                    } else {
-                        return left.intValue() >>> right.intValue();
-                    }
-                } else if (operator == JavaTokenType.PLUS) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() + right.longValue();
-                        } else {
-                            return left.intValue() + right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() + right.doubleValue();
-                        } else {
-                            return left.floatValue() + right.floatValue();
-                        }
-                    }
-                } else if (operator == JavaTokenType.MINUS) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() - right.longValue();
-                        } else {
-                            return left.intValue() - right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() - right.doubleValue();
-                        } else {
-                            return left.floatValue() - right.floatValue();
-                        }
-                    }
-                } else if (operator == JavaTokenType.ASTERISK) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() * right.longValue();
-                        } else {
-                            return left.intValue() * right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() * right.doubleValue();
-                        } else {
-                            return left.floatValue() * right.floatValue();
-                        }
-                    }
-                } else if (operator == JavaTokenType.DIV) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() / right.longValue();
-                        } else {
-                            return left.intValue() / right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() / right.doubleValue();
-                        } else {
-                            return left.floatValue() / right.floatValue();
-                        }
-                    }
-                } else if (operator == JavaTokenType.PERC) {
-                    if (isInteger) {
-                        if (isWide) {
-                            return left.longValue() % right.longValue();
-                        } else {
-                            return left.intValue() % right.intValue();
-                        }
-                    } else {
-                        if (isWide) {
-                            return left.doubleValue() % right.doubleValue();
-                        } else {
-                            return left.floatValue() % right.floatValue();
-                        }
-                    }
-                } else {
-                    return null;
-                }
-            }
-        } else if (node instanceof PsiTypeCastExpression) {
-            PsiTypeCastExpression cast = (PsiTypeCastExpression) node;
-            Object operandValue = evaluate(cast.getOperand());
-            if (operandValue instanceof Number) {
-                Number number = (Number) operandValue;
-                PsiTypeElement typeElement = cast.getCastType();
-                if (typeElement != null) {
-                    PsiType type = typeElement.getType();
-                    if (PsiType.FLOAT.equals(type)) {
-                        return number.floatValue();
-                    } else if (PsiType.DOUBLE.equals(type)) {
-                        return number.doubleValue();
-                    } else if (PsiType.INT.equals(type)) {
-                        return number.intValue();
-                    } else if (PsiType.LONG.equals(type)) {
-                        return number.longValue();
-                    } else if (PsiType.SHORT.equals(type)) {
-                        return number.shortValue();
-                    } else if (PsiType.BYTE.equals(type)) {
-                        return number.byteValue();
-                    }
-                }
-            }
-            return operandValue;
-        } else if (node instanceof PsiReference) {
-            PsiElement resolved = ((PsiReference) node).resolve();
-            if (resolved instanceof PsiField) {
-                PsiField field = (PsiField) resolved;
-                Object value = field.computeConstantValue();
-                if (value != null) {
-                    return value;
-                }
-                if (field.getInitializer() != null) {
-                    return evaluate(field.getInitializer());
-                }
-                return null;
-            } else if (resolved instanceof PsiLocalVariable) {
-                PsiLocalVariable variable = (PsiLocalVariable) resolved;
-                PsiStatement statement = PsiTreeUtil.getParentOfType(node, PsiStatement.class,
-                        false);
-                if (statement != null) {
-                    PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement,
-                            PsiStatement.class);
-                    String targetName = variable.getName();
-                    if (targetName == null) {
-                        return null;
-                    }
-                    while (prev != null) {
-                        if (prev instanceof PsiDeclarationStatement) {
-                            for (PsiElement element : ((PsiDeclarationStatement) prev)
-                                    .getDeclaredElements()) {
-                                if (variable.equals(element)) {
-                                    return evaluate(variable.getInitializer());
-                                }
-                            }
-                        } else if (prev instanceof PsiExpressionStatement) {
-                            PsiExpression expression = ((PsiExpressionStatement) prev)
-                                    .getExpression();
-                            if (expression instanceof PsiAssignmentExpression) {
-                                PsiAssignmentExpression assign
-                                        = (PsiAssignmentExpression) expression;
-                                PsiExpression lhs = assign.getLExpression();
-                                if (lhs instanceof PsiReferenceExpression) {
-                                    PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
-                                    if (targetName.equals(reference.getReferenceName()) &&
-                                            reference.getQualifier() == null) {
-                                        return evaluate(assign.getRExpression());
-                                    }
-                                }
-                            }
-                        }
-                        prev = PsiTreeUtil.getPrevSiblingOfType(prev,
-                                PsiStatement.class);
-                    }
-                }
-            }
-        } else if (node instanceof PsiNewExpression) {
-            PsiNewExpression creation = (PsiNewExpression) node;
-            PsiArrayInitializerExpression initializer = creation.getArrayInitializer();
-            PsiType type = creation.getType();
-            if (type instanceof PsiArrayType) {
-                if (initializer != null) {
-                    PsiExpression[] initializers = initializer.getInitializers();
-                    Class<?> commonType = null;
-                    List<Object> values = Lists.newArrayListWithExpectedSize(initializers.length);
-                    int count = 0;
-                    for (PsiExpression expression : initializers) {
-                        Object value = evaluate(expression);
-                        if (value != null) {
-                            values.add(value);
-                            if (commonType == null) {
-                                commonType = value.getClass();
-                            } else {
-                                while (!commonType.isAssignableFrom(value.getClass())) {
-                                    commonType = commonType.getSuperclass();
-                                }
-                            }
-                        } else if (!mAllowUnknown) {
-                            // Inconclusive
-                            return null;
-                        }
-                        count++;
-                        if (count == 20) { // avoid large initializers
-                            break;
-                        }
-                    }
-                    type = type.getDeepComponentType();
-                    if (type == PsiType.INT) {
-                        if (!values.isEmpty()) {
-                            int[] array = new int[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Integer) {
-                                    array[i] = (Integer) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new int[0];
-                    } else if (type == PsiType.BOOLEAN) {
-                        if (!values.isEmpty()) {
-                            boolean[] array = new boolean[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Boolean) {
-                                    array[i] = (Boolean) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new boolean[0];
-                    } else if (type == PsiType.DOUBLE) {
-                        if (!values.isEmpty()) {
-                            double[] array = new double[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Double) {
-                                    array[i] = (Double) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new double[0];
-                    } else if (type == PsiType.LONG) {
-                        if (!values.isEmpty()) {
-                            long[] array = new long[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Long) {
-                                    array[i] = (Long) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new long[0];
-                    } else if (type == PsiType.FLOAT) {
-                        if (!values.isEmpty()) {
-                            float[] array = new float[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Float) {
-                                    array[i] = (Float) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new float[0];
-                    } else if (type == PsiType.CHAR) {
-                        if (!values.isEmpty()) {
-                            char[] array = new char[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Character) {
-                                    array[i] = (Character) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new char[0];
-                    } else if (type == PsiType.BYTE) {
-                        if (!values.isEmpty()) {
-                            byte[] array = new byte[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Byte) {
-                                    array[i] = (Byte) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new byte[0];
-                    } else if (type == PsiType.SHORT) {
-                        if (!values.isEmpty()) {
-                            short[] array = new short[values.size()];
-                            for (int i = 0; i < values.size(); i++) {
-                                Object o = values.get(i);
-                                if (o instanceof Short) {
-                                    array[i] = (Short) o;
-                                }
-                            }
-                            return array;
-                        }
-                        return new short[0];
-                    } else {
-                        if (!values.isEmpty()) {
-                            Object o = Array.newInstance(commonType, values.size());
-                            return values.toArray((Object[]) o);
-                        }
-                        return null;
-                    }
-                } else {
-                    // something like "new byte[3]" but with no initializer.
-                    // Look up the size and only if small, use it. E.g. if it was byte[3]
-                    // we return a byte[3] array, but if it's say byte[1024*1024] we don't
-                    // want to do that.
-                    PsiExpression[] arrayDimensions = creation.getArrayDimensions();
-                    int size = 0;
-                    if (arrayDimensions.length == 1) {
-                        Object fixedSize = evaluate(arrayDimensions[0]);
-                        if (fixedSize instanceof Number) {
-                            size = ((Number)fixedSize).intValue();
-                            if (size > 30) {
-                                size = 30;
-                            }
-                        }
-                    }
-                    type = type.getDeepComponentType();
-                    if (type instanceof PsiPrimitiveType) {
-                        if (PsiType.BYTE.equals(type)) {
-                            return new byte[size];
-                        }
-                        if (PsiType.BOOLEAN.equals(type)) {
-                            return new boolean[size];
-                        }
-                        if (PsiType.INT.equals(type)) {
-                            return new int[size];
-                        }
-                        if (PsiType.LONG.equals(type)) {
-                            return new long[size];
-                        }
-                        if (PsiType.CHAR.equals(type)) {
-                            return new char[size];
-                        }
-                        if (PsiType.FLOAT.equals(type)) {
-                            return new float[size];
-                        }
-                        if (PsiType.DOUBLE.equals(type)) {
-                            return new double[size];
-                        }
-                        if (PsiType.SHORT.equals(type)) {
-                            return new short[size];
-                        }
-                    } else if (type instanceof PsiClassType) {
-                        String className = type.getCanonicalText();
-                        if (TYPE_STRING.equals(className)) {
-                            //noinspection SSBasedInspection
-                            return new String[size];
-                        }
-                        if (TYPE_OBJECT.equals(className)) {
-                            //noinspection SSBasedInspection
-                            return new Object[size];
-                        }
-                    }
-                }
-            }
-        }
-
-        // TODO: Check for MethodInvocation and perform some common operations -
-        // Math.* methods, String utility methods like notNullize, etc
-
-        return null;
-    }
-
-    /**
-     * Returns true if the node is pointing to a an array literal
-     */
-    public static boolean isArrayLiteral(@Nullable UElement node, @NonNull JavaContext context) {
-        if (node instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) node).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                UExpression lastAssignment =
-                        UastLintUtils.findLastAssignment(variable, node, context);
-
-                if (lastAssignment != null) {
-                    return isArrayLiteral(lastAssignment, context);
-                }
-            }
-        } else if (UastExpressionUtils.isNewArrayWithDimensions(node)) {
-            return true;
-        } else if (UastExpressionUtils.isNewArrayWithInitializer(node)) {
-            return true;
-        } else if (node instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) node;
-            UExpression expression = parenthesizedExpression.getExpression();
-            return isArrayLiteral(expression, context);
-        } else if (UastExpressionUtils.isTypeCast(node)) {
-            UBinaryExpressionWithType castExpression = (UBinaryExpressionWithType) node;
-            assert castExpression != null;
-            UExpression operand = castExpression.getOperand();
-            return isArrayLiteral(operand, context);
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the node is pointing to a an array literal
-     */
-    public static boolean isArrayLiteral(@Nullable PsiElement node) {
-        if (node instanceof PsiReference) {
-            PsiElement resolved = ((PsiReference) node).resolve();
-            if (resolved instanceof PsiField) {
-                PsiField field = (PsiField) resolved;
-                if (field.getInitializer() != null) {
-                    return isArrayLiteral(field.getInitializer());
-                }
-            } else if (resolved instanceof PsiLocalVariable) {
-                PsiLocalVariable variable = (PsiLocalVariable) resolved;
-                PsiStatement statement = PsiTreeUtil.getParentOfType(node, PsiStatement.class,
-                        false);
-                if (statement != null) {
-                    PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement,
-                            PsiStatement.class);
-                    String targetName = variable.getName();
-                    if (targetName == null) {
-                        return false;
-                    }
-                    while (prev != null) {
-                        if (prev instanceof PsiDeclarationStatement) {
-                            for (PsiElement element : ((PsiDeclarationStatement) prev)
-                                    .getDeclaredElements()) {
-                                if (variable.equals(element)) {
-                                    return isArrayLiteral(variable.getInitializer());
-                                }
-                            }
-                        } else if (prev instanceof PsiExpressionStatement) {
-                            PsiExpression expression = ((PsiExpressionStatement) prev)
-                                    .getExpression();
-                            if (expression instanceof PsiAssignmentExpression) {
-                                PsiAssignmentExpression assign
-                                        = (PsiAssignmentExpression) expression;
-                                PsiExpression lhs = assign.getLExpression();
-                                if (lhs instanceof PsiReferenceExpression) {
-                                    PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
-                                    if (targetName.equals(reference.getReferenceName()) &&
-                                            reference.getQualifier() == null) {
-                                        return isArrayLiteral(assign.getRExpression());
-                                    }
-                                }
-                            }
-                        }
-                        prev = PsiTreeUtil.getPrevSiblingOfType(prev,
-                                PsiStatement.class);
-                    }
-                }
-            }
-        } else if (node instanceof PsiNewExpression) {
-            PsiNewExpression creation = (PsiNewExpression) node;
-            if (creation.getArrayInitializer() != null) {
-                return true;
-            }
-            PsiType type = creation.getType();
-            if (type instanceof PsiArrayType) {
-                return true;
-            }
-        } else if (node instanceof PsiParenthesizedExpression) {
-            PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) node;
-            PsiExpression expression = parenthesizedExpression.getExpression();
-            if (expression != null) {
-                return isArrayLiteral(expression);
-            }
-        } else if (node instanceof PsiTypeCastExpression) {
-            PsiTypeCastExpression castExpression = (PsiTypeCastExpression) node;
-            PsiExpression operand = castExpression.getOperand();
-            if (operand != null) {
-                return isArrayLiteral(operand);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result.
-     *
-     * @param context the context to use to resolve field references, if any
-     * @param node    the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     * @deprecated Use {@link #evaluate(JavaContext, PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static Object evaluate(@NonNull JavaContext context, @NonNull Node node) {
-        return new ConstantEvaluator(context).evaluate(node);
-    }
-
-    /**
-     * Evaluates the given node and returns the constant string it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result if the result is a string.
-     *
-     * @param context      the context to use to resolve field references, if any
-     * @param node         the node to compute the constant value for
-     * @param allowUnknown whether we should construct the string even if some parts of it are
-     *                     unknown
-     * @return the corresponding string, if any
-     * @deprecated Use {@link #evaluateString(JavaContext, PsiElement, boolean)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static String evaluateString(@NonNull JavaContext context, @NonNull Node node,
-            boolean allowUnknown) {
-        ConstantEvaluator evaluator = new ConstantEvaluator(context);
-        if (allowUnknown) {
-            evaluator.allowUnknowns();
-        }
-        Object value = evaluator.evaluate(node);
-        return value instanceof String ? (String) value : null;
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result.
-     *
-     * @param context the context to use to resolve field references, if any
-     * @param node    the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    @Nullable
-    public static Object evaluate(@Nullable JavaContext context, @NonNull PsiElement node) {
-        return new ConstantEvaluator(context).evaluate(node);
-    }
-
-    /**
-     * Evaluates the given node and returns the constant value it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result.
-     *
-     * @param context the context to use to resolve field references, if any
-     * @param node    the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    @Nullable
-    public static Object evaluate(@Nullable JavaContext context, @NonNull UElement node) {
-        return new ConstantEvaluator(context).evaluate(node);
-    }
-
-    /**
-     * Evaluates the given node and returns the constant string it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result if the result is a string.
-     *
-     * @param context      the context to use to resolve field references, if any
-     * @param node         the node to compute the constant value for
-     * @param allowUnknown whether we should construct the string even if some parts of it are
-     *                     unknown
-     * @return the corresponding string, if any
-     */
-    @Nullable
-    public static String evaluateString(@Nullable JavaContext context, @NonNull PsiElement node,
-            boolean allowUnknown) {
-        ConstantEvaluator evaluator = new ConstantEvaluator(context);
-        if (allowUnknown) {
-            evaluator.allowUnknowns();
-        }
-        Object value = evaluator.evaluate(node);
-        return value instanceof String ? (String) value : null;
-    }
-
-    /**
-     * Evaluates the given node and returns the constant string it resolves to, if any. Convenience
-     * wrapper which creates a new {@linkplain ConstantEvaluator}, evaluates the node and returns
-     * the result if the result is a string.
-     *
-     * @param context      the context to use to resolve field references, if any
-     * @param node         the node to compute the constant value for
-     * @param allowUnknown whether we should construct the string even if some parts of it are
-     *                     unknown
-     * @return the corresponding string, if any
-     */
-    @Nullable
-    public static String evaluateString(@Nullable JavaContext context, @NonNull UElement node,
-            boolean allowUnknown) {
-        ConstantEvaluator evaluator = new ConstantEvaluator(context);
-        if (allowUnknown) {
-            evaluator.allowUnknowns();
-        }
-        Object value = evaluator.evaluate(node);
-        return value instanceof String ? (String) value : null;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Context.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Context.java
deleted file mode 100644
index 9d87fae..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Context.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.SdkConstants.DOT_GRADLE;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.SUPPRESS_ALL;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.Configuration;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.SdkInfo;
-import com.google.common.annotations.Beta;
-
-import java.io.File;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Context passed to the detectors during an analysis run. It provides
- * information about the file being analyzed, it allows shared properties (so
- * the detectors can share results), etc.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class Context {
-    /**
-     * The file being checked. Note that this may not always be to a concrete
-     * file. For example, in the {@link Detector#beforeCheckProject(Context)}
-     * method, the context file is the directory of the project.
-     */
-    public final File file;
-
-    /** The driver running through the checks */
-    protected final LintDriver mDriver;
-
-    /** The project containing the file being checked */
-    @NonNull
-    private final Project mProject;
-
-    /**
-     * The "main" project. For normal projects, this is the same as {@link #mProject},
-     * but for library projects, it's the root project that includes (possibly indirectly)
-     * the various library projects and their library projects.
-     * <p>
-     * Note that this is a property on the {@link Context}, not the
-     * {@link Project}, since a library project can be included from multiple
-     * different top level projects, so there isn't <b>one</b> main project,
-     * just one per main project being analyzed with its library projects.
-     */
-    private final Project mMainProject;
-
-    /** The current configuration controlling which checks are enabled etc */
-    private final Configuration mConfiguration;
-
-    /** The contents of the file */
-    private String mContents;
-
-    /** Map of properties to share results between detectors */
-    private Map<String, Object> mProperties;
-
-    /** Whether this file contains any suppress markers (null means not yet determined) */
-    private Boolean mContainsCommentSuppress;
-
-    /**
-     * Construct a new {@link Context}
-     *
-     * @param driver the driver running through the checks
-     * @param project the project containing the file being checked
-     * @param main the main project if this project is a library project, or
-     *            null if this is not a library project. The main project is
-     *            the root project of all library projects, not necessarily the
-     *            directly including project.
-     * @param file the file being checked
-     */
-    public Context(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File file) {
-        this.file = file;
-
-        mDriver = driver;
-        mProject = project;
-        mMainProject = main;
-        mConfiguration = project.getConfiguration(driver);
-    }
-
-    /**
-     * Returns the scope for the lint job
-     *
-     * @return the scope, never null
-     */
-    @NonNull
-    public EnumSet<Scope> getScope() {
-        return mDriver.getScope();
-    }
-
-    /**
-     * Returns the configuration for this project.
-     *
-     * @return the configuration, never null
-     */
-    @NonNull
-    public Configuration getConfiguration() {
-        return mConfiguration;
-    }
-
-    /**
-     * Returns the project containing the file being checked
-     *
-     * @return the project, never null
-     */
-    @NonNull
-    public Project getProject() {
-        return mProject;
-    }
-
-    /**
-     * Returns the main project if this project is a library project, or self
-     * if this is not a library project. The main project is the root project
-     * of all library projects, not necessarily the directly including project.
-     *
-     * @return the main project, never null
-     */
-    @NonNull
-    public Project getMainProject() {
-        return mMainProject != null ? mMainProject : mProject;
-    }
-
-    /**
-     * Returns the lint client requesting the lint check
-     *
-     * @return the client, never null
-     */
-    @NonNull
-    public LintClient getClient() {
-        return mDriver.getClient();
-    }
-
-    /**
-     * Returns the driver running through the lint checks
-     *
-     * @return the driver
-     */
-    @NonNull
-    public LintDriver getDriver() {
-        return mDriver;
-    }
-
-    /**
-     * Returns the contents of the file. This may not be the contents of the
-     * file on disk, since it delegates to the {@link LintClient}, which in turn
-     * may decide to return the current edited contents of the file open in an
-     * editor.
-     *
-     * @return the contents of the given file, or null if an error occurs.
-     */
-    @Nullable
-    public String getContents() {
-        if (mContents == null) {
-            mContents = mDriver.getClient().readFile(file);
-        }
-
-        return mContents;
-    }
-
-    /**
-     * Returns the value of the given named property, or null.
-     *
-     * @param name the name of the property
-     * @return the corresponding value, or null
-     */
-    @SuppressWarnings("UnusedDeclaration") // Used in ADT
-    @Nullable
-    public Object getProperty(String name) {
-        if (mProperties == null) {
-            return null;
-        }
-
-        return mProperties.get(name);
-    }
-
-    /**
-     * Sets the value of the given named property.
-     *
-     * @param name the name of the property
-     * @param value the corresponding value
-     */
-    @SuppressWarnings("UnusedDeclaration") // Used in ADT
-    public void setProperty(@NonNull String name, @Nullable Object value) {
-        if (value == null) {
-            if (mProperties != null) {
-                mProperties.remove(name);
-            }
-        } else {
-            if (mProperties == null) {
-                mProperties = new HashMap<String, Object>();
-            }
-            mProperties.put(name, value);
-        }
-    }
-
-    /**
-     * Gets the SDK info for the current project.
-     *
-     * @return the SDK info for the current project, never null
-     */
-    @NonNull
-    public SdkInfo getSdkInfo() {
-        return mProject.getSdkInfo();
-    }
-
-    // ---- Convenience wrappers  ---- (makes the detector code a bit leaner)
-
-    /**
-     * Returns false if the given issue has been disabled. Convenience wrapper
-     * around {@link Configuration#getSeverity(Issue)}.
-     *
-     * @param issue the issue to check
-     * @return false if the issue has been disabled
-     */
-    public boolean isEnabled(@NonNull Issue issue) {
-        return mConfiguration.isEnabled(issue);
-    }
-
-    /**
-     * Reports an issue. Convenience wrapper around {@link LintClient#report}
-     *
-     * @param issue the issue to report
-     * @param location the location of the issue
-     * @param message the message for this warning
-     */
-    public void report(
-            @NonNull Issue issue,
-            @NonNull Location location,
-            @NonNull String message) {
-        //noinspection ConstantConditions
-        if (location == null) {
-            // Misbehaving third-party lint detectors
-            assert false : issue;
-            return;
-        }
-
-        if (location == Location.NONE) {
-            // Detector reported error for issue in a non-applicable location etc
-            return;
-        }
-
-        Configuration configuration = mConfiguration;
-
-        // If this error was computed for a context where the context corresponds to
-        // a project instead of a file, the actual error may be in a different project (e.g.
-        // a library project), so adjust the configuration as necessary.
-        Project project = mDriver.findProjectFor(location.getFile());
-        if (project != null) {
-            configuration = project.getConfiguration(mDriver);
-        }
-
-        // If an error occurs in a library project, but you've disabled that check in the
-        // main project, disable it in the library project too. (In some cases you don't
-        // control the lint.xml of a library project, and besides, if you're not interested in
-        // a check for your main project you probably don't care about it in the library either.)
-        if (configuration != mConfiguration
-                && mConfiguration.getSeverity(issue) == Severity.IGNORE) {
-            return;
-        }
-
-        Severity severity = configuration.getSeverity(issue);
-        if (severity == Severity.IGNORE) {
-            return;
-        }
-
-        mDriver.getClient().report(this, issue, severity, location, message, TextFormat.RAW);
-    }
-
-    /**
-     * Report an error.
-     * Like {@link #report(Issue, Location, String)} but with
-     * a now-unused data parameter at the end
-     *
-     * @deprecated Use {@link #report(Issue, Location, String)} instead;
-     *    this method is here for custom rule compatibility
-     */
-    @SuppressWarnings("UnusedDeclaration") // Potentially used by external existing custom rules
-    @Deprecated
-    public void report(
-            @NonNull Issue issue,
-            @NonNull Location location,
-            @NonNull String message,
-            @SuppressWarnings("UnusedParameters") @Nullable Object data) {
-        report(issue, location, message);
-    }
-
-    /**
-     * Send an exception to the log. Convenience wrapper around {@link LintClient#log}.
-     *
-     * @param exception the exception, possibly null
-     * @param format the error message using {@link String#format} syntax, possibly null
-     * @param args any arguments for the format string
-     */
-    public void log(
-            @Nullable Throwable exception,
-            @Nullable String format,
-            @Nullable Object... args) {
-        mDriver.getClient().log(exception, format, args);
-    }
-
-    /**
-     * Returns the current phase number. The first pass is numbered 1. Only one pass
-     * will be performed, unless a {@link Detector} calls {@link #requestRepeat}.
-     *
-     * @return the current phase, usually 1
-     */
-    public int getPhase() {
-        return mDriver.getPhase();
-    }
-
-    /**
-     * Requests another pass through the data for the given detector. This is
-     * typically done when a detector needs to do more expensive computation,
-     * but it only wants to do this once it <b>knows</b> that an error is
-     * present, or once it knows more specifically what to check for.
-     *
-     * @param detector the detector that should be included in the next pass.
-     *            Note that the lint runner may refuse to run more than a couple
-     *            of runs.
-     * @param scope the scope to be revisited. This must be a subset of the
-     *       current scope ({@link #getScope()}, and it is just a performance hint;
-     *       in particular, the detector should be prepared to be called on other
-     *       scopes as well (since they may have been requested by other detectors).
-     *       You can pall null to indicate "all".
-     */
-    public void requestRepeat(@NonNull Detector detector, @Nullable EnumSet<Scope> scope) {
-        mDriver.requestRepeat(detector, scope);
-    }
-
-    /** Returns the comment marker used in Studio to suppress statements for language, if any */
-    @Nullable
-    protected String getSuppressCommentPrefix() {
-        // Java and XML files are handled in sub classes (XmlContext, JavaContext)
-
-        String path = file.getPath();
-        if (path.endsWith(DOT_JAVA) || path.endsWith(".kt") || path.endsWith(DOT_GRADLE)) {
-            return JavaContext.SUPPRESS_COMMENT_PREFIX;
-        } else if (path.endsWith(DOT_XML)) {
-            return XmlContext.SUPPRESS_COMMENT_PREFIX;
-        } else if (path.endsWith(".cfg") || path.endsWith(".pro")) {
-            return "#suppress ";
-        }
-
-        return null;
-    }
-
-    /** Returns whether this file contains any suppress comment markers */
-    public boolean containsCommentSuppress() {
-        if (mContainsCommentSuppress == null) {
-            mContainsCommentSuppress = false;
-            String prefix = getSuppressCommentPrefix();
-            if (prefix != null) {
-                String contents = getContents();
-                if (contents != null) {
-                    mContainsCommentSuppress = contents.contains(prefix);
-                }
-            }
-        }
-
-        return mContainsCommentSuppress;
-    }
-
-    /**
-     * Returns true if the given issue is suppressed at the given character offset
-     * in the file's contents
-     */
-    public boolean isSuppressedWithComment(int startOffset, @NonNull Issue issue) {
-        String prefix = getSuppressCommentPrefix();
-        if (prefix == null) {
-            return false;
-        }
-
-        if (startOffset <= 0) {
-            return false;
-        }
-
-        // Check whether there is a comment marker
-        String contents = getContents();
-        assert contents != null; // otherwise we wouldn't be here
-        if (startOffset >= contents.length()) {
-            return false;
-        }
-
-        // Scan backwards to the previous line and see if it contains the marker
-        int lineStart = contents.lastIndexOf('\n', startOffset) + 1;
-        if (lineStart <= 1) {
-            return false;
-        }
-        int index = findPrefixOnPreviousLine(contents, lineStart, prefix);
-        if (index != -1 &&index+prefix.length() < lineStart) {
-                String line = contents.substring(index + prefix.length(), lineStart);
-            return line.contains(issue.getId())
-                    || line.contains(SUPPRESS_ALL) && line.trim().startsWith(SUPPRESS_ALL);
-        }
-
-        return false;
-    }
-
-    private static int findPrefixOnPreviousLine(String contents, int lineStart, String prefix) {
-        // Search backwards on the previous line until you find the prefix start (also look
-        // back on previous lines if the previous line(s) contain just whitespace
-        char first = prefix.charAt(0);
-        int offset = lineStart - 2; // 0: first char on this line, -1: \n on previous line, -2 last
-        boolean seenNonWhitespace = false;
-        for (; offset >= 0; offset--) {
-            char c = contents.charAt(offset);
-            if (seenNonWhitespace && c == '\n') {
-                return -1;
-            }
-
-            if (!seenNonWhitespace && !Character.isWhitespace(c)) {
-                seenNonWhitespace = true;
-            }
-
-            if (c == first && contents.regionMatches(false, offset, prefix, 0,
-                    prefix.length())) {
-                return offset;
-            }
-        }
-
-        return -1;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/DefaultPosition.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/DefaultPosition.java
deleted file mode 100644
index fd370cc..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/DefaultPosition.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A simple offset-based position *
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class DefaultPosition extends Position {
-    /** The line number (0-based where the first line is line 0) */
-    private final int mLine;
-
-    /**
-     * The column number (where the first character on the line is 0), or -1 if
-     * unknown
-     */
-    private final int mColumn;
-
-    /** The character offset */
-    private final int mOffset;
-
-    /**
-     * Creates a new {@link DefaultPosition}
-     *
-     * @param line the 0-based line number, or -1 if unknown
-     * @param column the 0-based column number, or -1 if unknown
-     * @param offset the offset, or -1 if unknown
-     */
-    public DefaultPosition(int line, int column, int offset) {
-        mLine = line;
-        mColumn = column;
-        mOffset = offset;
-    }
-
-    @Override
-    public int getLine() {
-        return mLine;
-    }
-
-    @Override
-    public int getOffset() {
-        return mOffset;
-    }
-
-    @Override
-    public int getColumn() {
-        return mColumn;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java
deleted file mode 100644
index fc60ac8..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java
+++ /dev/null
@@ -1,1515 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.JavaParser.ResolvedClass;
-import com.android.tools.klint.client.api.JavaParser.ResolvedMethod;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.UElementVisitor;
-import com.google.common.annotations.Beta;
-import com.intellij.psi.JavaElementVisitor;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiJavaCodeReferenceElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiNewExpression;
-
-import com.intellij.psi.PsiTypeParameter;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-import lombok.ast.AstVisitor;
-import lombok.ast.ClassDeclaration;
-import lombok.ast.ConstructorInvocation;
-import lombok.ast.MethodInvocation;
-import lombok.ast.Node;
-
-/**
- * A detector is able to find a particular problem (or a set of related problems).
- * Each problem type is uniquely identified as an {@link Issue}.
- * <p>
- * Detectors will be called in a predefined order:
- * <ol>
- *   <li> Manifest file
- *   <li> Resource files, in alphabetical order by resource type
- *        (therefore, "layout" is checked before "values", "values-de" is checked before
- *        "values-en" but after "values", and so on.
- *   <li> Java sources
- *   <li> Java classes
- *   <li> Gradle files
- *   <li> Generic files
- *   <li> Proguard files
- *   <li> Property files
- * </ol>
- * If a detector needs information when processing a file type that comes from a type of
- * file later in the order above, they can request a second phase; see
- * {@link LintDriver#requestRepeat}.
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class Detector {
-    /**
-     * Specialized interface for detectors that scan Java source file parse trees
-     * @deprecated Use {@link JavaPsiScanner} instead
-     */
-    @Deprecated @SuppressWarnings("unused") // Still here for third-party rules
-    public interface JavaScanner  {
-        /**
-         * Create a parse tree visitor to process the parse tree. All
-         * {@link JavaScanner} detectors must provide a visitor, unless they
-         * either return true from {@link #appliesToResourceRefs()} or return
-         * non null from {@link #getApplicableMethodNames()}.
-         * <p>
-         * If you return specific AST node types from
-         * {@link #getApplicableNodeTypes()}, then the visitor will <b>only</b>
-         * be called for the specific requested node types. This is more
-         * efficient, since it allows many detectors that apply to only a small
-         * part of the AST (such as method call nodes) to share iteration of the
-         * majority of the parse tree.
-         * <p>
-         * If you return null from {@link #getApplicableNodeTypes()}, then your
-         * visitor will be called from the top and all node types visited.
-         * <p>
-         * Note that a new visitor is created for each separate compilation
-         * unit, so you can store per file state in the visitor.
-         *
-         * @param context the {@link Context} for the file being analyzed
-         * @return a visitor, or null.
-         */
-        @Nullable
-        AstVisitor createJavaVisitor(@NonNull JavaContext context);
-
-        /**
-         * Return the types of AST nodes that the visitor returned from
-         * {@link #createJavaVisitor(JavaContext)} should visit. See the
-         * documentation for {@link #createJavaVisitor(JavaContext)} for details
-         * on how the shared visitor is used.
-         * <p>
-         * If you return null from this method, then the visitor will process
-         * the full tree instead.
-         * <p>
-         * Note that for the shared visitor, the return codes from the visit
-         * methods are ignored: returning true will <b>not</b> prune iteration
-         * of the subtree, since there may be other node types interested in the
-         * children. If you need to ensure that your visitor only processes a
-         * part of the tree, use a full visitor instead. See the
-         * OverdrawDetector implementation for an example of this.
-         *
-         * @return the list of applicable node types (AST node classes), or null
-         */
-        @Nullable
-        List<Class<? extends Node>> getApplicableNodeTypes();
-
-        /**
-         * Return the list of method names this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a method call in the list will be passed to the
-         * {@link #visitMethod(JavaContext, AstVisitor, MethodInvocation)}
-         * method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed calls.
-         * For example, the StringFormatDetector uses this mechanism to look for
-         * "format" calls, and when found it looks around (using the AST's
-         * {@link Node#getParent()} method) to see if it's called on
-         * a String class instance, and if so do its normal processing. Note
-         * that since it doesn't need to do any other AST processing, that
-         * detector does not actually supply a visitor.
-         *
-         * @return a set of applicable method names, or null.
-         */
-        @Nullable
-        List<String> getApplicableMethodNames();
-
-        /**
-         * Method invoked for any method calls found that matches any names
-         * returned by {@link #getApplicableMethodNames()}. This also passes
-         * back the visitor that was created by
-         * {@link #createJavaVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createJavaVisitor(JavaContext)}, or null
-         * @param node the {@link MethodInvocation} node for the invoked method
-         */
-        void visitMethod(
-                @NonNull JavaContext context,
-                @Nullable AstVisitor visitor,
-                @NonNull MethodInvocation node);
-
-        /**
-         * Return the list of constructor types this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a constructor call in the list will be passed to the
-         * {@link #visitConstructor(JavaContext, AstVisitor, ConstructorInvocation, ResolvedMethod)}
-         * method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed constructors.
-         *
-         * @return a set of applicable fully qualified types, or null.
-         */
-        @Nullable
-        List<String> getApplicableConstructorTypes();
-
-        /**
-         * Method invoked for any constructor calls found that matches any names
-         * returned by {@link #getApplicableConstructorTypes()}. This also passes
-         * back the visitor that was created by
-         * {@link #createJavaVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createJavaVisitor(JavaContext)}, or null
-         * @param node the {@link ConstructorInvocation} node for the invoked method
-         * @param constructor the resolved constructor method with type information
-         */
-        void visitConstructor(
-                @NonNull JavaContext context,
-                @Nullable AstVisitor visitor,
-                @NonNull ConstructorInvocation node,
-                @NonNull ResolvedMethod constructor);
-
-        /**
-         * Returns whether this detector cares about Android resource references
-         * (such as {@code R.layout.main} or {@code R.string.app_name}). If it
-         * does, then the visitor will look for these patterns, and if found, it
-         * will invoke {@link #visitResourceReference} passing the resource type
-         * and resource name. It also passes the visitor, if any, that was
-         * created by {@link #createJavaVisitor(JavaContext)}, such that a
-         * detector can do more than just look for resources.
-         *
-         * @return true if this detector wants to be notified of R resource
-         *         identifiers found in the code.
-         */
-        boolean appliesToResourceRefs();
-
-        /**
-         * Called for any resource references (such as {@code R.layout.main}
-         * found in Java code, provided this detector returned {@code true} from
-         * {@link #appliesToResourceRefs()}.
-         *
-         * @param context the lint scanning context
-         * @param visitor the visitor created from
-         *            {@link #createJavaVisitor(JavaContext)}, or null
-         * @param node the variable reference for the resource
-         * @param type the resource type, such as "layout" or "string"
-         * @param name the resource name, such as "main" from
-         *            {@code R.layout.main}
-         * @param isFramework whether the resource is a framework resource
-         *            (android.R) or a local project resource (R)
-         */
-        void visitResourceReference(
-                @NonNull JavaContext context,
-                @Nullable AstVisitor visitor,
-                @NonNull Node node,
-                @NonNull String type,
-                @NonNull String name,
-                boolean isFramework);
-
-        /**
-         * Returns a list of fully qualified names for super classes that this
-         * detector cares about. If not null, this detector will *only* be called
-         * if the current class is a subclass of one of the specified superclasses.
-         *
-         * @return a list of fully qualified names
-         */
-        @Nullable
-        List<String> applicableSuperClasses();
-
-        /**
-         * Called for each class that extends one of the super classes specified with
-         * {@link #applicableSuperClasses()}
-         *
-         * @param context the lint scanning context
-         * @param declaration the class declaration node, or null for anonymous classes
-         * @param node the class declaration node or the anonymous class construction node
-         * @param resolvedClass the resolved class
-         */
-        // TODO: Change signature to pass in the NormalTypeBody instead of the plain Node?
-        void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration declaration,
-                @NonNull Node node, @NonNull ResolvedClass resolvedClass);
-    }
-
-    /**
-     Interface to be implemented by lint detectors that want to analyze
-     Java source files.
-     <p>
-     The Lint Java API sits on top of IntelliJ IDEA's "PSI" API, an API
-     which exposes the underlying abstract syntax tree as well as providing
-     core services like resolving symbols.
-     <p>
-     This new API replaces the older Lombok AST API that was used for Java
-     source checks. Migrating a check from the Lombok APIs to the new PSI
-     based APIs is relatively straightforward.
-     <p>
-     First, replace "implements JavaScanner" with "implements
-     JavaPsiScanner" in your detector signature, and then locate all the
-     JavaScanner methods your detector was overriding and replace them with
-     the new corresponding signatures.
-     <p>
-     For example, replace
-     <pre>
-     {@code List<Class<? extends Node>> getApplicableNodeTypes();}
-     </pre>
-     with
-     <pre>
-     {@code List<Class<? extends PsiElement>> getApplicablePsiTypes();}
-     </pre>
-     and replace
-     <pre>
-     void visitMethod(
-     &#064;NonNull JavaContext context,
-     &#064;Nullable AstVisitor visitor,
-     &#064;NonNull MethodInvocation node);
-     </pre>
-     with
-     <pre>
-     void visitMethod(
-     &#064;NonNull JavaContext context,
-     &#064;Nullable JavaElementVisitor visitor,
-     &#064;NonNull PsiMethodCallExpression call,
-     &#064;NonNull PsiMethod method);
-     </pre>
-     and so on.
-     <p>
-     Finally, replace the various Lombok iteration code with PSI based
-     code. Both Lombok and PSI used class names that closely resemble the
-     Java language specification, so guessing the corresponding names is
-     straightforward; here are some examples:
-     <pre>
-     ClassDeclaration ⇒ PsiClass
-     MethodDeclaration ⇒ PsiMethod
-     MethodInvocation ⇒ PsiMethodCallExpression
-     ConstructorInvocation ⇒ PsiNewExpression
-     If ⇒ PsiIfStatement
-     For ⇒ PsiForStatement
-     Continue ⇒ PsiContinueStatement
-     StringLiteral ⇒ PsiLiteral
-     IntegralLiteral ⇒ PsiLiteral
-     ... etc
-     </pre>
-     Lombok AST had no support for symbol and type resolution, so lint
-     added its own separate API to support (the "ResolvedNode"
-     hierarchy). This is no longer needed since PSI supports it directly
-     (for example, on a PsiMethodCallExpression you just call
-     "resolveMethod" to get the PsiMethod the method calls, and on a
-     PsiExpression you just call getType() to get the corresponding
-     <p>
-     The old ResolvedNode interface was written for lint so it made certain
-     kinds of common checks very easy. To help make porting lint rules from
-     the old API easier, and to make writing future lint checks easier
-     too), there is a new helper class, "JavaEvaluator" (which you can
-     obtain from JavaContext). This lets you for example quickly check
-     whether a given method is a member of a subclass of a given class, or
-     whether a method has a certain set of parameters, etc. It also makes
-     it easy to check whether a given method is private, abstract or
-     static, and so on. (And most of its parameters are nullable which
-     makes it simpler to use; you don't have to null check resolve results
-     before calling into it.)
-     <p>
-     Some further porting tips:
-     <ul>
-     <li> Make sure you don't call toString() on nodes to get their
-     contents. In Lombok, toString returned the underlying source
-     text. In PSI, call getText() instead, since toString() is meant for
-     debugging and includes node types etc.
-
-     <li> ResolvedClass#getName() used to return *qualified* name. In PSI,
-     PsiClass#getName() returns just the simple name, so call
-     #getQualifiedName() instead if that's what your code needs! Node
-     also that PsiClassType#getClassName() returns the simple name; if
-     you want the fully qualified name, call PsiType#getCanonicalText().
-
-     <li> Lombok didn't distinguish between a local variable declaration, a
-     parameter and a field declaration. These are all different in PSI,
-     so when writing visitors, make sure you replace a single
-     visitVariableDeclaration with visitField, visitLocalVariable and
-     visitParameter methods as applicable.
-
-     <li> Note that when lint runs in the IDE, there may be extra PSI nodes in
-     the hierarchy representing whitespace as well as parentheses. Watch
-     out for this when calling getParent, getPrevSibling or
-     getNextSibling - don't just go one level up and check instanceof
-     {@code <something>}; instead, use LintUtils.skipParentheses (or the
-     corresponding methods to skip whitespace left and right.)  Note that
-     when you write lint unit tests, the infrastructure will run your
-     tests twice, one with a normal AST and once where it has inserted
-     whitespace and parentheses everywhere, and it asserts that you come
-     up with the same analysis results. (This caught 16 failing tests
-     across 7 different detectors.)
-
-     <li> Annotation handling is a bit different. In ResolvedAnnotations I had
-     (for convenience) inlined things like annotations on the class; you
-     now have to resolve the annotation name reference to the
-     corresponding annotation class and look there.
-     </ul>
-
-     Some additional conversion examples: replace
-     <pre>
-     &#064;Override
-     public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
-     &#064;NonNull MethodInvocation node) {
-         ResolvedNode resolved = context.resolve(node);
-         if (resolved instanceof ResolvedMethod) {
-             ResolvedMethod method = (ResolvedMethod) resolved;
-             if (method.getContainingClass().matches("android.os.Parcel")) {
-                 ...
-     </pre>
-     with
-     <pre>
-     &#064;Override
-     public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
-             &#064;NonNull PsiCall node) {
-         if (method != null &amp;&amp; method.getContainingClass() != null &amp;&amp;
-             "android.os.Parcel".equals(method.getContainingClass().getQualifiedName())) {
-             ....
-     </pre>
-
-     Similarly:
-     <pre>
-     if (method.getArgumentCount() != 2
-             || !method.getArgumentType(0).matchesName(TYPE_OBJECT)
-             || !method.getArgumentType(1).matchesName(TYPE_STRING)) {
-         return;
-     }
-     </pre>
-     can now be written as
-     <pre>
-     JavaEvaluator resolver = context.getEvaluator();
-     if (!resolver.methodMatches(method, WEB_VIEW, true, TYPE_OBJECT, TYPE_STRING)) {
-         return;
-     }
-     </pre>
-     Finally, note that many deprecated methods in lint itself point to the replacement
-     methods, see for example {@link JavaContext#findSurroundingMethod(Node)}.
-     */
-    public interface JavaPsiScanner  {
-        /**
-         * Create a parse tree visitor to process the parse tree. All
-         * {@link JavaScanner} detectors must provide a visitor, unless they
-         * either return true from {@link #appliesToResourceRefs()} or return
-         * non null from {@link #getApplicableMethodNames()}.
-         * <p>
-         * If you return specific AST node types from
-         * {@link #getApplicablePsiTypes()}, then the visitor will <b>only</b>
-         * be called for the specific requested node types. This is more
-         * efficient, since it allows many detectors that apply to only a small
-         * part of the AST (such as method call nodes) to share iteration of the
-         * majority of the parse tree.
-         * <p>
-         * If you return null from {@link #getApplicablePsiTypes()}, then your
-         * visitor will be called from the top and all node types visited.
-         * <p>
-         * Note that a new visitor is created for each separate compilation
-         * unit, so you can store per file state in the visitor.
-         * <p>
-         * <b>
-         * NOTE: Your visitor should <b>NOT</b> extend JavaRecursiveElementVisitor.
-         * Your visitor should only visit the current node type; the infrastructure
-         * will do the recursion. (Lint's unit test infrastructure will check and
-         * enforce this restriction.)
-         * </b>
-         *
-         * @param context the {@link Context} for the file being analyzed
-         * @return a visitor, or null.
-         */
-        @Nullable
-        JavaElementVisitor createPsiVisitor(@NonNull JavaContext context);
-
-        /**
-         * Return the types of AST nodes that the visitor returned from
-         * {@link #createJavaVisitor(JavaContext)} should visit. See the
-         * documentation for {@link #createJavaVisitor(JavaContext)} for details
-         * on how the shared visitor is used.
-         * <p>
-         * If you return null from this method, then the visitor will process
-         * the full tree instead.
-         * <p>
-         * Note that for the shared visitor, the return codes from the visit
-         * methods are ignored: returning true will <b>not</b> prune iteration
-         * of the subtree, since there may be other node types interested in the
-         * children. If you need to ensure that your visitor only processes a
-         * part of the tree, use a full visitor instead. See the
-         * OverdrawDetector implementation for an example of this.
-         *
-         * @return the list of applicable node types (AST node classes), or null
-         */
-        @Nullable
-        List<Class<? extends PsiElement>> getApplicablePsiTypes();
-
-        /**
-         * Return the list of method names this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a method call in the list will be passed to the
-         * {@link #visitMethod(JavaContext, JavaElementVisitor, PsiMethodCallExpression, PsiMethod)}
-         * method for processing. The visitor created by
-         * {@link #createPsiVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed calls.
-         * For example, the StringFormatDetector uses this mechanism to look for
-         * "format" calls, and when found it looks around (using the AST's
-         * {@link PsiElement#getParent()} method) to see if it's called on
-         * a String class instance, and if so do its normal processing. Note
-         * that since it doesn't need to do any other AST processing, that
-         * detector does not actually supply a visitor.
-         *
-         * @return a set of applicable method names, or null.
-         */
-        @Nullable
-        List<String> getApplicableMethodNames();
-
-        /**
-         * Method invoked for any method calls found that matches any names
-         * returned by {@link #getApplicableMethodNames()}. This also passes
-         * back the visitor that was created by
-         * {@link #createJavaVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param call the {@link PsiMethodCallExpression} node for the invoked method
-         * @param method the {@link PsiMethod} being called
-         */
-        void visitMethod(
-                @NonNull JavaContext context,
-                @Nullable JavaElementVisitor visitor,
-                @NonNull PsiMethodCallExpression call,
-                @NonNull PsiMethod method);
-
-        /**
-         * Return the list of constructor types this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a constructor call in the list will be passed to the
-         * {@link #visitConstructor(JavaContext, JavaElementVisitor, PsiNewExpression, PsiMethod)}
-         * method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed constructors.
-         *
-         * @return a set of applicable fully qualified types, or null.
-         */
-        @Nullable
-        List<String> getApplicableConstructorTypes();
-
-        /**
-         * Method invoked for any constructor calls found that matches any names
-         * returned by {@link #getApplicableConstructorTypes()}. This also passes
-         * back the visitor that was created by
-         * {@link #createPsiVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param node the {@link PsiNewExpression} node for the invoked method
-         * @param constructor the called constructor method
-         */
-        void visitConstructor(
-                @NonNull JavaContext context,
-                @Nullable JavaElementVisitor visitor,
-                @NonNull PsiNewExpression node,
-                @NonNull PsiMethod constructor);
-
-        /**
-         * Return the list of reference names types this detector is interested in, or null. If this
-         * method returns non-null, then any AST elements that match a reference in the list will be
-         * passed to the {@link #visitReference(JavaContext, JavaElementVisitor,
-         * PsiJavaCodeReferenceElement, PsiElement)} method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that method, although it can be
-         * null. <p> This makes it easy to write detectors that focus on some fixed references.
-         *
-         * @return a set of applicable reference names, or null.
-         */
-        @Nullable
-        List<String> getApplicableReferenceNames();
-
-        /**
-         * Method invoked for any references found that matches any names returned by {@link
-         * #getApplicableReferenceNames()}. This also passes back the visitor that was created by
-         * {@link #createPsiVisitor(JavaContext)}, but a visitor is not required. It is intended for
-         * detectors that need to do additional AST processing, but also want the convenience of not
-         * having to look for method names on their own.
-         *
-         * @param context    the context of the lint request
-         * @param visitor    the visitor created from {@link #createPsiVisitor(JavaContext)}, or
-         *                   null
-         * @param reference  the {@link PsiJavaCodeReferenceElement} element
-         * @param referenced the referenced element
-         */
-        void visitReference(
-                @NonNull JavaContext context,
-                @Nullable JavaElementVisitor visitor,
-                @NonNull PsiJavaCodeReferenceElement reference,
-                @NonNull PsiElement referenced);
-
-        /**
-         * Returns whether this detector cares about Android resource references
-         * (such as {@code R.layout.main} or {@code R.string.app_name}). If it
-         * does, then the visitor will look for these patterns, and if found, it
-         * will invoke {@link #visitResourceReference} passing the resource type
-         * and resource name. It also passes the visitor, if any, that was
-         * created by {@link #createJavaVisitor(JavaContext)}, such that a
-         * detector can do more than just look for resources.
-         *
-         * @return true if this detector wants to be notified of R resource
-         *         identifiers found in the code.
-         */
-        boolean appliesToResourceRefs();
-
-        /**
-         * Called for any resource references (such as {@code R.layout.main}
-         * found in Java code, provided this detector returned {@code true} from
-         * {@link #appliesToResourceRefs()}.
-         *
-         * @param context the lint scanning context
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param node the variable reference for the resource
-         * @param type the resource type, such as "layout" or "string"
-         * @param name the resource name, such as "main" from
-         *            {@code R.layout.main}
-         * @param isFramework whether the resource is a framework resource
-         *            (android.R) or a local project resource (R)
-         */
-        void visitResourceReference(
-                @NonNull JavaContext context,
-                @Nullable JavaElementVisitor visitor,
-                @NonNull PsiElement node,
-                @NonNull ResourceType type,
-                @NonNull String name,
-                boolean isFramework);
-
-        /**
-         * Returns a list of fully qualified names for super classes that this
-         * detector cares about. If not null, this detector will <b>only</b> be called
-         * if the current class is a subclass of one of the specified superclasses.
-         *
-         * @return a list of fully qualified names
-         */
-        @Nullable
-        List<String> applicableSuperClasses();
-
-        /**
-         * Called for each class that extends one of the super classes specified with
-         * {@link #applicableSuperClasses()}.
-         * <p>
-         * Note: This method will not be called for {@link PsiTypeParameter} classes. These
-         * aren't really classes in the sense most lint detectors think of them, so these
-         * are excluded to avoid having lint checks that don't defensively code for these
-         * accidentally report errors on type parameters. If you really need to check these,
-         * use {@link #getApplicablePsiTypes} with {@code PsiTypeParameter.class} instead.
-         *
-         * @param context the lint scanning context
-         * @param declaration the class declaration node, or null for anonymous classes
-         */
-        void checkClass(@NonNull JavaContext context, @NonNull PsiClass declaration);
-    }
-
-    public interface UastScanner {
-        /**
-         * Create a parse tree visitor to process the parse tree. All
-         * {@link JavaScanner} detectors must provide a visitor, unless they
-         * either return true from {@link #appliesToResourceRefs()} or return
-         * non null from {@link #getApplicableMethodNames()}.
-         * <p>
-         * If you return specific AST node types from
-         * {@link #getApplicablePsiTypes()}, then the visitor will <b>only</b>
-         * be called for the specific requested node types. This is more
-         * efficient, since it allows many detectors that apply to only a small
-         * part of the AST (such as method call nodes) to share iteration of the
-         * majority of the parse tree.
-         * <p>
-         * If you return null from {@link #getApplicablePsiTypes()}, then your
-         * visitor will be called from the top and all node types visited.
-         * <p>
-         * Note that a new visitor is created for each separate compilation
-         * unit, so you can store per file state in the visitor.
-         * <p>
-         * <b>
-         * NOTE: Your visitor should <b>NOT</b> extend JavaRecursiveElementVisitor.
-         * Your visitor should only visit the current node type; the infrastructure
-         * will do the recursion. (Lint's unit test infrastructure will check and
-         * enforce this restriction.)
-         * </b>
-         *
-         * @param context the {@link Context} for the file being analyzed
-         * @return a visitor, or null.
-         */
-        @Nullable
-        UastVisitor createUastVisitor(@NonNull JavaContext context);
-
-        /**
-         * Return the types of AST nodes that the visitor returned from
-         * {@link #createJavaVisitor(JavaContext)} should visit. See the
-         * documentation for {@link #createJavaVisitor(JavaContext)} for details
-         * on how the shared visitor is used.
-         * <p>
-         * If you return null from this method, then the visitor will process
-         * the full tree instead.
-         * <p>
-         * Note that for the shared visitor, the return codes from the visit
-         * methods are ignored: returning true will <b>not</b> prune iteration
-         * of the subtree, since there may be other node types interested in the
-         * children. If you need to ensure that your visitor only processes a
-         * part of the tree, use a full visitor instead. See the
-         * OverdrawDetector implementation for an example of this.
-         *
-         * @return the list of applicable node types (AST node classes), or null
-         */
-        @Nullable
-        List<Class<? extends UElement>> getApplicableUastTypes();
-
-        @Nullable
-        List<Class<? extends PsiElement>> getApplicablePsiTypes();
-        
-        /**
-         * Return the list of method names this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a method call in the list will be passed to the
-         * {@link #visitMethod(JavaContext, JavaElementVisitor, PsiMethodCallExpression, PsiMethod)}
-         * method for processing. The visitor created by
-         * {@link #createPsiVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed calls.
-         * For example, the StringFormatDetector uses this mechanism to look for
-         * "format" calls, and when found it looks around (using the AST's
-         * {@link PsiElement#getParent()} method) to see if it's called on
-         * a String class instance, and if so do its normal processing. Note
-         * that since it doesn't need to do any other AST processing, that
-         * detector does not actually supply a visitor.
-         *
-         * @return a set of applicable method names, or null.
-         */
-        @Nullable
-        List<String> getApplicableMethodNames();
-
-        /**
-         * Method invoked for any method calls found that matches any names
-         * returned by {@link #getApplicableMethodNames()}. This also passes
-         * back the visitor that was created by
-         * {@link #createJavaVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param node the {@link PsiMethodCallExpression} node for the invoked method
-         * @param method the {@link PsiMethod} being called
-         */
-        void visitMethod(
-                @NonNull JavaContext context,
-                @Nullable UastVisitor visitor,
-                @NonNull UCallExpression node,
-                @NonNull UMethod method);
-
-        /**
-         * Return the list of constructor types this detector is interested in, or
-         * null. If this method returns non-null, then any AST nodes that match
-         * a constructor call in the list will be passed to the
-         * {@link #visitConstructor(JavaContext, JavaElementVisitor, PsiNewExpression, PsiMethod)}
-         * method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that
-         * method, although it can be null.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed constructors.
-         *
-         * @return a set of applicable fully qualified types, or null.
-         */
-        @Nullable
-        List<String> getApplicableConstructorTypes();
-
-        /**
-         * Method invoked for any constructor calls found that matches any names
-         * returned by {@link #getApplicableConstructorTypes()}. This also passes
-         * back the visitor that was created by
-         * {@link #createPsiVisitor(JavaContext)}, but a visitor is not
-         * required. It is intended for detectors that need to do additional AST
-         * processing, but also want the convenience of not having to look for
-         * method names on their own.
-         *
-         * @param context the context of the lint request
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param node the {@link PsiNewExpression} node for the invoked method
-         * @param constructor the called constructor method
-         */
-        void visitConstructor(
-                @NonNull JavaContext context,
-                @Nullable UastVisitor visitor,
-                @NonNull UCallExpression node,
-                @NonNull UMethod constructor);
-
-        /**
-         * Return the list of reference names types this detector is interested in, or null. If this
-         * method returns non-null, then any AST elements that match a reference in the list will be
-         * passed to the {@link #visitReference(JavaContext, JavaElementVisitor,
-         * PsiJavaCodeReferenceElement, PsiElement)} method for processing. The visitor created by
-         * {@link #createJavaVisitor(JavaContext)} is also passed to that method, although it can be
-         * null. <p> This makes it easy to write detectors that focus on some fixed references.
-         *
-         * @return a set of applicable reference names, or null.
-         */
-        @Nullable
-        List<String> getApplicableReferenceNames();
-
-        /**
-         * Method invoked for any references found that matches any names returned by {@link
-         * #getApplicableReferenceNames()}. This also passes back the visitor that was created by
-         * {@link #createPsiVisitor(JavaContext)}, but a visitor is not required. It is intended for
-         * detectors that need to do additional AST processing, but also want the convenience of not
-         * having to look for method names on their own.
-         *
-         * @param context    the context of the lint request
-         * @param visitor    the visitor created from {@link #createPsiVisitor(JavaContext)}, or
-         *                   null
-         * @param reference  the {@link PsiJavaCodeReferenceElement} element
-         * @param referenced the referenced element
-         */
-        void visitReference(
-                @NonNull JavaContext context,
-                @Nullable UastVisitor visitor,
-                @NonNull UReferenceExpression reference,
-                @NonNull PsiElement referenced);
-
-        /**
-         * Returns whether this detector cares about Android resource references
-         * (such as {@code R.layout.main} or {@code R.string.app_name}). If it
-         * does, then the visitor will look for these patterns, and if found, it
-         * will invoke {@link #visitResourceReference} passing the resource type
-         * and resource name. It also passes the visitor, if any, that was
-         * created by {@link #createJavaVisitor(JavaContext)}, such that a
-         * detector can do more than just look for resources.
-         *
-         * @return true if this detector wants to be notified of R resource
-         *         identifiers found in the code.
-         */
-        boolean appliesToResourceRefs();
-
-        /**
-         * Called for any resource references (such as {@code R.layout.main}
-         * found in Java code, provided this detector returned {@code true} from
-         * {@link #appliesToResourceRefs()}.
-         *
-         * @param context the lint scanning context
-         * @param visitor the visitor created from
-         *            {@link #createPsiVisitor(JavaContext)}, or null
-         * @param node the variable reference for the resource
-         * @param type the resource type, such as "layout" or "string"
-         * @param name the resource name, such as "main" from
-         *            {@code R.layout.main}
-         * @param isFramework whether the resource is a framework resource
-         *            (android.R) or a local project resource (R)
-         */
-        void visitResourceReference(
-                @NonNull JavaContext context,
-                @Nullable UastVisitor visitor,
-                @NonNull UElement node,
-                @NonNull ResourceType type,
-                @NonNull String name,
-                boolean isFramework);
-
-        /**
-         * Returns a list of fully qualified names for super classes that this
-         * detector cares about. If not null, this detector will <b>only</b> be called
-         * if the current class is a subclass of one of the specified superclasses.
-         *
-         * @return a list of fully qualified names
-         */
-        @Nullable
-        List<String> applicableSuperClasses();
-
-        /**
-         * Called for each class that extends one of the super classes specified with
-         * {@link #applicableSuperClasses()}.
-         * <p>
-         * Note: This method will not be called for {@link PsiTypeParameter} classes. These
-         * aren't really classes in the sense most lint detectors think of them, so these
-         * are excluded to avoid having lint checks that don't defensively code for these
-         * accidentally report errors on type parameters. If you really need to check these,
-         * use {@link #getApplicablePsiTypes} with {@code PsiTypeParameter.class} instead.
-         *
-         * @param context the lint scanning context
-         * @param declaration the class declaration node, or null for anonymous classes
-         */
-        void checkClass(@NonNull JavaContext context, @NonNull UClass declaration);
-    }
-
-    /** Specialized interface for detectors that scan Java class files */
-    public interface ClassScanner  {
-        /**
-         * Checks the given class' bytecode for issues.
-         *
-         * @param context the context of the lint check, pointing to for example
-         *            the file
-         * @param classNode the root class node
-         */
-        void checkClass(@NonNull ClassContext context, @NonNull ClassNode classNode);
-
-        /**
-         * Returns the list of node types (corresponding to the constants in the
-         * {@link AbstractInsnNode} class) that this scanner applies to. The
-         * {@link #checkInstruction(ClassContext, ClassNode, MethodNode, AbstractInsnNode)}
-         * method will be called for each match.
-         *
-         * @return an array containing all the node types this detector should be
-         *         called for, or null if none.
-         */
-        @Nullable
-        int[] getApplicableAsmNodeTypes();
-
-        /**
-         * Process a given instruction node, and register lint issues if
-         * applicable.
-         *
-         * @param context the context of the lint check, pointing to for example
-         *            the file
-         * @param classNode the root class node
-         * @param method the method node containing the call
-         * @param instruction the actual instruction
-         */
-        void checkInstruction(@NonNull ClassContext context, @NonNull ClassNode classNode,
-                @NonNull MethodNode method, @NonNull AbstractInsnNode instruction);
-
-        /**
-         * Return the list of method call names (in VM format, e.g. {@code "<init>"} for
-         * constructors, etc) for method calls this detector is interested in,
-         * or null. T his will be used to dispatch calls to
-         * {@link #checkCall(ClassContext, ClassNode, MethodNode, MethodInsnNode)}
-         * for only the method calls in owners that the detector is interested
-         * in.
-         * <p>
-         * <b>NOTE</b>: If you return non null from this method, then <b>only</b>
-         * {@link #checkCall(ClassContext, ClassNode, MethodNode, MethodInsnNode)}
-         * will be called if a suitable method is found;
-         * {@link #checkClass(ClassContext, ClassNode)} will not be called under
-         * any circumstances.
-         * <p>
-         * This makes it easy to write detectors that focus on some fixed calls,
-         * and allows lint to make a single pass over the bytecode over a class,
-         * and efficiently dispatch method calls to any detectors that are
-         * interested in it. Without this, each new lint check interested in a
-         * single method, would be doing a complete pass through all the
-         * bytecode instructions of the class via the
-         * {@link #checkClass(ClassContext, ClassNode)} method, which would make
-         * each newly added lint check make lint slower. Now a single dispatch
-         * map is used instead, and for each encountered call in the single
-         * dispatch, it looks up in the map which if any detectors are
-         * interested in the given call name, and dispatches to each one in
-         * turn.
-         *
-         * @return a list of applicable method names, or null.
-         */
-        @Nullable
-        List<String> getApplicableCallNames();
-
-        /**
-         * Just like {@link Detector#getApplicableCallNames()}, but for the owner
-         * field instead. The
-         * {@link #checkCall(ClassContext, ClassNode, MethodNode, MethodInsnNode)}
-         * method will be called for all {@link MethodInsnNode} instances where the
-         * owner field matches any of the members returned in this node.
-         * <p>
-         * Note that if your detector provides both a name and an owner, the
-         * method will be called for any nodes matching either the name <b>or</b>
-         * the owner, not only where they match <b>both</b>. Note also that it will
-         * be called twice - once for the name match, and (at least once) for the owner
-         * match.
-         *
-         * @return a list of applicable owner names, or null.
-         */
-        @Nullable
-        List<String> getApplicableCallOwners();
-
-        /**
-         * Process a given method call node, and register lint issues if
-         * applicable. This is similar to the
-         * {@link #checkInstruction(ClassContext, ClassNode, MethodNode, AbstractInsnNode)}
-         * method, but has the additional advantage that it is only called for known
-         * method names or method owners, according to
-         * {@link #getApplicableCallNames()} and {@link #getApplicableCallOwners()}.
-         *
-         * @param context the context of the lint check, pointing to for example
-         *            the file
-         * @param classNode the root class node
-         * @param method the method node containing the call
-         * @param call the actual method call node
-         */
-        void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode,
-                @NonNull MethodNode method, @NonNull MethodInsnNode call);
-    }
-
-    /**
-     * Specialized interface for detectors that scan binary resource files
-     * (typically bitmaps but also files in res/raw)
-     */
-    public interface BinaryResourceScanner {
-        /**
-         * Called for each resource folder
-         *
-         * @param context the context for the resource file
-         */
-        void checkBinaryResource(@NonNull ResourceContext context);
-
-        /**
-         * Returns whether this detector applies to the given folder type. This
-         * allows the detectors to be pruned from iteration, so for example when we
-         * are analyzing a string value file we don't need to look up detectors
-         * related to layout.
-         *
-         * @param folderType the folder type to be visited
-         * @return true if this detector can apply to resources in folders of the
-         *         given type
-         */
-        boolean appliesTo(@NonNull ResourceFolderType folderType);
-    }
-
-    /** Specialized interface for detectors that scan resource folders (the folder directory
-     * itself, not the individual files within it */
-    public interface ResourceFolderScanner {
-        /**
-         * Called for each resource folder
-         *
-         * @param context    the context for the resource folder
-         * @param folderName the resource folder name
-         */
-        void checkFolder(@NonNull ResourceContext context, @NonNull String folderName);
-
-        /**
-         * Returns whether this detector applies to the given folder type. This
-         * allows the detectors to be pruned from iteration, so for example when we
-         * are analyzing a string value file we don't need to look up detectors
-         * related to layout.
-         *
-         * @param folderType the folder type to be visited
-         * @return true if this detector can apply to resources in folders of the
-         *         given type
-         */
-        boolean appliesTo(@NonNull ResourceFolderType folderType);
-    }
-
-    /** Specialized interface for detectors that scan XML files */
-    public interface XmlScanner {
-        /**
-         * Visit the given document. The detector is responsible for its own iteration
-         * through the document.
-         * @param context information about the document being analyzed
-         * @param document the document to examine
-         */
-        void visitDocument(@NonNull XmlContext context, @NonNull Document document);
-
-        /**
-         * Visit the given element.
-         * @param context information about the document being analyzed
-         * @param element the element to examine
-         */
-        void visitElement(@NonNull XmlContext context, @NonNull Element element);
-
-        /**
-         * Visit the given element after its children have been analyzed.
-         * @param context information about the document being analyzed
-         * @param element the element to examine
-         */
-        void visitElementAfter(@NonNull XmlContext context, @NonNull Element element);
-
-        /**
-         * Visit the given attribute.
-         * @param context information about the document being analyzed
-         * @param attribute the attribute node to examine
-         */
-        void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute);
-
-        /**
-         * Returns the list of elements that this detector wants to analyze. If non
-         * null, this detector will be called (specifically, the
-         * {@link #visitElement} method) for each matching element in the document.
-         * <p>
-         * If this method returns null, and {@link #getApplicableAttributes()} also returns
-         * null, then the {@link #visitDocument} method will be called instead.
-         *
-         * @return a collection of elements, or null, or the special
-         *         {@link XmlScanner#ALL} marker to indicate that every single
-         *         element should be analyzed.
-         */
-        @Nullable
-        Collection<String> getApplicableElements();
-
-        /**
-         * Returns the list of attributes that this detector wants to analyze. If non
-         * null, this detector will be called (specifically, the
-         * {@link #visitAttribute} method) for each matching attribute in the document.
-         * <p>
-         * If this method returns null, and {@link #getApplicableElements()} also returns
-         * null, then the {@link #visitDocument} method will be called instead.
-         *
-         * @return a collection of attributes, or null, or the special
-         *         {@link XmlScanner#ALL} marker to indicate that every single
-         *         attribute should be analyzed.
-         */
-        @Nullable
-        Collection<String> getApplicableAttributes();
-
-        /**
-         * Special marker collection returned by {@link #getApplicableElements()} or
-         * {@link #getApplicableAttributes()} to indicate that the check should be
-         * invoked on all elements or all attributes
-         */
-        @NonNull
-        List<String> ALL = new ArrayList<String>(0); // NOT Collections.EMPTY!
-        // We want to distinguish this from just an *empty* list returned by the caller!
-    }
-
-    /** Specialized interface for detectors that scan Gradle files */
-    public interface GradleScanner {
-        void visitBuildScript(@NonNull Context context, Map<String, Object> sharedData);
-    }
-
-    /** Specialized interface for detectors that scan other files */
-    public interface OtherFileScanner {
-        /**
-         * Returns the set of files this scanner wants to consider.  If this includes
-         * {@link Scope#OTHER} then all source files will be checked. Note that the
-         * set of files will not just include files of the indicated type, but all files
-         * within the relevant source folder. For example, returning {@link Scope#JAVA_FILE}
-         * will not just return {@code .java} files, but also other resource files such as
-         * {@code .html} and other files found within the Java source folders.
-         * <p>
-         * Lint will call the {@link #run(Context)}} method when the file should be checked.
-         *
-         * @return set of scopes that define the types of source files the
-         *    detector wants to consider
-         */
-        @NonNull
-        EnumSet<Scope> getApplicableFiles();
-    }
-
-    /**
-     * Runs the detector. This method will not be called for certain specialized
-     * detectors, such as {@link XmlScanner} and {@link JavaScanner}, where
-     * there are specialized analysis methods instead such as
-     * {@link XmlScanner#visitElement(XmlContext, Element)}.
-     *
-     * @param context the context describing the work to be done
-     */
-    public void run(@NonNull Context context) {
-    }
-
-    /**
-     * Returns true if this detector applies to the given file
-     *
-     * @param context the context to check
-     * @param file the file in the context to check
-     * @return true if this detector applies to the given context and file
-     */
-    @Deprecated // Slated for removal in lint 2.0
-    public boolean appliesTo(@NonNull Context context, @NonNull File file) {
-        return false;
-    }
-
-    /**
-     * Analysis is about to begin, perform any setup steps.
-     *
-     * @param context the context for the check referencing the project, lint
-     *            client, etc
-     */
-    public void beforeCheckProject(@NonNull Context context) {
-    }
-
-    /**
-     * Analysis has just been finished for the whole project, perform any
-     * cleanup or report issues that require project-wide analysis.
-     *
-     * @param context the context for the check referencing the project, lint
-     *            client, etc
-     */
-    public void afterCheckProject(@NonNull Context context) {
-    }
-
-    /**
-     * Analysis is about to begin for the given library project, perform any setup steps.
-     *
-     * @param context the context for the check referencing the project, lint
-     *            client, etc
-     */
-    public void beforeCheckLibraryProject(@NonNull Context context) {
-    }
-
-    /**
-     * Analysis has just been finished for the given library project, perform any
-     * cleanup or report issues that require library-project-wide analysis.
-     *
-     * @param context the context for the check referencing the project, lint
-     *            client, etc
-     */
-    public void afterCheckLibraryProject(@NonNull Context context) {
-    }
-
-    /**
-     * Analysis is about to be performed on a specific file, perform any setup
-     * steps.
-     * <p>
-     * Note: When this method is called at the beginning of checking an XML
-     * file, the context is guaranteed to be an instance of {@link XmlContext},
-     * and similarly for a Java source file, the context will be a
-     * {@link JavaContext} and so on.
-     *
-     * @param context the context for the check referencing the file to be
-     *            checked, the project, etc.
-     */
-    public void beforeCheckFile(@NonNull Context context) {
-    }
-
-    /**
-     * Analysis has just been finished for a specific file, perform any cleanup
-     * or report issues found
-     * <p>
-     * Note: When this method is called at the end of checking an XML
-     * file, the context is guaranteed to be an instance of {@link XmlContext},
-     * and similarly for a Java source file, the context will be a
-     * {@link JavaContext} and so on.
-     *
-     * @param context the context for the check referencing the file to be
-     *            checked, the project, etc.
-     */
-    public void afterCheckFile(@NonNull Context context) {
-    }
-
-    /**
-     * Returns the expected speed of this detector
-     *
-     * @return the expected speed of this detector
-     */
-    @NonNull
-    @Deprecated // Slated for removal in Lint 2.0
-    public Speed getSpeed() {
-        return Speed.NORMAL;
-    }
-
-    /**
-     * Returns the expected speed of this detector.
-     * The issue parameter is made available for subclasses which analyze multiple issues
-     * and which need to distinguish implementation cost by issue. If the detector does
-     * not analyze multiple issues or does not vary in speed by issue type, just override
-     * {@link #getSpeed()} instead.
-     *
-     * @param issue the issue to look up the analysis speed for
-     * @return the expected speed of this detector
-     */
-    @NonNull
-    @Deprecated // Slated for removal in Lint 2.0
-    public Speed getSpeed(@SuppressWarnings("UnusedParameters") @NonNull Issue issue) {
-        // If not overridden, this detector does not distinguish speed by issue type
-        return getSpeed();
-    }
-
-    // ---- Dummy implementations to make implementing XmlScanner easier: ----
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
-        // This method must be overridden if your detector does
-        // not return something from getApplicableElements or
-        // getApplicableAttributes
-        assert false;
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        // This method must be overridden if your detector returns
-        // tag names from getApplicableElements
-        assert false;
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitElementAfter(@NonNull XmlContext context, @NonNull Element element) {
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        // This method must be overridden if your detector returns
-        // attribute names from getApplicableAttributes
-        assert false;
-    }
-
-    @SuppressWarnings("javadoc")
-    @Nullable
-    public Collection<String> getApplicableElements() {
-        return null;
-    }
-
-    @Nullable
-    @SuppressWarnings("javadoc")
-    public Collection<String> getApplicableAttributes() {
-        return null;
-    }
-
-    // ---- Dummy implementations to make implementing JavaScanner easier: ----
-
-    @Deprecated @Nullable @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public AstVisitor createJavaVisitor(@NonNull JavaContext context) {
-        return null;
-    }
-
-    @Deprecated @Nullable@SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public List<Class<? extends Node>> getApplicableNodeTypes() {
-        return null;
-    }
-
-    @Deprecated @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
-            @NonNull MethodInvocation node) {
-    }
-
-    @Deprecated @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitResourceReference(@NonNull JavaContext context, @Nullable AstVisitor visitor,
-            @NonNull Node node, @NonNull String type, @NonNull String name,
-            boolean isFramework) {
-    }
-
-    @Deprecated @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration declaration,
-            @NonNull Node node, @NonNull ResolvedClass resolvedClass) {
-    }
-
-    @Deprecated @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitConstructor(
-            @NonNull JavaContext context,
-            @Nullable AstVisitor visitor,
-            @NonNull ConstructorInvocation node,
-            @NonNull ResolvedMethod constructor) {
-    }
-
-    // ---- Dummy implementations to make implementing a ClassScanner easier: ----
-
-    @SuppressWarnings("javadoc")
-    public void checkClass(@NonNull ClassContext context, @NonNull ClassNode classNode) {
-    }
-
-    @SuppressWarnings("javadoc")
-    @Nullable
-    public List<String> getApplicableCallNames() {
-        return null;
-    }
-
-    @SuppressWarnings("javadoc")
-    @Nullable
-    public List<String> getApplicableCallOwners() {
-        return null;
-    }
-
-    @SuppressWarnings("javadoc")
-    public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode,
-            @NonNull MethodNode method, @NonNull MethodInsnNode call) {
-    }
-
-    @SuppressWarnings("javadoc")
-    @Nullable
-    public int[] getApplicableAsmNodeTypes() {
-        return null;
-    }
-
-    @SuppressWarnings("javadoc")
-    public void checkInstruction(@NonNull ClassContext context, @NonNull ClassNode classNode,
-            @NonNull MethodNode method, @NonNull AbstractInsnNode instruction) {
-    }
-
-    // ---- Dummy implementations to make implementing an OtherFileScanner easier: ----
-
-    @SuppressWarnings({"UnusedParameters", "unused"})
-    public boolean appliesToFolder(@NonNull Scope scope, @Nullable ResourceFolderType folderType) {
-        return false;
-    }
-
-    @NonNull
-    public EnumSet<Scope> getApplicableFiles() {
-        return Scope.OTHER_SCOPE;
-    }
-
-    // ---- Dummy implementations to make implementing an GradleScanner easier: ----
-
-    public void visitBuildScript(@NonNull Context context, Map<String, Object> sharedData) {
-    }
-
-    // ---- Dummy implementations to make implementing a resource folder scanner easier: ----
-
-    public void checkFolder(@NonNull ResourceContext context, @NonNull String folderName) {
-    }
-
-    // ---- Dummy implementations to make implementing a binary resource scanner easier: ----
-
-    public void checkBinaryResource(@NonNull ResourceContext context) {
-    }
-
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return true;
-    }
-
-    // ---- Dummy implementation to make implementing UastScanner easier: ----
-
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-    }
-    
-    public void visitReference(
-            @NonNull JavaContext context,
-            @Nullable UastVisitor visitor,
-            @NonNull UReferenceExpression reference,
-            @NonNull PsiElement referenced) {
-    }
-
-    public void visitConstructor(
-            @NonNull JavaContext context,
-            @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node,
-            @NonNull UMethod constructor) {
-    }
-
-    public void visitMethod(
-            @NonNull JavaContext context,
-            @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node,
-            @NonNull UMethod method) {
-    }
-
-    @Nullable
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return null;
-    }
-    
-    @Nullable
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return null;
-    }
-
-    public void visitResourceReference(
-            @NonNull JavaContext context,
-            @Nullable UastVisitor visitor,
-            @NonNull UElement node,
-            @NonNull ResourceType type,
-            @NonNull String name,
-            boolean isFramework) {
-    }
-    
-    // ---- Dummy implementation to make implementing JavaPsiScanner easier: ----
-
-    @Nullable
-    public List<String> getApplicableMethodNames() {
-        return null;
-    }
-
-    @Nullable @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public List<String> getApplicableConstructorTypes() {
-        return null;
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public boolean appliesToResourceRefs() {
-        return false;
-    }
-
-    @Nullable @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public List<String> applicableSuperClasses() {
-        return null;
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitMethod(@NonNull JavaContext context, @Nullable JavaElementVisitor visitor,
-            @NonNull PsiMethodCallExpression call, @NonNull PsiMethod method) {
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitConstructor(
-            @NonNull JavaContext context,
-            @Nullable JavaElementVisitor visitor,
-            @NonNull PsiNewExpression node,
-            @NonNull PsiMethod constructor) {
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitResourceReference(@NonNull JavaContext context,
-            @Nullable JavaElementVisitor visitor, @NonNull PsiElement node,
-            @NonNull ResourceType type, @NonNull String name, boolean isFramework) {
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void checkClass(@NonNull JavaContext context, @NonNull PsiClass declaration) {
-    }
-
-    @Nullable @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public JavaElementVisitor createPsiVisitor(@NonNull JavaContext context) {
-        return null;
-    }
-
-    @Nullable @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public List<Class<? extends PsiElement>> getApplicablePsiTypes() {
-        return null;
-    }
-
-    @Nullable @SuppressWarnings({"unused", "javadoc"})
-    public List<String> getApplicableReferenceNames() {
-        return null;
-    }
-
-    @SuppressWarnings({"UnusedParameters", "unused", "javadoc"})
-    public void visitReference(
-            @NonNull JavaContext context,
-            @Nullable JavaElementVisitor visitor,
-            @NonNull PsiJavaCodeReferenceElement reference,
-            @NonNull PsiElement referenced) {
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Implementation.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Implementation.java
deleted file mode 100644
index eb5358c..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Implementation.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.google.common.annotations.Beta;
-
-import java.util.EnumSet;
-
-/**
- * An {@linkplain Implementation} of an {@link Issue} maps to the {@link Detector}
- * class responsible for analyzing the issue, as well as the {@link Scope} required
- * by the detector to perform its analysis.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class Implementation {
-    private final Class<? extends Detector> mClass;
-    private final EnumSet<Scope> mScope;
-    private EnumSet<Scope>[] mAnalysisScopes;
-
-    @SuppressWarnings("unchecked")
-    private static final EnumSet<Scope>[] EMPTY = new EnumSet[0];
-
-    /**
-     * Creates a new implementation for analyzing one or more issues
-     *
-     * @param detectorClass the class of the detector to find this issue
-     * @param scope the scope of files required to analyze this issue
-     */
-    @SuppressWarnings("unchecked")
-    public Implementation(
-            @NonNull Class<? extends Detector> detectorClass,
-            @NonNull EnumSet<Scope> scope) {
-        this(detectorClass, scope, EMPTY);
-    }
-
-    /**
-     * Creates a new implementation for analyzing one or more issues
-     *
-     * @param detectorClass the class of the detector to find this issue
-     * @param scope the scope of files required to analyze this issue
-     * @param analysisScopes optional set of extra scopes the detector is capable of working in
-     */
-    public Implementation(
-            @NonNull Class<? extends Detector> detectorClass,
-            @NonNull EnumSet<Scope> scope,
-            @NonNull EnumSet<Scope>... analysisScopes) {
-        mClass = detectorClass;
-        mScope = scope;
-        mAnalysisScopes = analysisScopes;
-    }
-
-    /**
-     * Returns the class of the detector to use to find this issue
-     *
-     * @return the class of the detector to use to find this issue
-     */
-    @NonNull
-    public Class<? extends Detector> getDetectorClass() {
-        return mClass;
-    }
-
-    @Override
-    public String toString() {
-        return mClass.toString();
-    }
-
-    /**
-     * Returns the scope required to analyze the code to detect this issue.
-     * This is determined by the detectors which reports the issue.
-     *
-     * @return the required scope
-     */
-    @NonNull
-    public EnumSet<Scope> getScope() {
-        return mScope;
-    }
-
-    /**
-     * Returns the sets of scopes required to analyze this issue, or null if all
-     * scopes named by {@link #getScope()} are necessary. Note that only
-     * <b>one</b> match out of this collection is required, not all, and that
-     * the scope set returned by {@link #getScope()} does not have to be returned
-     * by this method, but is always implied to be included.
-     * <p>
-     * The scopes returned by {@link #getScope()} list all the various
-     * scopes that are <b>affected</b> by this issue, meaning the detector
-     * should consider it. Frequently, the detector must analyze all these
-     * scopes in order to properly decide whether an issue is found. For
-     * example, the unused resource detector needs to consider both the XML
-     * resource files and the Java source files in order to decide if a resource
-     * is unused. If it analyzes just the Java files for example, it might
-     * incorrectly conclude that a resource is unused because it did not
-     * discover a resource reference in an XML file.
-     * <p>
-     * However, there are other issues where the issue can occur in a variety of
-     * files, but the detector can consider each in isolation. For example, the
-     * API checker is affected by both XML files and Java class files (detecting
-     * both layout constructor references in XML layout files as well as code
-     * references in .class files). It doesn't have to analyze both; it is
-     * capable of incrementally analyzing just an XML file, or just a class
-     * file, without considering the other.
-     * <p>
-     * The required scope list provides a list of scope sets that can be used to
-     * analyze this issue. For each scope set, all the scopes must be matched by
-     * the incremental analysis, but any one of the scope sets can be analyzed
-     * in isolation.
-     * <p>
-     * The required scope list is not required to include the full scope set
-     * returned by {@link #getScope()}; that set is always assumed to be
-     * included.
-     * <p>
-     * NOTE: You would normally call {@link #isAdequate(EnumSet)} rather
-     * than calling this method directly.
-     *
-     * @return a list of required scopes, or null.
-     */
-    @NonNull
-    public EnumSet<Scope>[] getAnalysisScopes() {
-        return mAnalysisScopes;
-    }
-
-    /**
-     * Returns true if the given scope is adequate for analyzing this issue.
-     * This looks through the analysis scopes (see
-     * {@link #getAnalysisScopes()}) and if the scope passed in fully
-     * covers at least one of them, or if it covers the scope of the issue
-     * itself (see {@link #getScope()}, which should be a superset of all the
-     * analysis scopes) returns true.
-     * <p>
-     * The scope set returned by {@link #getScope()} lists all the various
-     * scopes that are <b>affected</b> by this issue, meaning the detector
-     * should consider it. Frequently, the detector must analyze all these
-     * scopes in order to properly decide whether an issue is found. For
-     * example, the unused resource detector needs to consider both the XML
-     * resource files and the Java source files in order to decide if a resource
-     * is unused. If it analyzes just the Java files for example, it might
-     * incorrectly conclude that a resource is unused because it did not
-     * discover a resource reference in an XML file.
-     * <p>
-     * However, there are other issues where the issue can occur in a variety of
-     * files, but the detector can consider each in isolation. For example, the
-     * API checker is affected by both XML files and Java class files (detecting
-     * both layout constructor references in XML layout files as well as code
-     * references in .class files). It doesn't have to analyze both; it is
-     * capable of incrementally analyzing just an XML file, or just a class
-     * file, without considering the other.
-     * <p>
-     * An issue can register additional scope sets that can are adequate
-     * for analyzing the issue, by supplying it to
-     * {@link #Implementation(Class, java.util.EnumSet, java.util.EnumSet[])}.
-     * This method returns true if the given scope matches one or more analysis
-     * scope, or the overall scope.
-     *
-     * @param scope the scope available for analysis
-     * @return true if this issue can be analyzed with the given available scope
-     */
-    public boolean isAdequate(@NonNull EnumSet<Scope> scope) {
-        if (scope.containsAll(mScope)) {
-            return true;
-        }
-
-        if (mAnalysisScopes != null) {
-            for (EnumSet<Scope> analysisScope : mAnalysisScopes) {
-                if (scope.containsAll(analysisScope)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Issue.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Issue.java
deleted file mode 100644
index 2427132..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Issue.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.tools.klint.detector.api.TextFormat.RAW;
-
-import com.android.annotations.NonNull;
-import com.android.tools.klint.client.api.Configuration;
-import com.google.common.annotations.Beta;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * An issue is a potential bug in an Android application. An issue is discovered
- * by a {@link Detector}, and has an associated {@link Severity}.
- * <p>
- * Issues and detectors are separate classes because a detector can discover
- * multiple different issues as it's analyzing code, and we want to be able to
- * different severities for different issues, the ability to suppress one but
- * not other issues from the same detector, and so on.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public final class Issue implements Comparable<Issue> {
-    private final String mId;
-    private final String mBriefDescription;
-    private final String mExplanation;
-    private final Category mCategory;
-    private final int mPriority;
-    private final Severity mSeverity;
-    private Object mMoreInfoUrls;
-    private boolean mEnabledByDefault = true;
-    private Implementation mImplementation;
-
-    // Use factory methods
-    private Issue(
-            @NonNull String id,
-            @NonNull String shortDescription,
-            @NonNull String explanation,
-            @NonNull Category category,
-            int priority,
-            @NonNull Severity severity,
-            @NonNull Implementation implementation) {
-        assert !shortDescription.isEmpty();
-        assert !explanation.isEmpty();
-
-        mId = id;
-        mBriefDescription = shortDescription;
-        mExplanation = explanation;
-        mCategory = category;
-        mPriority = priority;
-        mSeverity = severity;
-        mImplementation = implementation;
-    }
-
-    /**
-     * Creates a new issue. The description strings can use some simple markup;
-     * see the {@link TextFormat#RAW} documentation
-     * for details.
-     *
-     * @param id the fixed id of the issue
-     * @param briefDescription short summary (typically 5-6 words or less), typically
-     *                         describing the <b>problem</b> rather than the <b>fix</b>
-     *                         (e.g. "Missing minSdkVersion")
-     * @param explanation a full explanation of the issue, with suggestions for
-     *            how to fix it
-     * @param category the associated category, if any
-     * @param priority the priority, a number from 1 to 10 with 10 being most
-     *            important/severe
-     * @param severity the default severity of the issue
-     * @param implementation the default implementation for this issue
-     * @return a new {@link Issue}
-     */
-    @NonNull
-    public static Issue create(
-            @NonNull String id,
-            @NonNull String briefDescription,
-            @NonNull String explanation,
-            @NonNull Category category,
-            int priority,
-            @NonNull Severity severity,
-            @NonNull Implementation implementation) {
-        return new Issue(id, briefDescription, explanation, category, priority,
-                severity, implementation);
-    }
-
-    /**
-     * For compatibility with older custom rules)
-     *
-     * @deprecated Use {@link #create(String, String, String, Category, int, Severity, Implementation)} instead
-     */
-    @NonNull
-    @Deprecated
-    public static Issue create(
-            @NonNull String id,
-            @NonNull String briefDescription,
-            @SuppressWarnings("UnusedParameters") @NonNull String description,
-            @NonNull String explanation,
-            @NonNull Category category,
-            int priority,
-            @NonNull Severity severity,
-            @NonNull Implementation implementation) {
-        return new Issue(id, briefDescription, explanation, category, priority,
-                severity, implementation);
-    }
-
-    /**
-     * Returns the unique id of this issue. These should not change over time
-     * since they are used to persist the names of issues suppressed by the user
-     * etc. It is typically a single camel-cased word.
-     *
-     * @return the associated fixed id, never null and always unique
-     */
-    @NonNull
-    public String getId() {
-        return mId;
-    }
-
-    /**
-     * Briefly (in a couple of words) describes these errors
-     *
-     * @return a brief summary of the issue, never null, never empty
-     */
-    @NonNull
-    public String getBriefDescription(@NonNull TextFormat format) {
-        return RAW.convertTo(mBriefDescription, format);
-    }
-
-    /**
-     * Describes the error found by this rule, e.g.
-     * "Buttons must define contentDescriptions". Preferably the explanation
-     * should also contain a description of how the problem should be solved.
-     * Additional info can be provided via {@link #getMoreInfo()}.
-     *
-     * @param format the format to write the format as
-     * @return an explanation of the issue, never null, never empty
-     */
-    @NonNull
-    public String getExplanation(@NonNull TextFormat format) {
-        return RAW.convertTo(mExplanation, format);
-    }
-
-    /**
-     * The primary category of the issue
-     *
-     * @return the primary category of the issue, never null
-     */
-    @NonNull
-    public Category getCategory() {
-        return mCategory;
-    }
-
-    /**
-     * Returns a priority, in the range 1-10, with 10 being the most severe and
-     * 1 the least
-     *
-     * @return a priority from 1 to 10
-     */
-    public int getPriority() {
-        return mPriority;
-    }
-
-    /**
-     * Returns the default severity of the issues found by this detector (some
-     * tools may allow the user to specify custom severities for detectors).
-     * <p>
-     * Note that even though the normal way for an issue to be disabled is for
-     * the {@link Configuration} to return {@link Severity#IGNORE}, there is a
-     * {@link #isEnabledByDefault()} method which can be used to turn off issues
-     * by default. This is done rather than just having the severity as the only
-     * attribute on the issue such that an issue can be configured with an
-     * appropriate severity (such as {@link Severity#ERROR}) even when issues
-     * are disabled by default for example because they are experimental or not
-     * yet stable.
-     *
-     * @return the severity of the issues found by this detector
-     */
-    @NonNull
-    public Severity getDefaultSeverity() {
-        return mSeverity;
-    }
-
-    /**
-     * Returns a link (a URL string) to more information, or null
-     *
-     * @return a link to more information, or null
-     */
-    @NonNull
-    public List<String> getMoreInfo() {
-        if (mMoreInfoUrls == null) {
-            return Collections.emptyList();
-        } else if (mMoreInfoUrls instanceof String) {
-            return Collections.singletonList((String) mMoreInfoUrls);
-        } else {
-            assert mMoreInfoUrls instanceof List;
-            //noinspection unchecked
-            return (List<String>) mMoreInfoUrls;
-        }
-    }
-
-    /**
-     * Adds a more info URL string
-     *
-     * @param moreInfoUrl url string
-     * @return this, for constructor chaining
-     */
-    @NonNull
-    public Issue addMoreInfo(@NonNull String moreInfoUrl) {
-        // Nearly all issues supply at most a single URL, so don't bother with
-        // lists wrappers for most of these issues
-        if (mMoreInfoUrls == null) {
-            mMoreInfoUrls = moreInfoUrl;
-        } else if (mMoreInfoUrls instanceof String) {
-            String existing = (String) mMoreInfoUrls;
-            List<String> list = new ArrayList<String>(2);
-            list.add(existing);
-            list.add(moreInfoUrl);
-            mMoreInfoUrls = list;
-        } else {
-            assert mMoreInfoUrls instanceof List;
-            //noinspection unchecked
-            ((List<String>) mMoreInfoUrls).add(moreInfoUrl);
-        }
-        return this;
-    }
-
-    /**
-     * Returns whether this issue should be enabled by default, unless the user
-     * has explicitly disabled it.
-     *
-     * @return true if this issue should be enabled by default
-     */
-    public boolean isEnabledByDefault() {
-        return mEnabledByDefault;
-    }
-
-    /**
-     * Returns the implementation for the given issue
-     *
-     * @return the implementation for this issue
-     */
-    @NonNull
-    public Implementation getImplementation() {
-        return mImplementation;
-    }
-
-    /**
-     * Sets the implementation for the given issue. This is typically done by
-     * IDEs that can offer a replacement for a given issue which performs better
-     * or in some other way works better within the IDE.
-     *
-     * @param implementation the new implementation to use
-     */
-    public void setImplementation(@NonNull Implementation implementation) {
-        mImplementation = implementation;
-    }
-
-    /**
-     * Sorts the detectors alphabetically by id. This is intended to make it
-     * convenient to store settings for detectors in a fixed order. It is not
-     * intended as the order to be shown to the user; for that, a tool embedding
-     * lint might consider the priorities, categories, severities etc of the
-     * various detectors.
-     *
-     * @param other the {@link Issue} to compare this issue to
-     */
-    @Override
-    public int compareTo(@NonNull Issue other) {
-        return getId().compareTo(other.getId());
-    }
-
-    /**
-     * Sets whether this issue is enabled by default.
-     *
-     * @param enabledByDefault whether the issue should be enabled by default
-     * @return this, for constructor chaining
-     */
-    @NonNull
-    public Issue setEnabledByDefault(boolean enabledByDefault) {
-        mEnabledByDefault = enabledByDefault;
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        return mId;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/JavaContext.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/JavaContext.java
deleted file mode 100644
index 4dd1b93..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/JavaContext.java
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.JavaParser;
-import com.android.tools.klint.client.api.JavaParser.ResolvedClass;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.containers.ContainerUtil;
-import lombok.ast.*;
-import lombok.ast.Position;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.psi.UElementWithLocation;
-
-import java.io.File;
-import java.util.Iterator;
-
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.tools.klint.client.api.JavaParser.ResolvedNode;
-import static com.android.tools.klint.client.api.JavaParser.TypeDescriptor;
-
-/**
- * A {@link Context} used when checking Java files.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-public class JavaContext extends Context {
-    static final String SUPPRESS_COMMENT_PREFIX = "//noinspection "; //$NON-NLS-1$
-
-    /**
-     * The parse tree
-     *
-     * @deprecated Use {@link #mJavaFile} instead (see {@link JavaPsiScanner})
-     */
-    @Deprecated
-    private Node mCompilationUnit;
-
-    /** The parse tree */
-    private PsiJavaFile mJavaFile;
-    
-    private UFile mUFile;
-
-    /** The parser which produced the parse tree */
-    private final JavaParser mParser;
-
-    /**
-     * Constructs a {@link JavaContext} for running lint on the given file, with
-     * the given scope, in the given project reporting errors to the given
-     * client.
-     *
-     * @param driver the driver running through the checks
-     * @param project the project to run lint on which contains the given file
-     * @param main the main project if this project is a library project, or
-     *            null if this is not a library project. The main project is
-     *            the root project of all library projects, not necessarily the
-     *            directly including project.
-     * @param file the file to be analyzed
-     * @param parser the parser to use
-     */
-    public JavaContext(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File file,
-            @NonNull JavaParser parser) {
-        super(driver, project, main, file);
-        mParser = parser;
-    }
-    
-    @NonNull
-    public UastContext getUastContext() {
-        return mParser.getUastContext();
-    }
-    
-    /**
-     * Returns a location for the given node
-     *
-     * @param node the AST node to get a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getLocation(@NonNull Node node) {
-        return mParser.getLocation(this, node);
-    }
-
-    /**
-     * Returns a location for the given node range (from the starting offset of the first node to
-     * the ending offset of the second node).
-     *
-     * @param from      the AST node to get a starting location from
-     * @param fromDelta Offset delta to apply to the starting offset
-     * @param to        the AST node to get a ending location from
-     * @param toDelta   Offset delta to apply to the ending offset
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getRangeLocation(
-            @NonNull Node from,
-            int fromDelta,
-            @NonNull Node to,
-            int toDelta) {
-        return mParser.getRangeLocation(this, from, fromDelta, to, toDelta);
-    }
-
-    /**
-     * Returns a location for the given node range (from the starting offset of the first node to
-     * the ending offset of the second node).
-     *
-     * @param from      the AST node to get a starting location from
-     * @param fromDelta Offset delta to apply to the starting offset
-     * @param to        the AST node to get a ending location from
-     * @param toDelta   Offset delta to apply to the ending offset
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getRangeLocation(
-            @NonNull PsiElement from,
-            int fromDelta,
-            @NonNull PsiElement to,
-            int toDelta) {
-        return mParser.getRangeLocation(this, from, fromDelta, to, toDelta);
-    }
-
-    /**
-     * Returns a {@link Location} for the given node. This attempts to pick a shorter
-     * location range than the entire node; for a class or method for example, it picks
-     * the name node (if found). For statement constructs such as a {@code switch} statement
-     * it will highlight the keyword, etc.
-     *
-     * @param node the AST node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getNameLocation(@NonNull Node node) {
-        return mParser.getNameLocation(this, node);
-    }
-
-    /**
-     * Returns a {@link Location} for the given node. This attempts to pick a shorter
-     * location range than the entire node; for a class or method for example, it picks
-     * the name node (if found). For statement constructs such as a {@code switch} statement
-     * it will highlight the keyword, etc.
-     *
-     * @param element the AST node to create a location for
-     * @return a location for the given node
-     */
-    @NonNull
-    public Location getNameLocation(@NonNull PsiElement element) {
-        if (element instanceof PsiSwitchStatement) {
-            // Just use keyword
-            return mParser.getRangeLocation(this, element, 0, 6); // 6: "switch".length()
-        }
-        return mParser.getNameLocation(this, element);
-    }
-
-    @NonNull
-    public Location getUastNameLocation(@NonNull UElement element) {
-        if (element instanceof UDeclaration) {
-            UElement nameIdentifier = ((UDeclaration) element).getUastAnchor();
-            if (nameIdentifier != null) {
-                return getUastLocation(nameIdentifier);
-            }
-        } else if (element instanceof PsiNameIdentifierOwner) {
-            PsiElement nameIdentifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
-            if (nameIdentifier != null) {
-                return getLocation(nameIdentifier);
-            }
-        } else if (element instanceof UCallExpression) {
-            UElement methodReference = ((UCallExpression) element).getMethodIdentifier();
-            if (methodReference != null) {
-                return getUastLocation(methodReference);
-            }
-        }
-        
-        return getUastLocation(element);
-    }
-
-    @NonNull
-    public Location getLocation(@NonNull PsiElement node) {
-        return mParser.getLocation(this, node);
-    }
-    
-    @NonNull
-    public Location getUastLocation(@Nullable UElement node) {
-        if (node == null) {
-            return Location.NONE;
-        }
-
-        if (node instanceof UElementWithLocation) {
-            UFile file = UastUtils.getContainingFile(node);
-            if (file == null) {
-                return Location.NONE;
-            }
-            File ioFile = UastUtils.getIoFile(file);
-            if (ioFile == null) {
-                return Location.NONE;
-            }
-            UElementWithLocation segment = (UElementWithLocation) node;
-            return Location.create(ioFile, file.getPsi().getText(),
-                    segment.getStartOffset(), segment.getEndOffset());
-        } else {
-            PsiElement psiElement = node.getPsi();
-            if (psiElement != null) {
-                TextRange range = psiElement.getTextRange();
-                UFile containingFile = getUFile();
-                if (containingFile == null) {
-                    return Location.NONE;
-                }
-                File file = this.file;
-                if (!containingFile.equals(getUFile())) {
-                    // Reporting an error in a different file.
-                    if (getDriver().getScope().size() == 1) {
-                        // Don't bother with this error if it's in a different file during single-file analysis
-                        return Location.NONE;
-                    }
-                    VirtualFile virtualFile = containingFile.getPsi().getVirtualFile();
-                    if (virtualFile == null) {
-                        return Location.NONE;
-                    }
-                    file = VfsUtilCore.virtualToIoFile(virtualFile);
-                }
-                return Location.create(file, getContents(), range.getStartOffset(),
-                        range.getEndOffset());
-            }
-        }
-        
-        return Location.NONE;
-    }
-
-    @NonNull
-    public JavaParser getParser() {
-        return mParser;
-    }
-
-    @NonNull
-    public JavaEvaluator getEvaluator() {
-        return mParser.getEvaluator();
-    }
-
-    @Nullable
-    public Node getCompilationUnit() {
-        return mCompilationUnit;
-    }
-
-    /**
-     * Sets the compilation result. Not intended for client usage; the lint infrastructure
-     * will set this when a context has been processed
-     *
-     * @param compilationUnit the parse tree
-     */
-    public void setCompilationUnit(@Nullable Node compilationUnit) {
-        mCompilationUnit = compilationUnit;
-    }
-    
-    /**
-     * Returns the {@link UFile}.
-     * 
-     * @return the parsed UFile
-     */
-    @Nullable
-    public UFile getUFile() {
-        return mUFile;
-    }
-
-    /**
-     * Sets the compilation result. Not intended for client usage; the lint infrastructure
-     * will set this when a context has been processed
-     *
-     * @param javaFile the parse tree
-     */
-    public void setJavaFile(@Nullable PsiJavaFile javaFile) {
-        mJavaFile = javaFile;
-    }
-    
-    public void setUFile(@Nullable UFile file) {
-        mUFile = file;
-    }
-
-    @Override
-    public void report(@NonNull Issue issue, @NonNull Location location,
-            @NonNull String message) {
-        if (mDriver.isSuppressed(this, issue, mCompilationUnit)) {
-            return;
-        }
-        super.report(issue, location, message);
-    }
-
-    /**
-     * Reports an issue applicable to a given AST node. The AST node is used as the
-     * scope to check for suppress lint annotations.
-     *
-     * @param issue the issue to report
-     * @param scope the AST node scope the error applies to. The lint infrastructure
-     *    will check whether there are suppress annotations on this node (or its enclosing
-     *    nodes) and if so suppress the warning without involving the client.
-     * @param location the location of the issue, or null if not known
-     * @param message the message for this warning
-     */
-    public void report(
-            @NonNull Issue issue,
-            @Nullable Node scope,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (scope != null && mDriver.isSuppressed(this, issue, scope)) {
-            return;
-        }
-        super.report(issue, location, message);
-    }
-
-    public void report(
-            @NonNull Issue issue,
-            @Nullable PsiElement scope,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (scope != null && mDriver.isSuppressed(this, issue, scope)) {
-            return;
-        }
-        super.report(issue, location, message);
-    }
-
-    public void report(
-            @NonNull Issue issue,
-            @Nullable UElement scope,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (scope != null && mDriver.isSuppressed(this, issue, scope)) {
-            return;
-        }
-        super.report(issue, location, message);
-    }
-
-    /** UDeclaration is a PsiElement, so it's impossible to call report(Issue, UElement, ...)
-     *  without an explicit cast. */
-    public void reportUast(
-            @NonNull Issue issue,
-            @Nullable UElement scope,
-            @NonNull Location location,
-            @NonNull String message) {
-        report(issue, scope, location, message);
-    }
-
-    /**
-     * Report an error.
-     * Like {@link #report(Issue, Node, Location, String)} but with
-     * a now-unused data parameter at the end.
-     *
-     * @deprecated Use {@link #report(Issue, Node, Location, String)} instead;
-     *    this method is here for custom rule compatibility
-     */
-    @SuppressWarnings("UnusedDeclaration") // Potentially used by external existing custom rules
-    @Deprecated
-    public void report(
-            @NonNull Issue issue,
-            @Nullable Node scope,
-            @NonNull Location location,
-            @NonNull String message,
-            @SuppressWarnings("UnusedParameters") @Nullable Object data) {
-        report(issue, scope, location, message);
-    }
-
-    /**
-     * @deprecated Use {@link PsiTreeUtil#getParentOfType(PsiElement, Class[])}
-     * with PsiMethod.class instead
-     */
-    @Deprecated
-    @Nullable
-    public static Node findSurroundingMethod(Node scope) {
-        while (scope != null) {
-            Class<? extends Node> type = scope.getClass();
-            // The Lombok AST uses a flat hierarchy of node type implementation classes
-            // so no need to do instanceof stuff here.
-            if (type == MethodDeclaration.class || type == ConstructorDeclaration.class) {
-                return scope;
-            }
-
-            scope = scope.getParent();
-        }
-
-        return null;
-    }
-
-    /**
-     * @deprecated Use {@link PsiTreeUtil#getParentOfType(PsiElement, Class[])}
-     * with PsiMethod.class instead
-     */
-    @Deprecated
-    @Nullable
-    public static ClassDeclaration findSurroundingClass(@Nullable Node scope) {
-        while (scope != null) {
-            Class<? extends Node> type = scope.getClass();
-            // The Lombok AST uses a flat hierarchy of node type implementation classes
-            // so no need to do instanceof stuff here.
-            if (type == ClassDeclaration.class) {
-                return (ClassDeclaration) scope;
-            }
-
-            scope = scope.getParent();
-        }
-
-        return null;
-    }
-
-    @Override
-    @Nullable
-    protected String getSuppressCommentPrefix() {
-        return SUPPRESS_COMMENT_PREFIX;
-    }
-
-    /**
-     * @deprecated Use {@link #isSuppressedWithComment(PsiElement, Issue)} instead
-     */
-    @Deprecated
-    public boolean isSuppressedWithComment(@NonNull Node scope, @NonNull Issue issue) {
-        // Check whether there is a comment marker
-        String contents = getContents();
-        assert contents != null; // otherwise we wouldn't be here
-        Position position = scope.getPosition();
-        if (position == null) {
-            return false;
-        }
-
-        int start = position.getStart();
-        return isSuppressedWithComment(start, issue);
-    }
-
-    public boolean isSuppressedWithComment(@NonNull UElement scope, @NonNull Issue issue) {
-        PsiElement psi = scope.getPsi();
-        return psi != null && isSuppressedWithComment(psi, issue);
-
-    }
-    
-    public boolean isSuppressedWithComment(@NonNull PsiElement scope, @NonNull Issue issue) {
-        // Check whether there is a comment marker
-        String contents = getContents();
-        assert contents != null; // otherwise we wouldn't be here
-        TextRange textRange = scope.getTextRange();
-        if (textRange == null) {
-            return false;
-        }
-        int start = textRange.getStartOffset();
-        return isSuppressedWithComment(start, issue);
-    }
-
-    /**
-     * @deprecated Location handles aren't needed for AST nodes anymore; just use the
-     * {@link PsiElement} from the AST
-     */
-    @Deprecated
-    @NonNull
-    public Location.Handle createLocationHandle(@NonNull Node node) {
-        return mParser.createLocationHandle(this, node);
-    }
-
-    /**
-     * @deprecated Use PsiElement resolve methods (varies by AST node type, e.g.
-     * {@link PsiMethodCallExpression#resolveMethod()}
-     */
-    @Deprecated
-    @Nullable
-    public ResolvedNode resolve(@NonNull Node node) {
-        return mParser.resolve(this, node);
-    }
-
-    /**
-     * @deprecated Use {@link JavaEvaluator#findClass(String)} instead
-     */
-    @Deprecated
-    @Nullable
-    public ResolvedClass findClass(@NonNull String fullyQualifiedName) {
-        return mParser.findClass(this, fullyQualifiedName);
-    }
-
-    /**
-     * @deprecated Use {@link PsiExpression#getType()} )} instead
-     */
-    @Deprecated
-    @Nullable
-    public TypeDescriptor getType(@NonNull Node node) {
-        return mParser.getType(this, node);
-    }
-
-    /**
-     * @deprecated Use {@link #getMethodName(PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static String getMethodName(@NonNull Node call) {
-        if (call instanceof MethodInvocation) {
-            return ((MethodInvocation)call).astName().astValue();
-        } else if (call instanceof ConstructorInvocation) {
-            return ((ConstructorInvocation)call).astTypeReference().getTypeName();
-        } else if (call instanceof EnumConstant) {
-            return ((EnumConstant)call).astName().astValue();
-        } else {
-            return null;
-        }
-    }
-
-    @Nullable
-    public static String getMethodName(@NonNull PsiElement call) {
-        if (call instanceof PsiMethodCallExpression) {
-            return ((PsiMethodCallExpression)call).getMethodExpression().getReferenceName();
-        } else if (call instanceof PsiNewExpression) {
-            PsiJavaCodeReferenceElement classReference = ((PsiNewExpression) call).getClassReference();
-            if (classReference != null) {
-                return classReference.getReferenceName();
-            } else {
-                return null;
-            }
-        } else if (call instanceof PsiEnumConstant) {
-            return ((PsiEnumConstant)call).getName();
-        } else {
-            return null;
-        }
-    }
-
-    @Nullable
-    public static String getMethodName(@NonNull UElement call) {
-        if (call instanceof UEnumConstant) {
-            return ((UEnumConstant)call).getName();
-        } else if (call instanceof UCallExpression) {
-            String methodName = ((UCallExpression) call).getMethodName();
-            if (methodName != null) {
-                return methodName;
-            } else {
-                return UastUtils.getQualifiedName(((UCallExpression) call).getClassReference());
-            }
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Searches for a name node corresponding to the given node
-     * @return the name node to use, if applicable
-     * @deprecated Use {@link #findNameElement(PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static Node findNameNode(@NonNull Node node) {
-        if (node instanceof TypeDeclaration) {
-            // ClassDeclaration, AnnotationDeclaration, EnumDeclaration, InterfaceDeclaration
-            return ((TypeDeclaration) node).astName();
-        } else if (node instanceof MethodDeclaration) {
-            return ((MethodDeclaration)node).astMethodName();
-        } else if (node instanceof ConstructorDeclaration) {
-            return ((ConstructorDeclaration)node).astTypeName();
-        } else if (node instanceof MethodInvocation) {
-            return ((MethodInvocation)node).astName();
-        } else if (node instanceof ConstructorInvocation) {
-            return ((ConstructorInvocation)node).astTypeReference();
-        } else if (node instanceof EnumConstant) {
-            return ((EnumConstant)node).astName();
-        } else if (node instanceof AnnotationElement) {
-            return ((AnnotationElement)node).astName();
-        } else if (node instanceof AnnotationMethodDeclaration) {
-            return ((AnnotationMethodDeclaration)node).astMethodName();
-        } else if (node instanceof VariableReference) {
-            return ((VariableReference)node).astIdentifier();
-        } else if (node instanceof LabelledStatement) {
-            return ((LabelledStatement)node).astLabel();
-        }
-
-        return null;
-    }
-
-    /**
-     * Searches for a name node corresponding to the given node
-     * @return the name node to use, if applicable
-     */
-    @Nullable
-    public static PsiElement findNameElement(@NonNull PsiElement element) {
-        if (element instanceof PsiClass) {
-            if (element instanceof PsiAnonymousClass) {
-                return ((PsiAnonymousClass)element).getBaseClassReference();
-            }
-            return ((PsiClass) element).getNameIdentifier();
-        } else if (element instanceof PsiMethod) {
-            return ((PsiMethod) element).getNameIdentifier();
-        } else if (element instanceof PsiMethodCallExpression) {
-            return ((PsiMethodCallExpression) element).getMethodExpression().
-                    getReferenceNameElement();
-        } else if (element instanceof PsiNewExpression) {
-            return ((PsiNewExpression) element).getClassReference();
-        } else if (element instanceof PsiField) {
-            return ((PsiField)element).getNameIdentifier();
-        } else if (element instanceof PsiAnnotation) {
-            return ((PsiAnnotation)element).getNameReferenceElement();
-        } else if (element instanceof PsiReferenceExpression) {
-            return ((PsiReferenceExpression) element).getReferenceNameElement();
-        } else if (element instanceof PsiLabeledStatement) {
-            return ((PsiLabeledStatement)element).getLabelIdentifier();
-        }
-
-        return null;
-    }
-
-    @Deprecated
-    @NonNull
-    public static Iterator<Expression> getParameters(@NonNull Node call) {
-        if (call instanceof MethodInvocation) {
-            return ((MethodInvocation) call).astArguments().iterator();
-        } else if (call instanceof ConstructorInvocation) {
-            return ((ConstructorInvocation) call).astArguments().iterator();
-        } else if (call instanceof EnumConstant) {
-            return ((EnumConstant) call).astArguments().iterator();
-        } else {
-            return ContainerUtil.emptyIterator();
-        }
-    }
-
-    @Deprecated
-    @Nullable
-    public static Node getParameter(@NonNull Node call, int parameter) {
-        Iterator<Expression> iterator = getParameters(call);
-
-        for (int i = 0; i < parameter - 1; i++) {
-            if (!iterator.hasNext()) {
-                return null;
-            }
-            iterator.next();
-        }
-        return iterator.hasNext() ? iterator.next() : null;
-    }
-
-    /**
-     * Returns true if the given method invocation node corresponds to a call on a
-     * {@code android.content.Context}
-     *
-     * @param node the method call node
-     * @return true iff the method call is on a class extending context
-     * @deprecated use {@link JavaEvaluator#isMemberInSubClassOf(PsiMember, String, boolean)} instead
-     */
-    @Deprecated
-    public boolean isContextMethod(@NonNull MethodInvocation node) {
-        // Method name used in many other contexts where it doesn't have the
-        // same semantics; only use this one if we can resolve types
-        // and we're certain this is the Context method
-        ResolvedNode resolved = resolve(node);
-        if (resolved instanceof JavaParser.ResolvedMethod) {
-            JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolved;
-            ResolvedClass containingClass = method.getContainingClass();
-            if (containingClass.isSubclassOf(CLASS_CONTEXT, false)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the first ancestor node of the given type
-     *
-     * @param element the element to search from
-     * @param clz     the target node type
-     * @param <T>     the target node type
-     * @return the nearest ancestor node in the parent chain, or null if not found
-     * @deprecated Use {@link PsiTreeUtil#getParentOfType} instead
-     */
-    @Deprecated
-    @Nullable
-    public static <T extends Node> T getParentOfType(
-            @Nullable Node element,
-            @NonNull Class<T> clz) {
-        return getParentOfType(element, clz, true);
-    }
-
-    /**
-     * Returns the first ancestor node of the given type
-     *
-     * @param element the element to search from
-     * @param clz     the target node type
-     * @param strict  if true, do not consider the element itself, only its parents
-     * @param <T>     the target node type
-     * @return the nearest ancestor node in the parent chain, or null if not found
-     * @deprecated Use {@link PsiTreeUtil#getParentOfType} instead
-     */
-    @Deprecated
-    @Nullable
-    public static <T extends Node> T getParentOfType(
-            @Nullable Node element,
-            @NonNull Class<T> clz,
-            boolean strict) {
-        if (element == null) {
-            return null;
-        }
-
-        if (strict) {
-            element = element.getParent();
-        }
-
-        while (element != null) {
-            if (clz.isInstance(element)) {
-                //noinspection unchecked
-                return (T) element;
-            }
-            element = element.getParent();
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the first ancestor node of the given type, stopping at the given type
-     *
-     * @param element     the element to search from
-     * @param clz         the target node type
-     * @param strict      if true, do not consider the element itself, only its parents
-     * @param terminators optional node types to terminate the search at
-     * @param <T>         the target node type
-     * @return the nearest ancestor node in the parent chain, or null if not found
-     * @deprecated Use {@link PsiTreeUtil#getParentOfType} instead
-     */
-    @Deprecated
-    @Nullable
-    public static <T extends Node> T getParentOfType(@Nullable Node element,
-            @NonNull Class<T> clz,
-            boolean strict,
-            @NonNull Class<? extends Node>... terminators) {
-        if (element == null) {
-            return null;
-        }
-        if (strict) {
-            element = element.getParent();
-        }
-
-        while (element != null && !clz.isInstance(element)) {
-            for (Class<?> terminator : terminators) {
-                if (terminator.isInstance(element)) {
-                    return null;
-                }
-            }
-            element = element.getParent();
-        }
-
-        //noinspection unchecked
-        return (T) element;
-    }
-
-    /**
-     * Returns the first sibling of the given node that is of the given class
-     *
-     * @param sibling the sibling to search from
-     * @param clz     the type to look for
-     * @param <T>     the type
-     * @return the first sibling of the given type, or null
-     * @deprecated Use {@link PsiTreeUtil#getNextSiblingOfType(PsiElement, Class)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static <T extends Node> T getNextSiblingOfType(@Nullable Node sibling,
-            @NonNull Class<T> clz) {
-        if (sibling == null) {
-            return null;
-        }
-        Node parent = sibling.getParent();
-        if (parent == null) {
-            return null;
-        }
-
-        Iterator<Node> iterator = parent.getChildren().iterator();
-        while (iterator.hasNext()) {
-            if (iterator.next() == sibling) {
-                break;
-            }
-        }
-
-        while (iterator.hasNext()) {
-            Node child = iterator.next();
-            if (clz.isInstance(child)) {
-                //noinspection unchecked
-                return (T) child;
-            }
-
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Returns the given argument of the given call
-     *
-     * @param call the call containing arguments
-     * @param index the index of the target argument
-     * @return the argument at the given index
-     * @throws IllegalArgumentException if index is outside the valid range
-     */
-    @Deprecated
-    @NonNull
-    public static Node getArgumentNode(@NonNull MethodInvocation call, int index) {
-        int i = 0;
-        for (Expression parameter : call.astArguments()) {
-            if (i == index) {
-                return parameter;
-            }
-            i++;
-        }
-        throw new IllegalArgumentException(Integer.toString(index));
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LayoutDetector.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LayoutDetector.java
deleted file mode 100644
index ce1b8b2..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LayoutDetector.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
-import static com.android.SdkConstants.ATTR_PADDING;
-import static com.android.SdkConstants.ATTR_PADDING_BOTTOM;
-import static com.android.SdkConstants.ATTR_PADDING_LEFT;
-import static com.android.SdkConstants.ATTR_PADDING_RIGHT;
-import static com.android.SdkConstants.ATTR_PADDING_TOP;
-import static com.android.SdkConstants.VALUE_FILL_PARENT;
-import static com.android.SdkConstants.VALUE_MATCH_PARENT;
-
-import com.android.annotations.NonNull;
-import com.android.resources.ResourceFolderType;
-import com.google.common.annotations.Beta;
-
-import org.w3c.dom.Element;
-
-/**
- * Abstract class specifically intended for layout detectors which provides some
- * common utility methods shared by layout detectors.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class LayoutDetector extends ResourceXmlDetector {
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.LAYOUT;
-    }
-
-    private static boolean isFillParent(@NonNull Element element, @NonNull String dimension) {
-        String width = element.getAttributeNS(ANDROID_URI, dimension);
-        return width.equals(VALUE_MATCH_PARENT) || width.equals(VALUE_FILL_PARENT);
-    }
-
-    protected static boolean isWidthFillParent(@NonNull Element element) {
-        return isFillParent(element, ATTR_LAYOUT_WIDTH);
-    }
-
-    protected static boolean isHeightFillParent(@NonNull Element element) {
-        return isFillParent(element, ATTR_LAYOUT_HEIGHT);
-    }
-
-    protected boolean hasPadding(@NonNull Element root) {
-        return root.hasAttributeNS(ANDROID_URI, ATTR_PADDING)
-                || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_LEFT)
-                || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_RIGHT)
-                || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_TOP)
-                || root.hasAttributeNS(ANDROID_URI, ATTR_PADDING_BOTTOM);
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LintUtils.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LintUtils.java
deleted file mode 100644
index a0ced7f..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/LintUtils.java
+++ /dev/null
@@ -1,1343 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.AndroidProject;
-import com.android.builder.model.ApiVersion;
-import com.android.ide.common.rendering.api.ItemResourceValue;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceUrl;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.LocaleQualifier;
-import com.android.resources.FolderTypeRelationship;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkVersionInfo;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.utils.PositionXmlParser;
-import com.android.utils.SdkUtils;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.intellij.psi.*;
-import lombok.ast.ImportDeclaration;
-import org.jetbrains.org.objectweb.asm.Opcodes;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.FieldNode;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UParenthesizedExpression;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import static com.android.SdkConstants.*;
-import static com.android.ide.common.resources.configuration.FolderConfiguration.QUALIFIER_SPLITTER;
-import static com.android.ide.common.resources.configuration.LocaleQualifier.BCP_47_PREFIX;
-import static com.android.tools.klint.client.api.JavaParser.*;
-
-
-/**
- * Useful utility methods related to lint.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class LintUtils {
-    // Utility class, do not instantiate
-    private LintUtils() {
-    }
-
-    /**
-     * Format a list of strings, and cut of the list at {@code maxItems} if the
-     * number of items are greater.
-     *
-     * @param strings the list of strings to print out as a comma separated list
-     * @param maxItems the maximum number of items to print
-     * @return a comma separated list
-     */
-    @NonNull
-    public static String formatList(@NonNull List<String> strings, int maxItems) {
-        StringBuilder sb = new StringBuilder(20 * strings.size());
-
-        for (int i = 0, n = strings.size(); i < n; i++) {
-            if (sb.length() > 0) {
-                sb.append(", "); //$NON-NLS-1$
-            }
-            sb.append(strings.get(i));
-
-            if (maxItems > 0 && i == maxItems - 1 && n > maxItems) {
-                sb.append(String.format("... (%1$d more)", n - i - 1));
-                break;
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Determine if the given type corresponds to a resource that has a unique
-     * file
-     *
-     * @param type the resource type to check
-     * @return true if the given type corresponds to a file-type resource
-     */
-    public static boolean isFileBasedResourceType(@NonNull ResourceType type) {
-        List<ResourceFolderType> folderTypes = FolderTypeRelationship.getRelatedFolders(type);
-        for (ResourceFolderType folderType : folderTypes) {
-            if (folderType != ResourceFolderType.VALUES) {
-                return type != ResourceType.ID;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the given file represents an XML file
-     *
-     * @param file the file to be checked
-     * @return true if the given file is an xml file
-     */
-    public static boolean isXmlFile(@NonNull File file) {
-        return SdkUtils.endsWithIgnoreCase(file.getPath(), DOT_XML);
-    }
-
-    /**
-     * Returns true if the given file represents a bitmap drawable file
-     *
-     * @param file the file to be checked
-     * @return true if the given file is an xml file
-     */
-    public static boolean isBitmapFile(@NonNull File file) {
-        String path = file.getPath();
-        // endsWith(name, DOT_PNG) is also true for endsWith(name, DOT_9PNG)
-        return endsWith(path, DOT_PNG)
-                || endsWith(path, DOT_JPG)
-                || endsWith(path, DOT_GIF)
-                || endsWith(path, DOT_JPEG)
-                || endsWith(path, DOT_WEBP);
-    }
-
-    /**
-     * Case insensitive ends with
-     *
-     * @param string the string to be tested whether it ends with the given
-     *            suffix
-     * @param suffix the suffix to check
-     * @return true if {@code string} ends with {@code suffix},
-     *         case-insensitively.
-     */
-    public static boolean endsWith(@NonNull String string, @NonNull String suffix) {
-        return string.regionMatches(true /* ignoreCase */, string.length() - suffix.length(),
-                suffix, 0, suffix.length());
-    }
-
-    /**
-     * Case insensitive starts with
-     *
-     * @param string the string to be tested whether it starts with the given prefix
-     * @param prefix the prefix to check
-     * @param offset the offset to start checking with
-     * @return true if {@code string} starts with {@code prefix},
-     *         case-insensitively.
-     */
-    public static boolean startsWith(@NonNull String string, @NonNull String prefix, int offset) {
-        return string.regionMatches(true /* ignoreCase */, offset, prefix, 0, prefix.length());
-    }
-
-    /**
-     * Returns the basename of the given filename, unless it's a dot-file such as ".svn".
-     *
-     * @param fileName the file name to extract the basename from
-     * @return the basename (the filename without the file extension)
-     */
-    public static String getBaseName(@NonNull String fileName) {
-        int extension = fileName.indexOf('.');
-        if (extension > 0) {
-            return fileName.substring(0, extension);
-        } else {
-            return fileName;
-        }
-    }
-
-    /**
-     * Returns the children elements of the given node
-     *
-     * @param node the parent node
-     * @return a list of element children, never null
-     */
-    @NonNull
-    public static List<Element> getChildren(@NonNull Node node) {
-        NodeList childNodes = node.getChildNodes();
-        List<Element> children = new ArrayList<Element>(childNodes.getLength());
-        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                children.add((Element) child);
-            }
-        }
-
-        return children;
-    }
-
-    /**
-     * Returns the <b>number</b> of children of the given node
-     *
-     * @param node the parent node
-     * @return the count of element children
-     */
-    public static int getChildCount(@NonNull Node node) {
-        NodeList childNodes = node.getChildNodes();
-        int childCount = 0;
-        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                childCount++;
-            }
-        }
-
-        return childCount;
-    }
-
-    /**
-     * Returns true if the given element is the root element of its document
-     *
-     * @param element the element to test
-     * @return true if the element is the root element
-     */
-    public static boolean isRootElement(Element element) {
-        return element == element.getOwnerDocument().getDocumentElement();
-    }
-
-    /**
-     * Returns the corresponding R field name for the given XML resource name
-     * @param styleName the XML name
-     * @return the corresponding R field name
-     */
-    public static String getFieldName(@NonNull String styleName) {
-        for (int i = 0, n = styleName.length(); i < n; i++) {
-            char c = styleName.charAt(i);
-            if (c == '.' || c == '-' || c == ':') {
-                return styleName.replace('.', '_').replace('-', '_').replace(':', '_');
-            }
-        }
-
-        return styleName;
-    }
-
-    /**
-     * Returns the given id without an {@code @id/} or {@code @+id} prefix
-     *
-     * @param id the id to strip
-     * @return the stripped id, never null
-     */
-    @NonNull
-    public static String stripIdPrefix(@Nullable String id) {
-        if (id == null) {
-            return "";
-        } else if (id.startsWith(NEW_ID_PREFIX)) {
-            return id.substring(NEW_ID_PREFIX.length());
-        } else if (id.startsWith(ID_PREFIX)) {
-            return id.substring(ID_PREFIX.length());
-        }
-
-        return id;
-    }
-
-    /**
-     * Returns true if the given two id references match. This is similar to
-     * String equality, but it also considers "{@code @+id/foo == @id/foo}.
-     *
-     * @param id1 the first id to compare
-     * @param id2 the second id to compare
-     * @return true if the two id references refer to the same id
-     */
-    public static boolean idReferencesMatch(@Nullable String id1, @Nullable String id2) {
-        if (id1 == null || id2 == null || id1.isEmpty() || id2.isEmpty()) {
-            return false;
-        }
-        if (id1.startsWith(NEW_ID_PREFIX)) {
-            if (id2.startsWith(NEW_ID_PREFIX)) {
-                return id1.equals(id2);
-            } else {
-                assert id2.startsWith(ID_PREFIX) : id2;
-                return ((id1.length() - id2.length())
-                            == (NEW_ID_PREFIX.length() - ID_PREFIX.length()))
-                        && id1.regionMatches(NEW_ID_PREFIX.length(), id2,
-                                ID_PREFIX.length(),
-                                id2.length() - ID_PREFIX.length());
-            }
-        } else {
-            assert id1.startsWith(ID_PREFIX) : id1;
-            if (id2.startsWith(ID_PREFIX)) {
-                return id1.equals(id2);
-            } else {
-                assert id2.startsWith(NEW_ID_PREFIX);
-                return (id2.length() - id1.length()
-                            == (NEW_ID_PREFIX.length() - ID_PREFIX.length()))
-                        && id2.regionMatches(NEW_ID_PREFIX.length(), id1,
-                                ID_PREFIX.length(),
-                                id1.length() - ID_PREFIX.length());
-            }
-        }
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions
-     * to edit one string into the other) between two strings. In particular,
-     * this will compute the Levenshtein distance.
-     * <p>
-     * See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @return the edit distance between the two strings
-     */
-    public static int editDistance(@NonNull String s, @NonNull String t) {
-        int m = s.length();
-        int n = t.length();
-        int[][] d = new int[m + 1][n + 1];
-        for (int i = 0; i <= m; i++) {
-            d[i][0] = i;
-        }
-        for (int j = 0; j <= n; j++) {
-            d[0][j] = j;
-        }
-        for (int j = 1; j <= n; j++) {
-            for (int i = 1; i <= m; i++) {
-                if (s.charAt(i - 1) == t.charAt(j - 1)) {
-                    d[i][j] = d[i - 1][j - 1];
-                } else {
-                    int deletion = d[i - 1][j] + 1;
-                    int insertion = d[i][j - 1] + 1;
-                    int substitution = d[i - 1][j - 1] + 1;
-                    d[i][j] = Math.min(deletion, Math.min(insertion, substitution));
-                }
-            }
-        }
-
-        return d[m][n];
-    }
-
-    /**
-     * Returns true if assertions are enabled
-     *
-     * @return true if assertions are enabled
-     */
-    @SuppressWarnings("all")
-    public static boolean assertionsEnabled() {
-        boolean assertionsEnabled = false;
-        assert assertionsEnabled = true; // Intentional side-effect
-        return assertionsEnabled;
-    }
-
-    /**
-     * Returns the layout resource name for the given layout file
-     *
-     * @param layoutFile the file pointing to the layout
-     * @return the layout resource name, not including the {@code @layout}
-     *         prefix
-     */
-    public static String getLayoutName(File layoutFile) {
-        String name = layoutFile.getName();
-        int dotIndex = name.indexOf('.');
-        if (dotIndex != -1) {
-            name = name.substring(0, dotIndex);
-        }
-        return name;
-    }
-
-    /**
-     * Splits the given path into its individual parts, attempting to be
-     * tolerant about path separators (: or ;). It can handle possibly ambiguous
-     * paths, such as {@code c:\foo\bar:\other}, though of course these are to
-     * be avoided if possible.
-     *
-     * @param path the path variable to split, which can use both : and ; as
-     *            path separators.
-     * @return the individual path components as an Iterable of strings
-     */
-    public static Iterable<String> splitPath(@NonNull String path) {
-        if (path.indexOf(';') != -1) {
-            return Splitter.on(';').omitEmptyStrings().trimResults().split(path);
-        }
-
-        List<String> combined = new ArrayList<String>();
-        Iterables.addAll(combined, Splitter.on(':').omitEmptyStrings().trimResults().split(path));
-        for (int i = 0, n = combined.size(); i < n; i++) {
-            String p = combined.get(i);
-            if (p.length() == 1 && i < n - 1 && Character.isLetter(p.charAt(0))
-                    // Technically, Windows paths do not have to have a \ after the :,
-                    // which means it would be using the current directory on that drive,
-                    // but that's unlikely to be the case in a path since it would have
-                    // unpredictable results
-                    && !combined.get(i+1).isEmpty() && combined.get(i+1).charAt(0) == '\\') {
-                combined.set(i, p + ':' + combined.get(i+1));
-                combined.remove(i+1);
-                n--;
-                continue;
-            }
-        }
-
-        return combined;
-    }
-
-    /**
-     * Computes the shared parent among a set of files (which may be null).
-     *
-     * @param files the set of files to be checked
-     * @return the closest common ancestor file, or null if none was found
-     */
-    @Nullable
-    public static File getCommonParent(@NonNull List<File> files) {
-        int fileCount = files.size();
-        if (fileCount == 0) {
-            return null;
-        } else if (fileCount == 1) {
-            return files.get(0);
-        } else if (fileCount == 2) {
-            return getCommonParent(files.get(0), files.get(1));
-        } else {
-            File common = files.get(0);
-            for (int i = 1; i < fileCount; i++) {
-                common = getCommonParent(common, files.get(i));
-                if (common == null) {
-                    return null;
-                }
-            }
-
-            return common;
-        }
-    }
-
-    /**
-     * Computes the closest common parent path between two files.
-     *
-     * @param file1 the first file to be compared
-     * @param file2 the second file to be compared
-     * @return the closest common ancestor file, or null if the two files have
-     *         no common parent
-     */
-    @Nullable
-    public static File getCommonParent(@NonNull File file1, @NonNull File file2) {
-        if (file1.equals(file2)) {
-            return file1;
-        } else if (file1.getPath().startsWith(file2.getPath())) {
-            return file2;
-        } else if (file2.getPath().startsWith(file1.getPath())) {
-            return file1;
-        } else {
-            // Dumb and simple implementation
-            File first = file1.getParentFile();
-            while (first != null) {
-                File second = file2.getParentFile();
-                while (second != null) {
-                    if (first.equals(second)) {
-                        return first;
-                    }
-                    second = second.getParentFile();
-                }
-
-                first = first.getParentFile();
-            }
-        }
-        return null;
-    }
-
-    private static final String UTF_16 = "UTF_16";               //$NON-NLS-1$
-    private static final String UTF_16LE = "UTF_16LE";           //$NON-NLS-1$
-
-    /**
-     * Returns the encoded String for the given file. This is usually the
-     * same as {@code Files.toString(file, Charsets.UTF8}, but if there's a UTF byte order mark
-     * (for UTF8, UTF_16 or UTF_16LE), use that instead.
-     *
-     * @param client the client to use for I/O operations
-     * @param file the file to read from
-     * @return the string
-     * @throws IOException if the file cannot be read properly
-     */
-    @NonNull
-    public static String getEncodedString(
-            @NonNull LintClient client,
-            @NonNull File file) throws IOException {
-        byte[] bytes = client.readBytes(file);
-        if (endsWith(file.getName(), DOT_XML)) {
-            return PositionXmlParser.getXmlString(bytes);
-        }
-
-        return getEncodedString(bytes);
-    }
-
-    /**
-     * Returns the String corresponding to the given data. This is usually the
-     * same as {@code new String(data)}, but if there's a UTF byte order mark
-     * (for UTF8, UTF_16 or UTF_16LE), use that instead.
-     * <p>
-     * NOTE: For XML files, there is the additional complication that there
-     * could be a {@code encoding=} attribute in the prologue. For those files,
-     * use {@link PositionXmlParser#getXmlString(byte[])} instead.
-     *
-     * @param data the byte array to construct the string from
-     * @return the string
-     */
-    @NonNull
-    public static String getEncodedString(@Nullable byte[] data) {
-        if (data == null) {
-            return "";
-        }
-
-        int offset = 0;
-        String defaultCharset = UTF_8;
-        String charset = null;
-        // Look for the byte order mark, to see if we need to remove bytes from
-        // the input stream (and to determine whether files are big endian or little endian) etc
-        // for files which do not specify the encoding.
-        // See http://unicode.org/faq/utf_bom.html#BOM for more.
-        if (data.length > 4) {
-            if (data[0] == (byte)0xef && data[1] == (byte)0xbb && data[2] == (byte)0xbf) {
-                // UTF-8
-                defaultCharset = charset = UTF_8;
-                offset += 3;
-            } else if (data[0] == (byte)0xfe && data[1] == (byte)0xff) {
-                //  UTF-16, big-endian
-                defaultCharset = charset = UTF_16;
-                offset += 2;
-            } else if (data[0] == (byte)0x0 && data[1] == (byte)0x0
-                    && data[2] == (byte)0xfe && data[3] == (byte)0xff) {
-                // UTF-32, big-endian
-                defaultCharset = charset = "UTF_32";    //$NON-NLS-1$
-                offset += 4;
-            } else if (data[0] == (byte)0xff && data[1] == (byte)0xfe
-                    && data[2] == (byte)0x0 && data[3] == (byte)0x0) {
-                // UTF-32, little-endian. We must check for this *before* looking for
-                // UTF_16LE since UTF_32LE has the same prefix!
-                defaultCharset = charset = "UTF_32LE";  //$NON-NLS-1$
-                offset += 4;
-            } else if (data[0] == (byte)0xff && data[1] == (byte)0xfe) {
-                //  UTF-16, little-endian
-                defaultCharset = charset = UTF_16LE;
-                offset += 2;
-            }
-        }
-        int length = data.length - offset;
-
-        // Guess encoding by searching for an encoding= entry in the first line.
-        boolean seenOddZero = false;
-        boolean seenEvenZero = false;
-        for (int lineEnd = offset; lineEnd < data.length; lineEnd++) {
-            if (data[lineEnd] == 0) {
-                if ((lineEnd - offset) % 2 == 0) {
-                    seenEvenZero = true;
-                } else {
-                    seenOddZero = true;
-                }
-            } else if (data[lineEnd] == '\n' || data[lineEnd] == '\r') {
-                break;
-            }
-        }
-
-        if (charset == null) {
-            charset = seenOddZero ? UTF_16LE : seenEvenZero ? UTF_16 : UTF_8;
-        }
-
-        String text = null;
-        try {
-            text = new String(data, offset, length, charset);
-        } catch (UnsupportedEncodingException e) {
-            try {
-                if (!charset.equals(defaultCharset)) {
-                    text = new String(data, offset, length, defaultCharset);
-                }
-            } catch (UnsupportedEncodingException u) {
-                // Just use the default encoding below
-            }
-        }
-        if (text == null) {
-            text = new String(data, offset, length);
-        }
-        return text;
-    }
-
-    /**
-     * Returns true if the given class node represents a static inner class.
-     *
-     * @param classNode the inner class to be checked
-     * @return true if the class node represents an inner class that is static
-     */
-    public static boolean isStaticInnerClass(@NonNull ClassNode classNode) {
-        // Note: We can't just filter out static inner classes like this:
-        //     (classNode.access & Opcodes.ACC_STATIC) != 0
-        // because the static flag only appears on methods and fields in the class
-        // file. Instead, look for the synthetic this pointer.
-
-        @SuppressWarnings("rawtypes") // ASM API
-        List fieldList = classNode.fields;
-        for (Object f : fieldList) {
-            FieldNode field = (FieldNode) f;
-            if (field.name.startsWith("this$") && (field.access & Opcodes.ACC_SYNTHETIC) != 0) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if the given class node represents an anonymous inner class
-     *
-     * @param classNode the class to be checked
-     * @return true if the class appears to be an anonymous class
-     */
-    public static boolean isAnonymousClass(@NonNull ClassNode classNode) {
-        if (classNode.outerClass == null) {
-            return false;
-        }
-
-        String name = classNode.name;
-        int index = name.lastIndexOf('$');
-        if (index == -1 || index == name.length() - 1) {
-            return false;
-        }
-
-        return Character.isDigit(name.charAt(index + 1));
-    }
-
-    /**
-     * Returns the previous opcode prior to the given node, ignoring label and
-     * line number nodes
-     *
-     * @param node the node to look up the previous opcode for
-     * @return the previous opcode, or {@link Opcodes#NOP} if no previous node
-     *         was found
-     */
-    public static int getPrevOpcode(@NonNull AbstractInsnNode node) {
-        AbstractInsnNode prev = getPrevInstruction(node);
-        if (prev != null) {
-            return prev.getOpcode();
-        } else {
-            return Opcodes.NOP;
-        }
-    }
-
-    /**
-     * Returns the previous instruction prior to the given node, ignoring label
-     * and line number nodes.
-     *
-     * @param node the node to look up the previous instruction for
-     * @return the previous instruction, or null if no previous node was found
-     */
-    @Nullable
-    public static AbstractInsnNode getPrevInstruction(@NonNull AbstractInsnNode node) {
-        AbstractInsnNode prev = node;
-        while (true) {
-            prev = prev.getPrevious();
-            if (prev == null) {
-                return null;
-            } else {
-                int type = prev.getType();
-                if (type != AbstractInsnNode.LINE && type != AbstractInsnNode.LABEL
-                        && type != AbstractInsnNode.FRAME) {
-                    return prev;
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the next opcode after to the given node, ignoring label and line
-     * number nodes
-     *
-     * @param node the node to look up the next opcode for
-     * @return the next opcode, or {@link Opcodes#NOP} if no next node was found
-     */
-    public static int getNextOpcode(@NonNull AbstractInsnNode node) {
-        AbstractInsnNode next = getNextInstruction(node);
-        if (next != null) {
-            return next.getOpcode();
-        } else {
-            return Opcodes.NOP;
-        }
-    }
-
-    /**
-     * Returns the next instruction after to the given node, ignoring label and
-     * line number nodes.
-     *
-     * @param node the node to look up the next node for
-     * @return the next instruction, or null if no next node was found
-     */
-    @Nullable
-    public static AbstractInsnNode getNextInstruction(@NonNull AbstractInsnNode node) {
-        AbstractInsnNode next = node;
-        while (true) {
-            next = next.getNext();
-            if (next == null) {
-                return null;
-            } else {
-                int type = next.getType();
-                if (type != AbstractInsnNode.LINE && type != AbstractInsnNode.LABEL
-                        && type != AbstractInsnNode.FRAME) {
-                    return next;
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if the given directory is a lint manifest file directory.
-     *
-     * @param dir the directory to check
-     * @return true if the directory contains a manifest file
-     */
-    public static boolean isManifestFolder(File dir) {
-        boolean hasManifest = new File(dir, ANDROID_MANIFEST_XML).exists();
-        if (hasManifest) {
-            // Special case: the bin/ folder can also contain a copy of the
-            // manifest file, but this is *not* a project directory
-            if (dir.getName().equals(BIN_FOLDER)) {
-                // ...unless of course it just *happens* to be a project named bin, in
-                // which case we peek at its parent to see if this is the case
-                dir = dir.getParentFile();
-                //noinspection ConstantConditions
-                if (dir != null && isManifestFolder(dir)) {
-                    // Yes, it's a bin/ directory inside a real project: ignore this dir
-                    return false;
-                }
-            }
-        }
-
-        return hasManifest;
-    }
-
-    /**
-     * Look up the locale and region from the given parent folder name and
-     * return it as a combined string, such as "en", "en-rUS", b+eng-US, etc, or null if
-     * no language is specified.
-     *
-     * @param folderName the folder name
-     * @return the locale+region string or null
-     */
-    @Nullable
-    public static String getLocaleAndRegion(@NonNull String folderName) {
-        if (folderName.indexOf('-') == -1) {
-            return null;
-        }
-
-        String locale = null;
-
-        for (String qualifier : QUALIFIER_SPLITTER.split(folderName)) {
-            int qualifierLength = qualifier.length();
-            if (qualifierLength == 2) {
-                char first = qualifier.charAt(0);
-                char second = qualifier.charAt(1);
-                if (first >= 'a' && first <= 'z' && second >= 'a' && second <= 'z') {
-                    locale = qualifier;
-                }
-            } else if (qualifierLength == 3 && qualifier.charAt(0) == 'r' && locale != null) {
-                char first = qualifier.charAt(1);
-                char second = qualifier.charAt(2);
-                if (first >= 'A' && first <= 'Z' && second >= 'A' && second <= 'Z') {
-                    return locale + '-' + qualifier;
-                }
-                break;
-            } else if (qualifier.startsWith(BCP_47_PREFIX)) {
-                return qualifier;
-            }
-        }
-
-        return locale;
-    }
-
-    /**
-     * Returns true if the given class (specified by a fully qualified class
-     * name) name is imported in the given compilation unit either through a fully qualified
-     * import or by a wildcard import.
-     *
-     * @param compilationUnit the compilation unit
-     * @param fullyQualifiedName the fully qualified class name
-     * @return true if the given imported name refers to the given fully
-     *         qualified name
-     * @deprecated Use PSI element hierarchies instead where type resolution is more directly
-     *  available (call {@link PsiImportStatement#resolve()})
-     */
-    @Deprecated
-    public static boolean isImported(
-            @Nullable lombok.ast.Node compilationUnit,
-            @NonNull String fullyQualifiedName) {
-        if (compilationUnit == null) {
-            return false;
-        }
-        int dotIndex = fullyQualifiedName.lastIndexOf('.');
-        int dotLength = fullyQualifiedName.length() - dotIndex;
-
-        boolean imported = false;
-        for (lombok.ast.Node rootNode : compilationUnit.getChildren()) {
-            if (rootNode instanceof ImportDeclaration) {
-                ImportDeclaration importDeclaration = (ImportDeclaration) rootNode;
-                String fqn = importDeclaration.asFullyQualifiedName();
-                if (fqn.equals(fullyQualifiedName)) {
-                    return true;
-                } else if (fullyQualifiedName.regionMatches(dotIndex, fqn,
-                        fqn.length() - dotLength, dotLength)) {
-                    // This import is importing the class name using some other prefix, so there
-                    // fully qualified class name cannot be imported under that name
-                    return false;
-                } else if (importDeclaration.astStarImport()
-                        && fqn.regionMatches(0, fqn, 0, dotIndex + 1)) {
-                    imported = true;
-                    // but don't break -- keep searching in case there's a non-wildcard
-                    // import of the specific class name, e.g. if we're looking for
-                    // android.content.SharedPreferences.Editor, don't match on the following:
-                    //   import android.content.SharedPreferences.*;
-                    //   import foo.bar.Editor;
-                }
-            }
-        }
-
-        return imported;
-    }
-
-    /**
-     * Looks up the resource values for the given attribute given a style. Note that
-     * this only looks project-level style values, it does not resume into the framework
-     * styles.
-     */
-    @Nullable
-    public static List<ResourceValue> getStyleAttributes(
-            @NonNull Project project, @NonNull LintClient client,
-            @NonNull String styleUrl, @NonNull String namespace, @NonNull String attribute) {
-        if (!client.supportsProjectResources()) {
-            return null;
-        }
-
-        AbstractResourceRepository resources = client.getProjectResources(project, true);
-        if (resources == null) {
-            return null;
-        }
-
-        ResourceUrl style = ResourceUrl.parse(styleUrl);
-        if (style == null || style.framework) {
-            return null;
-        }
-
-        List<ResourceValue> result = null;
-
-        Queue<ResourceValue> queue = new ArrayDeque<ResourceValue>();
-        queue.add(new ResourceValue(ResourceUrl.create(style.type, style.name, false), null));
-        Set<String> seen = Sets.newHashSet();
-        int count = 0;
-        boolean isFrameworkAttribute = ANDROID_URI.equals(namespace);
-        while (count < 30 && !queue.isEmpty()) {
-            ResourceValue front = queue.remove();
-            String name = front.getName();
-            seen.add(name);
-            List<ResourceItem> items = resources.getResourceItem(front.getResourceType(), name);
-            if (items != null) {
-                for (ResourceItem item : items) {
-                    ResourceValue rv = item.getResourceValue(false);
-                    if (rv instanceof StyleResourceValue) {
-                        StyleResourceValue srv = (StyleResourceValue) rv;
-                        ItemResourceValue value = srv.getItem(attribute, isFrameworkAttribute);
-                        if (value != null) {
-                            if (result == null) {
-                                result = Lists.newArrayList();
-                            }
-                            if (!result.contains(value)) {
-                                result.add(value);
-                            }
-                        }
-
-                        String parent = srv.getParentStyle();
-                        if (parent != null && !parent.startsWith(ANDROID_PREFIX)) {
-                            ResourceUrl p = ResourceUrl.parse(parent);
-                            if (p != null && !p.framework && !seen.contains(p.name)) {
-                                seen.add(p.name);
-                                queue.add(new ResourceValue(ResourceUrl.create(ResourceType.STYLE, p.name,
-                                        false), null));
-                            }
-                        }
-
-                        int index = name.lastIndexOf('.');
-                        if (index > 0) {
-                            String parentName = name.substring(0, index);
-                            if (!seen.contains(parentName)) {
-                                seen.add(parentName);
-                                queue.add(new ResourceValue(ResourceUrl.create(ResourceType.STYLE, parentName,
-                                        false), null));
-                            }
-                        }
-                    }
-                }
-            }
-
-            count++;
-        }
-
-        return result;
-    }
-
-    @Nullable
-    public static List<StyleResourceValue> getInheritedStyles(
-            @NonNull Project project, @NonNull LintClient client,
-            @NonNull String styleUrl) {
-        if (!client.supportsProjectResources()) {
-            return null;
-        }
-
-        AbstractResourceRepository resources = client.getProjectResources(project, true);
-        if (resources == null) {
-            return null;
-        }
-
-        ResourceUrl style = ResourceUrl.parse(styleUrl);
-        if (style == null || style.framework) {
-            return null;
-        }
-
-        List<StyleResourceValue> result = null;
-
-        Queue<ResourceValue> queue = new ArrayDeque<ResourceValue>();
-        queue.add(new ResourceValue(ResourceUrl.create(style.type, style.name, false), null));
-        Set<String> seen = Sets.newHashSet();
-        int count = 0;
-        while (count < 30 && !queue.isEmpty()) {
-            ResourceValue front = queue.remove();
-            String name = front.getName();
-            seen.add(name);
-            List<ResourceItem> items = resources.getResourceItem(front.getResourceType(), name);
-            if (items != null) {
-                for (ResourceItem item : items) {
-                    ResourceValue rv = item.getResourceValue(false);
-                    if (rv instanceof StyleResourceValue) {
-                        StyleResourceValue srv = (StyleResourceValue) rv;
-                        if (result == null) {
-                            result = Lists.newArrayList();
-                        }
-                        result.add(srv);
-
-                        String parent = srv.getParentStyle();
-                        if (parent != null && !parent.startsWith(ANDROID_PREFIX)) {
-                            ResourceUrl p = ResourceUrl.parse(parent);
-                            if (p != null && !p.framework && !seen.contains(p.name)) {
-                                seen.add(p.name);
-                                queue.add(new ResourceValue(ResourceUrl.create(ResourceType.STYLE, p.name,
-                                        false), null));
-                            }
-                        }
-
-                        int index = name.lastIndexOf('.');
-                        if (index > 0) {
-                            String parentName = name.substring(0, index);
-                            if (!seen.contains(parentName)) {
-                                seen.add(parentName);
-                                queue.add(new ResourceValue(ResourceUrl.create(ResourceType.STYLE, parentName,
-                                        false), null));
-                            }
-                        }
-                    }
-                }
-            }
-
-            count++;
-        }
-
-        return result;
-    }
-
-    /** Returns true if the given two paths point to the same logical resource file within
-     * a source set. This means that it only checks the parent folder name and individual
-     * file name, not the path outside the parent folder.
-     *
-     * @param file1 the first file to compare
-     * @param file2 the second file to compare
-     * @return true if the two files have the same parent and file names
-     */
-    public static boolean isSameResourceFile(@Nullable File file1, @Nullable File file2) {
-        if (file1 != null && file2 != null
-                && file1.getName().equals(file2.getName())) {
-            File parent1 = file1.getParentFile();
-            File parent2 = file2.getParentFile();
-            if (parent1 != null && parent2 != null &&
-                    parent1.getName().equals(parent2.getName())) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Whether we should attempt to look up the prefix from the model. Set to false
-     * if we encounter a model which is too old.
-     * <p>
-     * This is public such that code which for example syncs to a new gradle model
-     * can reset it.
-     */
-    public static boolean sTryPrefixLookup = true;
-
-    /** Looks up the resource prefix for the given Gradle project, if possible */
-    @Nullable
-    public static String computeResourcePrefix(@Nullable AndroidProject project) {
-        try {
-            if (sTryPrefixLookup && project != null) {
-                return project.getResourcePrefix();
-            }
-        } catch (Exception e) {
-            // This happens if we're talking to an older model than 0.10
-            // Ignore; fall through to normal handling and never try again.
-            //noinspection AssignmentToStaticFieldFromInstanceMethod
-            sTryPrefixLookup = false;
-        }
-
-        return null;
-    }
-
-    /** Computes a suggested name given a resource prefix and resource name */
-    public static String computeResourceName(@NonNull String prefix, @NonNull String name) {
-        if (prefix.isEmpty()) {
-            return name;
-        } else if (name.isEmpty()) {
-            return prefix;
-        } else if (prefix.endsWith("_")) {
-            return prefix + name;
-        } else {
-            return prefix + Character.toUpperCase(name.charAt(0)) + name.substring(1);
-        }
-    }
-
-
-    /**
-     * Convert an {@link com.android.builder.model.ApiVersion} to a {@link
-     * com.android.sdklib.AndroidVersion}. The chief problem here is that the {@link
-     * com.android.builder.model.ApiVersion}, when using a codename, will not encode the
-     * corresponding API level (it just reflects the string entered by the user in the gradle file)
-     * so we perform a search here (since lint really wants to know the actual numeric API level)
-     *
-     * @param api     the api version to convert
-     * @param targets if known, the installed targets (used to resolve platform codenames, only
-     *                needed to resolve platforms newer than the tools since {@link
-     *                com.android.sdklib.SdkVersionInfo} knows the rest)
-     * @return the corresponding version
-     */
-    @NonNull
-    public static AndroidVersion convertVersion(
-            @NonNull ApiVersion api,
-            @Nullable IAndroidTarget[] targets) {
-        String codename = api.getCodename();
-        if (codename != null) {
-            AndroidVersion version = SdkVersionInfo.getVersion(codename, targets);
-            if (version != null) {
-                return version;
-            }
-            return new AndroidVersion(api.getApiLevel(), codename);
-        }
-        return new AndroidVersion(api.getApiLevel(), null);
-    }
-    
-    /**
-     * Looks for a certain string within a larger string, which should immediately follow
-     * the given prefix and immediately precede the given suffix.
-     *
-     * @param string the full string to search
-     * @param prefix the optional prefix to follow
-     * @param suffix the optional suffix to precede
-     * @return the corresponding substring, if present
-     */
-    @Nullable
-    public static String findSubstring(@NonNull String string, @Nullable String prefix,
-            @Nullable String suffix) {
-        int start = 0;
-        if (prefix != null) {
-            start = string.indexOf(prefix);
-            if (start == -1) {
-                return null;
-            }
-            start += prefix.length();
-        }
-
-        if (suffix != null) {
-            int end = string.indexOf(suffix, start);
-            if (end == -1) {
-                return null;
-            }
-            return string.substring(start, end);
-        }
-
-        return string.substring(start);
-    }
-
-    /**
-     * Splits up the given message coming from a given string format (where the string
-     * format follows the very specific convention of having only strings formatted exactly
-     * with the format %n$s where n is between 1 and 9 inclusive, and each formatting parameter
-     * appears exactly once, and in increasing order.
-     *
-     * @param format the format string responsible for creating the error message
-     * @param errorMessage an error message formatted with the format string
-     * @return the specific values inserted into the format
-     */
-    @NonNull
-    public static List<String> getFormattedParameters(
-            @NonNull String format,
-            @NonNull String errorMessage) {
-        StringBuilder pattern = new StringBuilder(format.length());
-        int parameter = 1;
-        for (int i = 0, n = format.length(); i < n; i++) {
-            char c = format.charAt(i);
-            if (c == '%') {
-                // Only support formats of the form %n$s where n is 1 <= n <=9
-                assert i < format.length() - 4 : format;
-                assert format.charAt(i + 1) == ('0' + parameter) : format;
-                assert Character.isDigit(format.charAt(i + 1)) : format;
-                assert format.charAt(i + 2) == '$' : format;
-                assert format.charAt(i + 3) == 's' : format;
-                parameter++;
-                i += 3;
-                pattern.append("(.*)");
-            } else {
-                pattern.append(c);
-            }
-        }
-        try {
-            Pattern compile = Pattern.compile(pattern.toString());
-            Matcher matcher = compile.matcher(errorMessage);
-            if (matcher.find()) {
-                int groupCount = matcher.groupCount();
-                List<String> parameters = Lists.newArrayListWithExpectedSize(groupCount);
-                for (int i = 1; i <= groupCount; i++) {
-                    parameters.add(matcher.group(i));
-                }
-
-                return parameters;
-            }
-
-        } catch (PatternSyntaxException pse) {
-            // Internal error: string format is not valid. Should be caught by unit tests
-            // as a failure to return the formatted parameters.
-        }
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the locale for the given parent folder.
-     *
-     * @param parent the name of the parent folder
-     * @return null if the locale is not known, or a locale qualifier providing the language
-     *    and possibly region
-     */
-    @Nullable
-    public static LocaleQualifier getLocale(@NonNull String parent) {
-        if (parent.indexOf('-') != -1) {
-            FolderConfiguration config = FolderConfiguration.getConfigForFolder(parent);
-            if (config != null) {
-                return config.getLocaleQualifier();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the locale for the given context.
-     *
-     * @param context the context to look up the locale for
-     * @return null if the locale is not known, or a locale qualifier providing the language
-     *    and possibly region
-     */
-    @Nullable
-    public static LocaleQualifier getLocale(@NonNull XmlContext context) {
-        Element root = context.document.getDocumentElement();
-        if (root != null) {
-            String locale = root.getAttributeNS(TOOLS_URI, ATTR_LOCALE);
-            if (locale != null && !locale.isEmpty()) {
-                return getLocale(locale);
-            }
-        }
-
-        return getLocale(context.file.getParentFile().getName());
-    }
-
-    /**
-     * Check whether the given resource file is in an English locale
-     * @param context the XML context for the resource file
-     * @param assumeForBase whether the base folder (e.g. no locale specified) should be
-     *                      treated as English
-     */
-    public static boolean isEnglishResource(@NonNull XmlContext context, boolean assumeForBase) {
-        LocaleQualifier locale = LintUtils.getLocale(context);
-        if (locale == null) {
-            return assumeForBase;
-        } else {
-            return "en".equals(locale.getLanguage());  //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Create a {@link Location} for an error in the top level build.gradle file.
-     * This is necessary when we're doing an analysis based on the Gradle interpreted model,
-     * not from parsing Gradle files - and the model doesn't provide source positions.
-     * @param project the project containing the gradle file being analyzed
-     * @return location for the top level gradle file if it exists, otherwise fall back to
-     *     the project directory.
-     */
-    public static Location guessGradleLocation(@NonNull Project project) {
-        File dir = project.getDir();
-        Location location;
-        File topLevel = new File(dir, FN_BUILD_GRADLE);
-        if (topLevel.exists()) {
-            location = Location.create(topLevel);
-        } else {
-            location = Location.create(dir);
-        }
-        return location;
-    }
-
-    /**
-     * Returns true if the given element is the null literal
-     *
-     * @param element the element to check
-     * @return true if the element is "null"
-     */
-    public static boolean isNullLiteral(@Nullable PsiElement element) {
-        return element instanceof PsiLiteral && "null".equals(element.getText());
-    }
-
-    public static boolean isTrueLiteral(@Nullable PsiElement element) {
-        return element instanceof PsiLiteral && "true".equals(element.getText());
-    }
-
-    public static boolean isFalseLiteral(@Nullable PsiElement element) {
-        return element instanceof PsiLiteral && "false".equals(element.getText());
-    }
-
-    @Nullable
-    public static PsiElement skipParentheses(@Nullable PsiElement element) {
-        while (element instanceof PsiParenthesizedExpression) {
-            element = element.getParent();
-        }
-
-        return element;
-    }
-
-    @Nullable
-    public static UElement skipParentheses(@Nullable UElement element) {
-        while (element instanceof UParenthesizedExpression) {
-            element = element.getUastParent();
-        }
-
-        return element;
-    }
-
-    @Nullable
-    public static PsiElement nextNonWhitespace(@Nullable PsiElement element) {
-        if (element != null) {
-            element = element.getNextSibling();
-            while (element instanceof PsiWhiteSpace) {
-                element = element.getNextSibling();
-            }
-        }
-
-        return element;
-    }
-
-    @Nullable
-    public static PsiElement prevNonWhitespace(@Nullable PsiElement element) {
-        if (element != null) {
-            element = element.getPrevSibling();
-            while (element instanceof PsiWhiteSpace) {
-                element = element.getPrevSibling();
-            }
-        }
-
-        return element;
-    }
-
-    public static boolean isString(@NonNull PsiType type) {
-        if (type instanceof PsiClassType) {
-            final String shortName = ((PsiClassType)type).getClassName();
-            if (!Objects.equal(shortName, CommonClassNames.JAVA_LANG_STRING_SHORT)) {
-                return false;
-            }
-        }
-        return CommonClassNames.JAVA_LANG_STRING.equals(type.getCanonicalText());
-    }
-
-    @Nullable
-    public static String getAutoBoxedType(@NonNull String primitive) {
-        if (TYPE_INT.equals(primitive)) {
-            return TYPE_INTEGER_WRAPPER;
-        } else if (TYPE_LONG.equals(primitive)) {
-            return TYPE_LONG_WRAPPER;
-        } else if (TYPE_CHAR.equals(primitive)) {
-            return TYPE_CHARACTER_WRAPPER;
-        } else if (TYPE_FLOAT.equals(primitive)) {
-            return TYPE_FLOAT_WRAPPER;
-        } else if (TYPE_DOUBLE.equals(primitive)) {
-            return TYPE_DOUBLE_WRAPPER;
-        } else if (TYPE_BOOLEAN.equals(primitive)) {
-            return TYPE_BOOLEAN_WRAPPER;
-        } else if (TYPE_SHORT.equals(primitive)) {
-            return TYPE_SHORT_WRAPPER;
-        } else if (TYPE_BYTE.equals(primitive)) {
-            return TYPE_BYTE_WRAPPER;
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static String getPrimitiveType(@NonNull String autoBoxedType) {
-        if (TYPE_INTEGER_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_INT;
-        } else if (TYPE_LONG_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_LONG;
-        } else if (TYPE_CHARACTER_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_CHAR;
-        } else if (TYPE_FLOAT_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_FLOAT;
-        } else if (TYPE_DOUBLE_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_DOUBLE;
-        } else if (TYPE_BOOLEAN_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_BOOLEAN;
-        } else if (TYPE_SHORT_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_SHORT;
-        } else if (TYPE_BYTE_WRAPPER.equals(autoBoxedType)) {
-            return TYPE_BYTE;
-        }
-
-        return null;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Location.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Location.java
deleted file mode 100644
index bb80f41..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Location.java
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.blame.SourcePosition;
-import com.android.ide.common.res2.ResourceFile;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.tools.klint.client.api.JavaParser;
-import com.google.common.annotations.Beta;
-import com.intellij.psi.PsiElement;
-
-import java.io.File;
-
-/**
- * Location information for a warning
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class Location {
-    private static final String SUPER_KEYWORD = "super"; //$NON-NLS-1$
-
-    private final File mFile;
-    private final Position mStart;
-    private final Position mEnd;
-    private String mMessage;
-    private Location mSecondary;
-    private Object mClientData;
-
-    /**
-     * Special marker location which means location not available, or not applicable, or filtered out, etc.
-     * For example, the infrastructure may return {@link #NONE} if you ask {@link JavaParser#getLocation(JavaContext, PsiElement)}
-     * for an element which is not in the current file during an incremental lint run in a single file.
-     */
-    public static final Location NONE = new Location(new File("NONE"), null, null);
-
-    /**
-     * (Private constructor, use one of the factory methods
-     * {@link Location#create(File)},
-     * {@link Location#create(File, Position, Position)}, or
-     * {@link Location#create(File, String, int, int)}.
-     * <p>
-     * Constructs a new location range for the given file, from start to end. If
-     * the length of the range is not known, end may be null.
-     *
-     * @param file the associated file (but see the documentation for
-     *            {@link #getFile()} for more information on what the file
-     *            represents)
-     * @param start the starting position, or null
-     * @param end the ending position, or null
-     */
-    protected Location(@NonNull File file, @Nullable Position start, @Nullable Position end) {
-        super();
-        mFile = file;
-        mStart = start;
-        mEnd = end;
-    }
-
-    /**
-     * Returns the file containing the warning. Note that the file *itself* may
-     * not yet contain the error. When editing a file in the IDE for example,
-     * the tool could generate warnings in the background even before the
-     * document is saved. However, the file is used as a identifying token for
-     * the document being edited, and the IDE integration can map this back to
-     * error locations in the editor source code.
-     *
-     * @return the file handle for the location
-     */
-    @NonNull
-    public File getFile() {
-        return mFile;
-    }
-
-    /**
-     * The start position of the range
-     *
-     * @return the start position of the range, or null
-     */
-    @Nullable
-    public Position getStart() {
-        return mStart;
-    }
-
-    /**
-     * The end position of the range
-     *
-     * @return the start position of the range, may be null for an empty range
-     */
-    @Nullable
-    public Position getEnd() {
-        return mEnd;
-    }
-
-    /**
-     * Returns a secondary location associated with this location (if
-     * applicable), or null.
-     *
-     * @return a secondary location or null
-     */
-    @Nullable
-    public Location getSecondary() {
-        return mSecondary;
-    }
-
-    /**
-     * Sets a secondary location for this location.
-     *
-     * @param secondary a secondary location associated with this location
-     */
-    public void setSecondary(@Nullable Location secondary) {
-        mSecondary = secondary;
-    }
-
-    /**
-     * Sets a custom message for this location. This is typically used for
-     * secondary locations, to describe the significance of this alternate
-     * location. For example, for a duplicate id warning, the primary location
-     * might say "This is a duplicate id", pointing to the second occurrence of
-     * id declaration, and then the secondary location could point to the
-     * original declaration with the custom message "Originally defined here".
-     *
-     * @param message the message to apply to this location
-     */
-    public void setMessage(@NonNull String message) {
-        mMessage = message;
-    }
-
-    /**
-     * Returns the custom message for this location, if any. This is typically
-     * used for secondary locations, to describe the significance of this
-     * alternate location. For example, for a duplicate id warning, the primary
-     * location might say "This is a duplicate id", pointing to the second
-     * occurrence of id declaration, and then the secondary location could point
-     * to the original declaration with the custom message
-     * "Originally defined here".
-     *
-     * @return the custom message for this location, or null
-     */
-    @Nullable
-    public String getMessage() {
-        return mMessage;
-    }
-
-    /**
-     * Sets the client data associated with this location. This is an optional
-     * field which can be used by the creator of the {@link Location} to store
-     * temporary state associated with the location.
-     *
-     * @param clientData the data to store with this location
-     */
-    public void setClientData(@Nullable Object clientData) {
-        mClientData = clientData;
-    }
-
-    /**
-     * Returns the client data associated with this location - an optional field
-     * which can be used by the creator of the {@link Location} to store
-     * temporary state associated with the location.
-     *
-     * @return the data associated with this location
-     */
-    @Nullable
-    public Object getClientData() {
-        return mClientData;
-    }
-
-    @Override
-    public String toString() {
-        return "Location [file=" + mFile + ", start=" + mStart + ", end=" + mEnd + ", message="
-                + mMessage + ']';
-    }
-
-    /**
-     * Creates a new location for the given file
-     *
-     * @param file the file to create a location for
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(@NonNull File file) {
-        return new Location(file, null /*start*/, null /*end*/);
-    }
-
-    /**
-     * Creates a new location for the given file and SourcePosition.
-     *
-     * @param file the file containing the positions
-     * @param position the source position
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(
-            @NonNull File file,
-            @NonNull SourcePosition position) {
-        if (position.equals(SourcePosition.UNKNOWN)) {
-            return new Location(file, null /*start*/, null /*end*/);
-        }
-        return new Location(file,
-                new DefaultPosition(
-                        position.getStartLine(),
-                        position.getStartColumn(),
-                        position.getStartOffset()),
-                new DefaultPosition(
-                        position.getEndLine(),
-                        position.getEndColumn(),
-                        position.getEndOffset()));
-    }
-
-    /**
-     * Creates a new location for the given file and starting and ending
-     * positions.
-     *
-     * @param file the file containing the positions
-     * @param start the starting position
-     * @param end the ending position
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(
-            @NonNull File file,
-            @NonNull Position start,
-            @Nullable Position end) {
-        return new Location(file, start, end);
-    }
-
-    /**
-     * Creates a new location for the given file, with the given contents, for
-     * the given offset range.
-     *
-     * @param file the file containing the location
-     * @param contents the current contents of the file
-     * @param startOffset the starting offset
-     * @param endOffset the ending offset
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(
-            @NonNull File file,
-            @Nullable String contents,
-            int startOffset,
-            int endOffset) {
-        if (startOffset < 0 || endOffset < startOffset) {
-            throw new IllegalArgumentException("Invalid offsets");
-        }
-
-        if (contents == null) {
-            return new Location(file,
-                    new DefaultPosition(-1, -1, startOffset),
-                    new DefaultPosition(-1, -1, endOffset));
-        }
-
-        int size = contents.length();
-        endOffset = Math.min(endOffset, size);
-        startOffset = Math.min(startOffset, endOffset);
-        Position start = null;
-        int line = 0;
-        int lineOffset = 0;
-        char prev = 0;
-        for (int offset = 0; offset <= size; offset++) {
-            if (offset == startOffset) {
-                start = new DefaultPosition(line, offset - lineOffset, offset);
-            }
-            if (offset == endOffset) {
-                Position end = new DefaultPosition(line, offset - lineOffset, offset);
-                return new Location(file, start, end);
-            }
-            char c = contents.charAt(offset);
-            if (c == '\n') {
-                lineOffset = offset + 1;
-                if (prev != '\r') {
-                    line++;
-                }
-            } else if (c == '\r') {
-                line++;
-                lineOffset = offset + 1;
-            }
-            prev = c;
-        }
-        return create(file);
-    }
-
-    /**
-     * Creates a new location for the given file, with the given contents, for
-     * the given line number.
-     *
-     * @param file the file containing the location
-     * @param contents the current contents of the file
-     * @param line the line number (0-based) for the position
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(@NonNull File file, @NonNull String contents, int line) {
-        return create(file, contents, line, null, null, null);
-    }
-
-    /**
-     * Creates a new location for the given file, with the given contents, for
-     * the given line number.
-     *
-     * @param file the file containing the location
-     * @param contents the current contents of the file
-     * @param line the line number (0-based) for the position
-     * @param patternStart an optional pattern to search for from the line
-     *            match; if found, adjust the column and offsets to begin at the
-     *            pattern start
-     * @param patternEnd an optional pattern to search for behind the start
-     *            pattern; if found, adjust the end offset to match the end of
-     *            the pattern
-     * @param hints optional additional information regarding the pattern search
-     * @return a new location
-     */
-    @NonNull
-    public static Location create(@NonNull File file, @NonNull String contents, int line,
-            @Nullable String patternStart, @Nullable String patternEnd,
-            @Nullable SearchHints hints) {
-        int currentLine = 0;
-        int offset = 0;
-        while (currentLine < line) {
-            offset = contents.indexOf('\n', offset);
-            if (offset == -1) {
-                return create(file);
-            }
-            currentLine++;
-            offset++;
-        }
-
-        if (line == currentLine) {
-            if (patternStart != null) {
-                SearchDirection direction = SearchDirection.NEAREST;
-                if (hints != null) {
-                    direction = hints.mDirection;
-                }
-
-                int index;
-                if (direction == SearchDirection.BACKWARD) {
-                    index = findPreviousMatch(contents, offset, patternStart, hints);
-                    line = adjustLine(contents, line, offset, index);
-                } else if (direction == SearchDirection.EOL_BACKWARD) {
-                    int lineEnd = contents.indexOf('\n', offset);
-                    if (lineEnd == -1) {
-                        lineEnd = contents.length();
-                    }
-
-                    index = findPreviousMatch(contents, lineEnd, patternStart, hints);
-                    line = adjustLine(contents, line, offset, index);
-                } else if (direction == SearchDirection.FORWARD) {
-                    index = findNextMatch(contents, offset, patternStart, hints);
-                    line = adjustLine(contents, line, offset, index);
-                } else {
-                    assert direction == SearchDirection.NEAREST ||
-                            direction == SearchDirection.EOL_NEAREST;
-
-                    int lineEnd = contents.indexOf('\n', offset);
-                    if (lineEnd == -1) {
-                        lineEnd = contents.length();
-                    }
-                    offset = lineEnd;
-
-                    int before = findPreviousMatch(contents, offset, patternStart, hints);
-                    int after = findNextMatch(contents, offset, patternStart, hints);
-
-                    if (before == -1) {
-                        index = after;
-                        line = adjustLine(contents, line, offset, index);
-                    } else if (after == -1) {
-                        index = before;
-                        line = adjustLine(contents, line, offset, index);
-                    } else {
-                        int newLinesBefore = 0;
-                        for (int i = before; i < offset; i++) {
-                            if (contents.charAt(i) == '\n') {
-                                newLinesBefore++;
-                            }
-                        }
-                        int newLinesAfter = 0;
-                        for (int i = offset; i < after; i++) {
-                            if (contents.charAt(i) == '\n') {
-                                newLinesAfter++;
-                            }
-                        }
-                        if (newLinesBefore < newLinesAfter || newLinesBefore == newLinesAfter
-                                && offset - before < after - offset) {
-                            index = before;
-                            line = adjustLine(contents, line, offset, index);
-                        } else {
-                            index = after;
-                            line = adjustLine(contents, line, offset, index);
-                        }
-                    }
-                }
-
-                if (index != -1) {
-                    int lineStart = contents.lastIndexOf('\n', index);
-                    if (lineStart == -1) {
-                        lineStart = 0;
-                    } else {
-                        lineStart++; // was pointing to the previous line's CR, not line start
-                    }
-                    int column = index - lineStart;
-                    if (patternEnd != null) {
-                        int end = contents.indexOf(patternEnd, offset + patternStart.length());
-                        if (end != -1) {
-                            return new Location(file, new DefaultPosition(line, column, index),
-                                    new DefaultPosition(line, -1, end + patternEnd.length()));
-                        }
-                    } else if (hints != null && (hints.isJavaSymbol() || hints.isWholeWord())) {
-                        if (hints.isConstructor() && contents.startsWith(SUPER_KEYWORD, index)) {
-                            patternStart = SUPER_KEYWORD;
-                        }
-                        return new Location(file, new DefaultPosition(line, column, index),
-                                new DefaultPosition(line, column + patternStart.length(),
-                                        index + patternStart.length()));
-                    }
-                    return new Location(file, new DefaultPosition(line, column, index),
-                            new DefaultPosition(line, column, index + patternStart.length()));
-                }
-            }
-
-            Position position = new DefaultPosition(line, -1, offset);
-            return new Location(file, position, position);
-        }
-
-        return create(file);
-    }
-
-    private static int findPreviousMatch(@NonNull String contents, int offset, String pattern,
-            @Nullable SearchHints hints) {
-        while (true) {
-            int index = contents.lastIndexOf(pattern, offset);
-            if (index == -1) {
-                return -1;
-            } else {
-                if (isMatch(contents, index, pattern, hints)) {
-                    return index;
-                } else {
-                    offset = index - pattern.length();
-                }
-            }
-        }
-    }
-
-    private static int findNextMatch(@NonNull String contents, int offset, String pattern,
-            @Nullable SearchHints hints) {
-        int constructorIndex = -1;
-        if (hints != null && hints.isConstructor()) {
-            // Special condition: See if the call is referenced as "super" instead.
-            assert hints.isWholeWord();
-            int index = contents.indexOf(SUPER_KEYWORD, offset);
-            if (index != -1 && isMatch(contents, index, SUPER_KEYWORD, hints)) {
-                constructorIndex = index;
-            }
-        }
-
-        while (true) {
-            int index = contents.indexOf(pattern, offset);
-            if (index == -1) {
-                return constructorIndex;
-            } else {
-                if (isMatch(contents, index, pattern, hints)) {
-                    if (constructorIndex != -1) {
-                        return Math.min(constructorIndex, index);
-                    }
-                    return index;
-                } else {
-                    offset = index + pattern.length();
-                }
-            }
-        }
-    }
-
-    private static boolean isMatch(@NonNull String contents, int offset, String pattern,
-            @Nullable SearchHints hints) {
-        if (!contents.startsWith(pattern, offset)) {
-            return false;
-        }
-
-        if (hints != null) {
-            char prevChar = offset > 0 ? contents.charAt(offset - 1) : 0;
-            int lastIndex = offset + pattern.length() - 1;
-            char nextChar = lastIndex < contents.length() - 1 ? contents.charAt(lastIndex + 1) : 0;
-
-            if (hints.isWholeWord() && (Character.isLetter(prevChar)
-                    || Character.isLetter(nextChar))) {
-                return false;
-
-            }
-
-            if (hints.isJavaSymbol()) {
-                if (Character.isJavaIdentifierPart(prevChar)
-                        || Character.isJavaIdentifierPart(nextChar)) {
-                    return false;
-                }
-
-                if (prevChar == '"') {
-                    return false;
-                }
-
-                // TODO: Additional validation to see if we're in a comment, string, etc.
-                // This will require lexing from the beginning of the buffer.
-            }
-
-            if (hints.isConstructor() && SUPER_KEYWORD.equals(pattern)) {
-                // Only looking for super(), not super.x, so assert that the next
-                // non-space character is (
-                int index = lastIndex + 1;
-                while (index < contents.length() - 1) {
-                    char c = contents.charAt(index);
-                    if (c == '(') {
-                        break;
-                    } else if (!Character.isWhitespace(c)) {
-                        return false;
-                    }
-                    index++;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    private static int adjustLine(String doc, int line, int offset, int newOffset) {
-        if (newOffset == -1) {
-            return line;
-        }
-
-        if (newOffset < offset) {
-            return line - countLines(doc, newOffset, offset);
-        } else {
-            return line + countLines(doc, offset, newOffset);
-        }
-    }
-
-    private static int countLines(String doc, int start, int end) {
-        int lines = 0;
-        for (int offset = start; offset < end; offset++) {
-            char c = doc.charAt(offset);
-            if (c == '\n') {
-                lines++;
-            }
-        }
-
-        return lines;
-    }
-
-    /**
-     * Reverses the secondary location list initiated by the given location
-     *
-     * @param location the first location in the list
-     * @return the first location in the reversed list
-     */
-    public static Location reverse(@NonNull Location location) {
-        Location next = location.getSecondary();
-        location.setSecondary(null);
-        while (next != null) {
-            Location nextNext = next.getSecondary();
-            next.setSecondary(location);
-            location = next;
-            next = nextNext;
-        }
-
-        return location;
-    }
-
-    /**
-     * A {@link Handle} is a reference to a location. The point of a location
-     * handle is to be able to create them cheaply, and then resolve them into
-     * actual locations later (if needed). This makes it possible to for example
-     * delay looking up line numbers, for locations that are offset based.
-     */
-    public interface Handle {
-        /**
-         * Compute a full location for the given handle
-         *
-         * @return create a location for this handle
-         */
-        @NonNull
-        Location resolve();
-
-        /**
-         * Sets the client data associated with this location. This is an optional
-         * field which can be used by the creator of the {@link Location} to store
-         * temporary state associated with the location.
-         *
-         * @param clientData the data to store with this location
-         */
-        void setClientData(@Nullable Object clientData);
-
-        /**
-         * Returns the client data associated with this location - an optional field
-         * which can be used by the creator of the {@link Location} to store
-         * temporary state associated with the location.
-         *
-         * @return the data associated with this location
-         */
-        @Nullable
-        Object getClientData();
-    }
-
-    /** A default {@link Handle} implementation for simple file offsets */
-    public static class DefaultLocationHandle implements Handle {
-        private final File mFile;
-        private final String mContents;
-        private final int mStartOffset;
-        private final int mEndOffset;
-        private Object mClientData;
-
-        /**
-         * Constructs a new {@link DefaultLocationHandle}
-         *
-         * @param context the context pointing to the file and its contents
-         * @param startOffset the start offset within the file
-         * @param endOffset the end offset within the file
-         */
-        public DefaultLocationHandle(@NonNull Context context, int startOffset, int endOffset) {
-            mFile = context.file;
-            mContents = context.getContents();
-            mStartOffset = startOffset;
-            mEndOffset = endOffset;
-        }
-
-        @Override
-        @NonNull
-        public Location resolve() {
-            return create(mFile, mContents, mStartOffset, mEndOffset);
-        }
-
-        @Override
-        public void setClientData(@Nullable Object clientData) {
-            mClientData = clientData;
-        }
-
-        @Override
-        @Nullable
-        public Object getClientData() {
-            return mClientData;
-        }
-    }
-
-    public static class ResourceItemHandle implements Handle {
-        private final ResourceItem mItem;
-
-        public ResourceItemHandle(@NonNull ResourceItem item) {
-            mItem = item;
-        }
-        @NonNull
-        @Override
-        public Location resolve() {
-            // TODO: Look up the exact item location more
-            // closely
-            ResourceFile source = mItem.getSource();
-            assert source != null : mItem;
-            return create(source.getFile());
-        }
-
-        @Override
-        public void setClientData(@Nullable Object clientData) {
-        }
-
-        @Nullable
-        @Override
-        public Object getClientData() {
-            return null;
-        }
-    }
-
-    /**
-     * Whether to look forwards, or backwards, or in both directions, when
-     * searching for a pattern in the source code to determine the right
-     * position range for a given symbol.
-     * <p>
-     * When dealing with bytecode for example, there are only line number entries
-     * within method bodies, so when searching for the method declaration, we should only
-     * search backwards from the first line entry in the method.
-     */
-    public enum SearchDirection {
-        /** Only search forwards */
-        FORWARD,
-
-        /** Only search backwards */
-        BACKWARD,
-
-        /** Search backwards from the current end of line (normally it's the beginning of
-         * the current line) */
-        EOL_BACKWARD,
-
-        /**
-         * Search both forwards and backwards from the given line, and prefer
-         * the match that is closest
-         */
-        NEAREST,
-
-        /**
-         * Search both forwards and backwards from the end of the given line, and prefer
-         * the match that is closest
-         */
-        EOL_NEAREST,
-    }
-
-    /**
-     * Extra information pertaining to finding a symbol in a source buffer,
-     * used by {@link Location#create(File, String, int, String, String, SearchHints)}
-     */
-    public static class SearchHints {
-        /**
-         * the direction to search for the nearest match in (provided
-         * {@code patternStart} is non null)
-         */
-        @NonNull
-        private final SearchDirection mDirection;
-
-        /** Whether the matched pattern should be a whole word */
-        private boolean mWholeWord;
-
-        /**
-         * Whether the matched pattern should be a Java symbol (so for example,
-         * a match inside a comment or string literal should not be used)
-         */
-        private boolean mJavaSymbol;
-
-        /**
-         * Whether the matched pattern corresponds to a constructor; if so, look for
-         * some other possible source aliases too, such as "super".
-         */
-        private boolean mConstructor;
-
-        private SearchHints(@NonNull SearchDirection direction) {
-            super();
-            mDirection = direction;
-        }
-
-        /**
-         * Constructs a new {@link SearchHints} object
-         *
-         * @param direction the direction to search in for the pattern
-         * @return a new @link SearchHints} object
-         */
-        @NonNull
-        public static SearchHints create(@NonNull SearchDirection direction) {
-            return new SearchHints(direction);
-        }
-
-        /**
-         * Indicates that pattern matches should apply to whole words only
-
-         * @return this, for constructor chaining
-         */
-        @NonNull
-        public SearchHints matchWholeWord() {
-            mWholeWord = true;
-
-            return this;
-        }
-
-        /** @return true if the pattern match should be for whole words only */
-        public boolean isWholeWord() {
-            return mWholeWord;
-        }
-
-        /**
-         * Indicates that pattern matches should apply to Java symbols only
-         *
-         * @return this, for constructor chaining
-         */
-        @NonNull
-        public SearchHints matchJavaSymbol() {
-            mJavaSymbol = true;
-            mWholeWord = true;
-
-            return this;
-        }
-
-        /** @return true if the pattern match should be for Java symbols only */
-        public boolean isJavaSymbol() {
-            return mJavaSymbol;
-        }
-
-        /**
-         * Indicates that pattern matches should apply to constructors. If so, look for
-         * some other possible source aliases too, such as "super".
-         *
-         * @return this, for constructor chaining
-         */
-        @NonNull
-        public SearchHints matchConstructor() {
-            mConstructor = true;
-            mWholeWord = true;
-            mJavaSymbol = true;
-
-            return this;
-        }
-
-        /** @return true if the pattern match should be for a constructor */
-        public boolean isConstructor() {
-            return mConstructor;
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Position.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Position.java
deleted file mode 100644
index 02756d7..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Position.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Information about a position in a file/document.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class Position {
-    /**
-     * Returns the line number (0-based where the first line is line 0)
-     *
-     * @return the 0-based line number
-     */
-    public abstract int getLine();
-
-    /**
-     * The character offset
-     *
-     * @return the 0-based character offset
-     */
-    public abstract int getOffset();
-
-    /**
-     * Returns the column number (where the first character on the line is 0),
-     * or -1 if unknown
-     *
-     * @return the 0-based column number
-     */
-    public abstract int getColumn();
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Project.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Project.java
deleted file mode 100644
index ba3221c..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Project.java
+++ /dev/null
@@ -1,1491 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.SdkConstants.ANDROID_LIBRARY;
-import static com.android.SdkConstants.ANDROID_LIBRARY_REFERENCE_FORMAT;
-import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT;
-import static com.android.SdkConstants.ATTR_MIN_SDK_VERSION;
-import static com.android.SdkConstants.ATTR_PACKAGE;
-import static com.android.SdkConstants.ATTR_TARGET_SDK_VERSION;
-import static com.android.SdkConstants.FN_ANDROID_MANIFEST_XML;
-import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
-import static com.android.SdkConstants.OLD_PROGUARD_FILE;
-import static com.android.SdkConstants.PROGUARD_CONFIG;
-import static com.android.SdkConstants.PROJECT_PROPERTIES;
-import static com.android.SdkConstants.RES_FOLDER;
-import static com.android.SdkConstants.SUPPORT_LIB_ARTIFACT;
-import static com.android.SdkConstants.TAG_USES_SDK;
-import static com.android.SdkConstants.VALUE_TRUE;
-import static com.android.sdklib.SdkVersionInfo.HIGHEST_KNOWN_API;
-import static com.android.sdklib.SdkVersionInfo.LOWEST_ACTIVE_API;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.build.FilterData;
-import com.android.build.OutputFile;
-import com.android.builder.model.AndroidArtifact;
-import com.android.builder.model.AndroidArtifactOutput;
-import com.android.builder.model.AndroidLibrary;
-import com.android.builder.model.AndroidProject;
-import com.android.builder.model.ProductFlavor;
-import com.android.builder.model.ProductFlavorContainer;
-import com.android.builder.model.Variant;
-import com.android.ide.common.repository.GradleVersion;
-import com.android.ide.common.repository.ResourceVisibilityLookup;
-import com.android.resources.Density;
-import com.android.resources.ResourceFolderType;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkVersionInfo;
-import com.android.tools.klint.client.api.CircularDependencyException;
-import com.android.tools.klint.client.api.Configuration;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.SdkInfo;
-import com.google.common.annotations.Beta;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Charsets;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.io.Closeables;
-import com.google.common.io.Files;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A project contains information about an Android project being scanned for
- * Lint errors.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class Project {
-    protected final LintClient mClient;
-    protected final File mDir;
-    protected final File mReferenceDir;
-    protected Configuration mConfiguration;
-    protected String mPackage;
-    protected int mBuildSdk = -1;
-    protected IAndroidTarget mTarget;
-
-    protected AndroidVersion mManifestMinSdk = AndroidVersion.DEFAULT;
-    protected AndroidVersion mManifestTargetSdk = AndroidVersion.DEFAULT;
-
-    protected boolean mLibrary;
-    protected String mName;
-    protected String mProguardPath;
-    protected boolean mMergeManifests;
-
-    /** The SDK info, if any */
-    protected SdkInfo mSdkInfo;
-
-    /**
-     * If non null, specifies a non-empty list of specific files under this
-     * project which should be checked.
-     */
-    protected List<File> mFiles;
-    protected List<File> mProguardFiles;
-    protected List<File> mGradleFiles;
-    protected List<File> mManifestFiles;
-    protected List<File> mJavaSourceFolders;
-    protected List<File> mJavaClassFolders;
-    protected List<File> mNonProvidedJavaLibraries;
-    protected List<File> mJavaLibraries;
-    protected List<File> mTestSourceFolders;
-    protected List<File> mResourceFolders;
-    protected List<File> mAssetFolders;
-    protected List<Project> mDirectLibraries;
-    protected List<Project> mAllLibraries;
-    protected boolean mReportIssues = true;
-    protected Boolean mGradleProject;
-    protected Boolean mSupportLib;
-    protected Boolean mAppCompat;
-    protected GradleVersion mGradleVersion;
-    private Map<String, String> mSuperClassMap;
-    private ResourceVisibilityLookup mResourceVisibility;
-    private BuildToolInfo mBuildTools;
-
-    /**
-     * Creates a new {@link Project} for the given directory.
-     *
-     * @param client the tool running the lint check
-     * @param dir the root directory of the project
-     * @param referenceDir See {@link #getReferenceDir()}.
-     * @return a new {@link Project}
-     */
-    @NonNull
-    public static Project create(
-            @NonNull LintClient client,
-            @NonNull File dir,
-            @NonNull File referenceDir) {
-        return new Project(client, dir, referenceDir);
-    }
-
-    /**
-     * Returns true if this project is a Gradle-based Android project
-     *
-     * @return true if this is a Gradle-based project
-     */
-    public boolean isGradleProject() {
-        if (mGradleProject == null) {
-            mGradleProject = mClient.isGradleProject(this);
-        }
-
-        return mGradleProject;
-    }
-
-    /**
-     * Returns true if this project is an Android project.
-     *
-     * @return true if this project is an Android project.
-     */
-    @SuppressWarnings("MethodMayBeStatic")
-    public boolean isAndroidProject() {
-        return true;
-    }
-
-    /**
-     * Returns the project model for this project if it corresponds to
-     * a Gradle project. This is the case if {@link #isGradleProject()}
-     * is true and {@link #isLibrary()} is false.
-     *
-     * @return the project model, or null
-     */
-    @Nullable
-    public AndroidProject getGradleProjectModel() {
-        return null;
-    }
-
-    /**
-     * If this is a Gradle project with a valid Gradle model, return the version
-     * of the model/plugin.
-     *
-     * @return the Gradle plugin version, or null if invalid or not a Gradle project
-     */
-    @Nullable
-    public GradleVersion getGradleModelVersion() {
-        if (mGradleVersion == null && isGradleProject()) {
-            AndroidProject gradleProjectModel = getGradleProjectModel();
-            if (gradleProjectModel != null) {
-                mGradleVersion = GradleVersion.tryParse(gradleProjectModel.getModelVersion());
-            }
-        }
-
-        return mGradleVersion;
-    }
-    
-    /**
-     * Returns the project model for this project if it corresponds to
-     * a Gradle library. This is the case if both
-     * {@link #isGradleProject()} and {@link #isLibrary()} return true.
-     *
-     * @return the project model, or null
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    @Nullable
-    public AndroidLibrary getGradleLibraryModel() {
-        return null;
-    }
-
-    /**
-     * Returns the current selected variant, if any (and if the current project is a Gradle
-     * project). This can be used by incremental lint rules to warn about problems in the current
-     * context. Lint rules should however strive to perform cross variant analysis and warn about
-     * problems in any configuration.
-     *
-     * @return the select variant, or null
-     */
-    @Nullable
-    public Variant getCurrentVariant() {
-        return null;
-    }
-
-    /** Creates a new Project. Use one of the factory methods to create. */
-    protected Project(
-            @NonNull LintClient client,
-            @NonNull File dir,
-            @NonNull File referenceDir) {
-        mClient = client;
-        mDir = dir;
-        mReferenceDir = referenceDir;
-        initialize();
-    }
-
-    protected void initialize() {
-        // Default initialization: Use ADT/ant style project.properties file
-        try {
-            // Read properties file and initialize library state
-            Properties properties = new Properties();
-            File propFile = new File(mDir, PROJECT_PROPERTIES);
-            if (propFile.exists()) {
-                BufferedInputStream is = new BufferedInputStream(new FileInputStream(propFile));
-                try {
-                    properties.load(is);
-                    String value = properties.getProperty(ANDROID_LIBRARY);
-                    mLibrary = VALUE_TRUE.equals(value);
-                    String proguardPath = properties.getProperty(PROGUARD_CONFIG);
-                    if (proguardPath != null) {
-                        mProguardPath = proguardPath;
-                    }
-                    mMergeManifests = VALUE_TRUE.equals(properties.getProperty(
-                            "manifestmerger.enabled")); //$NON-NLS-1$
-                    String target = properties.getProperty("target"); //$NON-NLS-1$
-                    if (target != null) {
-                        int index = target.lastIndexOf('-');
-                        if (index == -1) {
-                            index = target.lastIndexOf(':');
-                        }
-                        if (index != -1) {
-                            String versionString = target.substring(index + 1);
-                            try {
-                                mBuildSdk = Integer.parseInt(versionString);
-                            } catch (NumberFormatException nufe) {
-                                mClient.log(Severity.WARNING, null,
-                                        "Unexpected build target format: %1$s", target);
-                            }
-                        }
-                    }
-
-                    for (int i = 1; i < 1000; i++) {
-                        String key = String.format(ANDROID_LIBRARY_REFERENCE_FORMAT, i);
-                        String library = properties.getProperty(key);
-                        if (library == null || library.isEmpty()) {
-                            // No holes in the numbering sequence is allowed
-                            break;
-                        }
-
-                        File libraryDir = new File(mDir, library).getCanonicalFile();
-
-                        if (mDirectLibraries == null) {
-                            mDirectLibraries = new ArrayList<Project>();
-                        }
-
-                        // Adjust the reference dir to be a proper prefix path of the
-                        // library dir
-                        File libraryReferenceDir = mReferenceDir;
-                        if (!libraryDir.getPath().startsWith(mReferenceDir.getPath())) {
-                            // Symlinks etc might have been resolved, so do those to
-                            // the reference dir as well
-                            libraryReferenceDir = libraryReferenceDir.getCanonicalFile();
-                            if (!libraryDir.getPath().startsWith(mReferenceDir.getPath())) {
-                                File file = libraryReferenceDir;
-                                while (file != null && !file.getPath().isEmpty()) {
-                                    if (libraryDir.getPath().startsWith(file.getPath())) {
-                                        libraryReferenceDir = file;
-                                        break;
-                                    }
-                                    file = file.getParentFile();
-                                }
-                            }
-                        }
-
-                        try {
-                            Project libraryPrj = mClient.getProject(libraryDir,
-                                    libraryReferenceDir);
-                            mDirectLibraries.add(libraryPrj);
-                            // By default, we don't report issues in inferred library projects.
-                            // The driver will set report = true for those library explicitly
-                            // requested.
-                            libraryPrj.setReportIssues(false);
-                        } catch (CircularDependencyException e) {
-                            e.setProject(this);
-                            e.setLocation(Location.create(propFile));
-                            throw e;
-                        }
-                    }
-                } finally {
-                    try {
-                        Closeables.close(is, true /* swallowIOException */);
-                    } catch (IOException e) {
-                        // cannot happen
-                    }
-                }
-            }
-        } catch (IOException ioe) {
-            mClient.log(ioe, "Initializing project state");
-        }
-
-        if (mDirectLibraries != null) {
-            mDirectLibraries = Collections.unmodifiableList(mDirectLibraries);
-        } else {
-            mDirectLibraries = Collections.emptyList();
-        }
-
-        if (isAospBuildEnvironment()) {
-            if (isAospFrameworksRelatedProject(mDir)) {
-                // No manifest file for this project: just init the manifest values here
-                mManifestMinSdk = mManifestTargetSdk = new AndroidVersion(HIGHEST_KNOWN_API, null);
-            } else if (mBuildSdk == -1) {
-                // only set BuildSdk for projects other than frameworks and
-                // the ones that don't have one set in project.properties.
-                mBuildSdk = getClient().getHighestKnownApiLevel();
-            }
-
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "Project [dir=" + mDir + ']';
-    }
-
-    @Override
-    public int hashCode() {
-        return mDir.hashCode();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        Project other = (Project) obj;
-        return mDir.equals(other.mDir);
-    }
-
-    /**
-     * Adds the given file to the list of files which should be checked in this
-     * project. If no files are added, the whole project will be checked.
-     *
-     * @param file the file to be checked
-     */
-    public void addFile(@NonNull File file) {
-        if (mFiles == null) {
-            mFiles = new ArrayList<File>();
-        }
-        mFiles.add(file);
-    }
-
-    /**
-     * The list of files to be checked in this project. If null, the whole
-     * project should be checked.
-     *
-     * @return the subset of files to be checked, or null for the whole project
-     */
-    @Nullable
-    public List<File> getSubset() {
-        return mFiles;
-    }
-
-    /**
-     * Returns the list of source folders for Java source files
-     *
-     * @return a list of source folders to search for .java files
-     */
-    @NonNull
-    public List<File> getJavaSourceFolders() {
-        if (mJavaSourceFolders == null) {
-            if (isAospFrameworksRelatedProject(mDir)) {
-                return Collections.singletonList(new File(mDir, "java")); //$NON-NLS-1$
-            }
-            if (isAospBuildEnvironment()) {
-                String top = getAospTop();
-                if (mDir.getAbsolutePath().startsWith(top)) {
-                    mJavaSourceFolders = getAospJavaSourcePath();
-                    return mJavaSourceFolders;
-                }
-            }
-
-            mJavaSourceFolders = mClient.getJavaSourceFolders(this);
-        }
-
-        return mJavaSourceFolders;
-    }
-
-    /**
-     * Returns the list of output folders for class files
-     * @return a list of output folders to search for .class files
-     */
-    @NonNull
-    public List<File> getJavaClassFolders() {
-        if (mJavaClassFolders == null) {
-            if (isAospFrameworksProject(mDir)) {
-                String top = getAospTop();
-                if (top != null) {
-                    File out = new File(top, "out"); //$NON-NLS-1$
-                    if (out.exists()) {
-                        String relative =
-                            "target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar";
-                        File jar = new File(out, relative.replace('/', File.separatorChar));
-                        if (jar.exists()) {
-                            mJavaClassFolders = Collections.singletonList(jar);
-                            return mJavaClassFolders;
-                        }
-                    }
-                }
-            }
-            if (isAospBuildEnvironment()) {
-                String top = getAospTop();
-                if (mDir.getAbsolutePath().startsWith(top)) {
-                    mJavaClassFolders = getAospJavaClassPath();
-                    return mJavaClassFolders;
-                }
-            }
-
-            mJavaClassFolders = mClient.getJavaClassFolders(this);
-        }
-        return mJavaClassFolders;
-    }
-
-    /**
-     * Returns the list of Java libraries (typically .jar files) that this
-     * project depends on. Note that this refers to jar libraries, not Android
-     * library projects which are processed in a separate pass with their own
-     * source and class folders.
-     *
-     * @param includeProvided If true, included provided libraries too (libraries
-     *                        that are not packaged with the app, but are provided
-     *                        for compilation purposes and are assumed to be present
-     *                        in the running environment)
-     * @return a list of .jar files (or class folders) that this project depends
-     *         on.
-     */
-    @NonNull
-    public List<File> getJavaLibraries(boolean includeProvided) {
-        if (includeProvided) {
-            if (mJavaLibraries == null) {
-                // AOSP builds already merge libraries and class folders into
-                // the single classes.jar file, so these have already been processed
-                // in getJavaClassFolders.
-                mJavaLibraries = mClient.getJavaLibraries(this, true);
-                if (isAospBuildEnvironment()) {
-                    // We still need to add the support-annotations library in the case of AOSP
-                    File out = new File(getAospTop(), "out");
-                    String relative = "target/common/obj/JAVA_LIBRARIES/"
-                            + "android-support-annotations_intermediates/classes";
-                    File annotationsDir = new File(out, relative.replace('/', File.separatorChar));
-                    if (annotationsDir.exists()) {
-                        mJavaLibraries.add(annotationsDir);
-                    }
-                }
-            }
-            return mJavaLibraries;
-        } else {
-            if (mNonProvidedJavaLibraries == null) {
-                mNonProvidedJavaLibraries = mClient.getJavaLibraries(this, false);
-            }
-            return mNonProvidedJavaLibraries;
-        }
-    }
-
-    /**
-     * Returns the list of source folders for Java test source files
-     *
-     * @return a list of source folders to search for .java files
-     */
-    @NonNull
-    public List<File> getTestSourceFolders() {
-        if (mTestSourceFolders == null) {
-            mTestSourceFolders = mClient.getTestSourceFolders(this);
-        }
-
-        return mTestSourceFolders;
-    }
-
-    /**
-     * Returns the resource folders.
-     *
-     * @return a list of files pointing to the resource folders, which might be empty if the project
-     * does not provide any resources.
-     */
-    @NonNull
-    public List<File> getResourceFolders() {
-        if (mResourceFolders == null) {
-            List<File> folders = mClient.getResourceFolders(this);
-
-            if (folders.size() == 1 && isAospFrameworksRelatedProject(mDir)) {
-                // No manifest file for this project: just init the manifest values here
-                mManifestMinSdk = mManifestTargetSdk = new AndroidVersion(HIGHEST_KNOWN_API, null);
-                File folder = new File(folders.get(0), RES_FOLDER);
-                if (!folder.exists()) {
-                    folders = Collections.emptyList();
-                }
-            }
-
-            mResourceFolders = folders;
-        }
-
-        return mResourceFolders;
-    }
-
-    /**
-     * Returns the asset folders.
-     *
-     * @return a list of files pointing to the asset folders, which might be empty if the project
-     * does not provide any resources.
-     */
-    @NonNull
-    public List<File> getAssetFolders() {
-        if (mAssetFolders == null) {
-            mAssetFolders = mClient.getAssetFolders(this);
-        }
-
-        return mAssetFolders;
-    }
-
-    /**
-     * Returns the relative path of a given file relative to the user specified
-     * directory (which is often the project directory but sometimes a higher up
-     * directory when a directory tree is being scanned
-     *
-     * @param file the file under this project to check
-     * @return the path relative to the reference directory (often the project directory)
-     */
-    @NonNull
-    public String getDisplayPath(@NonNull File file) {
-       String path = file.getPath();
-       String referencePath = mReferenceDir.getPath();
-       if (path.startsWith(referencePath)) {
-           int length = referencePath.length();
-           if (path.length() > length && path.charAt(length) == File.separatorChar) {
-               length++;
-           }
-
-           return path.substring(length);
-       }
-
-       return path;
-    }
-
-    /**
-     * Returns the relative path of a given file within the current project.
-     *
-     * @param file the file under this project to check
-     * @return the path relative to the project
-     */
-    @NonNull
-    public String getRelativePath(@NonNull File file) {
-       String path = file.getPath();
-       String referencePath = mDir.getPath();
-       if (path.startsWith(referencePath)) {
-           int length = referencePath.length();
-           if (path.length() > length && path.charAt(length) == File.separatorChar) {
-               length++;
-           }
-
-           return path.substring(length);
-       }
-
-       return path;
-    }
-
-    /**
-     * Returns the project root directory
-     *
-     * @return the dir
-     */
-    @NonNull
-    public File getDir() {
-        return mDir;
-    }
-
-    /**
-     * Returns the original user supplied directory where the lint search
-     * started. For example, if you run lint against {@code /tmp/foo}, and it
-     * finds a project to lint in {@code /tmp/foo/dev/src/project1}, then the
-     * {@code dir} is {@code /tmp/foo/dev/src/project1} and the
-     * {@code referenceDir} is {@code /tmp/foo/}.
-     *
-     * @return the reference directory, never null
-     */
-    @NonNull
-    public File getReferenceDir() {
-        return mReferenceDir;
-    }
-
-    /**
-     * Gets the configuration associated with this project
-     *
-     * @param driver the current driver, if any
-     * @return the configuration associated with this project
-     */
-    @NonNull
-    public Configuration getConfiguration(@Nullable LintDriver driver) {
-        if (mConfiguration == null) {
-            mConfiguration = mClient.getConfiguration(this, driver);
-        }
-        return mConfiguration;
-    }
-
-    /**
-     * Returns the application package specified by the manifest
-     *
-     * @return the application package, or null if unknown
-     */
-    @Nullable
-    public String getPackage() {
-        return mPackage;
-    }
-
-    /**
-     * Returns the minimum API level for the project
-     *
-     * @return the minimum API level or {@link AndroidVersion#DEFAULT} if unknown
-     */
-    @NonNull
-    public AndroidVersion getMinSdkVersion() {
-        return mManifestMinSdk == null ? AndroidVersion.DEFAULT : mManifestMinSdk;
-    }
-
-    /**
-     * Returns the minimum API <b>level</b> requested by the manifest, or -1 if not
-     * specified. Use {@link #getMinSdkVersion()} to get a full version if you need
-     * to check if the platform is a preview platform etc.
-     *
-     * @return the minimum API level or -1 if unknown
-     */
-    public int getMinSdk() {
-        AndroidVersion version = getMinSdkVersion();
-        return version == AndroidVersion.DEFAULT ? -1 : version.getApiLevel();
-    }
-
-    /**
-     * Returns the target API level for the project
-     *
-     * @return the target API level or {@link AndroidVersion#DEFAULT} if unknown
-     */
-    @NonNull
-    public AndroidVersion getTargetSdkVersion() {
-        return mManifestTargetSdk == AndroidVersion.DEFAULT
-                ? getMinSdkVersion() : mManifestTargetSdk;
-    }
-
-    /**
-     * Returns the target API <b>level</b> specified by the manifest, or -1 if not
-     * specified. Use {@link #getTargetSdkVersion()} to get a full version if you need
-     * to check if the platform is a preview platform etc.
-     *
-     * @return the target API level or -1 if unknown
-     */
-    public int getTargetSdk() {
-        AndroidVersion version = getTargetSdkVersion();
-        return version == AndroidVersion.DEFAULT ? -1 : version.getApiLevel();
-    }
-
-    /**
-     * Returns the target API used to build the project, or -1 if not known
-     *
-     * @return the build target API or -1 if unknown
-     */
-    public int getBuildSdk() {
-        return mBuildSdk;
-    }
-
-    /**
-     * Returns the specific version of the build tools being used, if known
-     *
-     * @return the build tools version in use, or null if not known
-     */
-    @Nullable
-    public BuildToolInfo getBuildTools() {
-        if (mBuildTools == null) {
-            mBuildTools = mClient.getBuildTools(this);
-        }
-
-        return mBuildTools;
-    }
-
-    /**
-     * Returns the target used to build the project, or null if not known
-     *
-     * @return the build target, or null
-     */
-    @Nullable
-    public IAndroidTarget getBuildTarget() {
-        if (mTarget == null) {
-            mTarget = mClient.getCompileTarget(this);
-        }
-
-        return mTarget;
-    }
-
-    /**
-     * Initialized the manifest state from the given manifest model
-     *
-     * @param document the DOM document for the manifest XML document
-     */
-    public void readManifest(@NonNull Document document) {
-        Element root = document.getDocumentElement();
-        if (root == null) {
-            return;
-        }
-
-        mPackage = root.getAttribute(ATTR_PACKAGE);
-
-        // Treat support libraries as non-reportable (in Eclipse where we don't
-        // have binary libraries, the support libraries have to be source-copied into
-        // the workspace which then triggers warnings in these libraries that users
-        // shouldn't have to investigate)
-        if (mPackage != null && mPackage.startsWith("android.support.")) {
-            mReportIssues = false;
-        }
-
-        // Initialize minSdk and targetSdk
-        mManifestMinSdk = AndroidVersion.DEFAULT;
-        mManifestTargetSdk = AndroidVersion.DEFAULT;
-        NodeList usesSdks = root.getElementsByTagName(TAG_USES_SDK);
-        if (usesSdks.getLength() > 0) {
-            Element element = (Element) usesSdks.item(0);
-
-            String minSdk = null;
-            if (element.hasAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION)) {
-                minSdk = element.getAttributeNS(ANDROID_URI, ATTR_MIN_SDK_VERSION);
-            }
-            if (minSdk != null) {
-                IAndroidTarget[] targets = mClient.getTargets();
-                mManifestMinSdk = SdkVersionInfo.getVersion(minSdk, targets);
-            }
-
-            if (element.hasAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION)) {
-                String targetSdk = element.getAttributeNS(ANDROID_URI, ATTR_TARGET_SDK_VERSION);
-                if (targetSdk != null) {
-                    IAndroidTarget[] targets = mClient.getTargets();
-                    mManifestTargetSdk = SdkVersionInfo.getVersion(targetSdk, targets);
-                }
-            } else {
-                mManifestTargetSdk = mManifestMinSdk;
-            }
-        } else if (isAospBuildEnvironment()) {
-            extractAospMinSdkVersion();
-            mManifestTargetSdk = mManifestMinSdk;
-        }
-    }
-
-    /**
-     * Returns true if this project is an Android library project
-     *
-     * @return true if this project is an Android library project
-     */
-    public boolean isLibrary() {
-        return mLibrary;
-    }
-
-    /**
-     * Returns the list of library projects referenced by this project
-     *
-     * @return the list of library projects referenced by this project, never
-     *         null
-     */
-    @NonNull
-    public List<Project> getDirectLibraries() {
-        return mDirectLibraries != null ? mDirectLibraries : Collections.<Project>emptyList();
-    }
-
-    /**
-     * Returns the transitive closure of the library projects for this project
-     *
-     * @return the transitive closure of the library projects for this project
-     */
-    @NonNull
-    public List<Project> getAllLibraries() {
-        if (mAllLibraries == null) {
-            if (mDirectLibraries.isEmpty()) {
-                return mDirectLibraries;
-            }
-
-            List<Project> all = new ArrayList<Project>();
-            Set<Project> seen = Sets.newHashSet();
-            Set<Project> path = Sets.newHashSet();
-            seen.add(this);
-            path.add(this);
-            addLibraryProjects(all, seen, path);
-            mAllLibraries = all;
-        }
-
-        return mAllLibraries;
-    }
-
-    /**
-     * Adds this project's library project and their library projects
-     * recursively into the given collection of projects
-     *
-     * @param collection the collection to add the projects into
-     * @param seen full set of projects we've processed
-     * @param path the current path of library dependencies followed
-     */
-    private void addLibraryProjects(@NonNull Collection<Project> collection,
-            @NonNull Set<Project> seen, @NonNull Set<Project> path) {
-        for (Project library : mDirectLibraries) {
-            if (seen.contains(library)) {
-                if (path.contains(library)) {
-                    mClient.log(Severity.WARNING, null,
-                            "Internal lint error: cyclic library dependency for %1$s", library);
-                }
-                continue;
-            }
-            collection.add(library);
-            seen.add(library);
-            path.add(library);
-            // Recurse
-            library.addLibraryProjects(collection, seen, path);
-            path.remove(library);
-        }
-    }
-
-    /**
-     * Gets the SDK info for the current project.
-     *
-     * @return the SDK info for the current project, never null
-     */
-    @NonNull
-    public SdkInfo getSdkInfo() {
-        if (mSdkInfo == null) {
-            mSdkInfo = mClient.getSdkInfo(this);
-        }
-
-        return mSdkInfo;
-    }
-
-    /**
-     * Gets the paths to the manifest files in this project, if any exists. The manifests
-     * should be provided such that the main manifest comes first, then any flavor versions,
-     * then any build types.
-     *
-     * @return the path to the manifest file, or null if it does not exist
-     */
-    @NonNull
-    public List<File> getManifestFiles() {
-        if (mManifestFiles == null) {
-            File manifestFile = new File(mDir, ANDROID_MANIFEST_XML);
-            if (manifestFile.exists()) {
-                mManifestFiles = Collections.singletonList(manifestFile);
-            } else {
-                mManifestFiles = Collections.emptyList();
-            }
-        }
-
-        return mManifestFiles;
-    }
-
-    /**
-     * Returns the proguard files configured for this project, if any
-     *
-     * @return the proguard files, if any
-     */
-    @NonNull
-    public List<File> getProguardFiles() {
-        if (mProguardFiles == null) {
-            List<File> files = new ArrayList<File>();
-            if (mProguardPath != null) {
-                Splitter splitter = Splitter.on(CharMatcher.anyOf(":;")); //$NON-NLS-1$
-                for (String path : splitter.split(mProguardPath)) {
-                    if (path.contains("${")) { //$NON-NLS-1$
-                        // Don't analyze the global/user proguard files
-                        continue;
-                    }
-                    File file = new File(path);
-                    if (!file.isAbsolute()) {
-                        file = new File(getDir(), path);
-                    }
-                    if (file.exists()) {
-                        files.add(file);
-                    }
-                }
-            }
-            if (files.isEmpty()) {
-                File file = new File(getDir(), OLD_PROGUARD_FILE);
-                if (file.exists()) {
-                    files.add(file);
-                }
-                file = new File(getDir(), FN_PROJECT_PROGUARD_FILE);
-                if (file.exists()) {
-                    files.add(file);
-                }
-            }
-            mProguardFiles = files;
-        }
-        return mProguardFiles;
-    }
-
-    /**
-     * Returns the Gradle build script files configured for this project, if any
-     *
-     * @return the Gradle files, if any
-     */
-    @NonNull
-    public List<File> getGradleBuildScripts() {
-        if (mGradleFiles == null) {
-            if (isGradleProject()) {
-                mGradleFiles = Lists.newArrayListWithExpectedSize(2);
-                File build = new File(mDir, SdkConstants.FN_BUILD_GRADLE);
-                if (build.exists()) {
-                    mGradleFiles.add(build);
-                }
-                File settings = new File(mDir, SdkConstants.FN_SETTINGS_GRADLE);
-                if (settings.exists()) {
-                    mGradleFiles.add(settings);
-                }
-            } else {
-                mGradleFiles = Collections.emptyList();
-            }
-        }
-
-        return mGradleFiles;
-    }
-
-    /**
-     * Returns the name of the project
-     *
-     * @return the name of the project, never null
-     */
-    @NonNull
-    public String getName() {
-        if (mName == null) {
-            mName = mClient.getProjectName(this);
-        }
-
-        return mName;
-    }
-
-    /**
-     * Sets the name of the project
-     *
-     * @param name the name of the project, never null
-     */
-    public void setName(@NonNull String name) {
-        assert !name.isEmpty();
-        mName = name;
-    }
-
-    /**
-     * Sets whether lint should report issues in this project. See
-     * {@link #getReportIssues()} for a full description of what that means.
-     *
-     * @param reportIssues whether lint should report issues in this project
-     */
-    public void setReportIssues(boolean reportIssues) {
-        mReportIssues = reportIssues;
-    }
-
-    /**
-     * Returns whether lint should report issues in this project.
-     * <p>
-     * If a user specifies a project and its library projects for analysis, then
-     * those library projects are all "included", and all errors found in all
-     * the projects are reported. But if the user is only running lint on the
-     * main project, we shouldn't report errors in any of the library projects.
-     * We still need to <b>consider</b> them for certain types of checks, such
-     * as determining whether resources found in the main project are unused, so
-     * the detectors must still get a chance to look at these projects. The
-     * {@code #getReportIssues()} attribute is used for this purpose.
-     *
-     * @return whether lint should report issues in this project
-     */
-    public boolean getReportIssues() {
-        return mReportIssues;
-    }
-
-    /**
-     * Returns whether manifest merging is in effect
-     *
-     * @return true if manifests in library projects should be merged into main projects
-     */
-    public boolean isMergingManifests() {
-        return mMergeManifests;
-    }
-
-
-    // ---------------------------------------------------------------------------
-    // Support for running lint on the AOSP source tree itself
-
-    private static Boolean sAospBuild;
-
-    /** Is lint running in an AOSP build environment */
-    public static boolean isAospBuildEnvironment() {
-        if (sAospBuild == null) {
-            sAospBuild = getAospTop() != null;
-        }
-
-        return sAospBuild;
-    }
-
-    /**
-     * Is this the frameworks or related AOSP project? Needs some hardcoded support since
-     * it doesn't have a manifest file, etc.
-     *
-     * A frameworks AOSP projects can be any directory under "frameworks" that
-     * 1. Is not the "support" directory (which uses the public support annotations)
-     * 2. Doesn't have an AndroidManifest.xml (it's an app instead)
-     *
-     * @param dir the project directory to check
-     * @return true if this looks like the frameworks/dir project and does not have
-     *         an AndroidManifest.xml
-     */
-    public static boolean isAospFrameworksRelatedProject(@NonNull File dir) {
-        if (isAospBuildEnvironment()) {
-            File frameworks = new File(getAospTop(), "frameworks"); //$NON-NLS-1$
-            String frameworksDir = frameworks.getAbsolutePath();
-            String supportDir = new File(frameworks, "support").getAbsolutePath(); //$NON-NLS-1$
-            if (dir.exists()
-                    && !dir.getAbsolutePath().startsWith(supportDir)
-                    && dir.getAbsolutePath().startsWith(frameworksDir)
-                    && !(new File(dir, FN_ANDROID_MANIFEST_XML).exists())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Is this the actual frameworks project.
-     * @param dir the project directory to check.
-     * @return true if this is the frameworks project.
-     */
-    public static boolean isAospFrameworksProject(@NonNull File dir) {
-        String top = getAospTop();
-        if (top != null) {
-            File toCompare = new File(top, "frameworks" //$NON-NLS-1$
-                    + File.separator + "base"           //$NON-NLS-1$
-                    + File.separator + "core");         //$NON-NLS-1$
-            try {
-                return dir.getCanonicalFile().equals(toCompare) && dir.exists();
-            } catch (IOException e) {
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    /** Get the root AOSP dir, if any */
-    private static String getAospTop() {
-        return System.getenv("ANDROID_BUILD_TOP");   //$NON-NLS-1$
-    }
-
-    /** Get the host out directory in AOSP, if any */
-    private static String getAospHostOut() {
-        return System.getenv("ANDROID_HOST_OUT");    //$NON-NLS-1$
-    }
-
-    /** Get the product out directory in AOSP, if any */
-    private static String getAospProductOut() {
-        return System.getenv("ANDROID_PRODUCT_OUT"); //$NON-NLS-1$
-    }
-
-    private List<File> getAospJavaSourcePath() {
-        List<File> sources = new ArrayList<File>(2);
-        // Normal sources
-        File src = new File(mDir, "src"); //$NON-NLS-1$
-        if (src.exists()) {
-            sources.add(src);
-        }
-
-        // Generates sources
-        for (File dir : getIntermediateDirs()) {
-            File classes = new File(dir, "src"); //$NON-NLS-1$
-            if (classes.exists()) {
-                sources.add(classes);
-            }
-        }
-
-        if (sources.isEmpty()) {
-            mClient.log(null,
-                    "Warning: Could not find sources or generated sources for project %1$s",
-                    getName());
-        }
-
-        return sources;
-    }
-
-    private List<File> getAospJavaClassPath() {
-        List<File> classDirs = new ArrayList<File>(1);
-
-        for (File dir : getIntermediateDirs()) {
-            File classes = new File(dir, "classes"); //$NON-NLS-1$
-            if (classes.exists()) {
-                classDirs.add(classes);
-            } else {
-                classes = new File(dir, "classes.jar"); //$NON-NLS-1$
-                if (classes.exists()) {
-                    classDirs.add(classes);
-                }
-            }
-        }
-
-        if (classDirs.isEmpty()) {
-            mClient.log(null,
-                    "No bytecode found: Has the project been built? (%1$s)", getName());
-        }
-
-        return classDirs;
-    }
-
-    /** Find the _intermediates directories for a given module name */
-    private List<File> getIntermediateDirs() {
-        // See build/core/definitions.mk and in particular the "intermediates-dir-for" definition
-        List<File> intermediates = new ArrayList<File>();
-
-        // TODO: Look up the module name, e.g. LOCAL_MODULE. However,
-        // some Android.mk files do some complicated things with it - and most
-        // projects use the same module name as the directory name.
-        String moduleName = mDir.getName();
-        try {
-            // Get the actual directory name instead of '.' that's possible
-            // when using this via CLI.
-            moduleName = mDir.getCanonicalFile().getName();
-        } catch (IOException ioe) {
-            // pass
-        }
-
-        String top = getAospTop();
-        final String[] outFolders = new String[] {
-            top + "/out/host/common/obj",             //$NON-NLS-1$
-            top + "/out/target/common/obj",           //$NON-NLS-1$
-            getAospHostOut() + "/obj",                //$NON-NLS-1$
-            getAospProductOut() + "/obj"              //$NON-NLS-1$
-        };
-        final String[] moduleClasses = new String[] {
-                "APPS",                //$NON-NLS-1$
-                "JAVA_LIBRARIES",      //$NON-NLS-1$
-        };
-
-        for (String out : outFolders) {
-            assert new File(out.replace('/', File.separatorChar)).exists() : out;
-            for (String moduleClass : moduleClasses) {
-                String path = out + '/' + moduleClass + '/' + moduleName
-                        + "_intermediates"; //$NON-NLS-1$
-                File file = new File(path.replace('/', File.separatorChar));
-                if (file.exists()) {
-                    intermediates.add(file);
-                }
-            }
-        }
-
-        return intermediates;
-    }
-
-    private void extractAospMinSdkVersion() {
-        // Is the SDK level specified by a Makefile?
-        boolean found = false;
-        File makefile = new File(mDir, "Android.mk"); //$NON-NLS-1$
-        if (makefile.exists()) {
-            try {
-                List<String> lines = Files.readLines(makefile, Charsets.UTF_8);
-                Pattern p = Pattern.compile("LOCAL_SDK_VERSION\\s*:=\\s*(.*)"); //$NON-NLS-1$
-                for (String line : lines) {
-                    line = line.trim();
-                    Matcher matcher = p.matcher(line);
-                    if (matcher.matches()) {
-                        found = true;
-                        String version = matcher.group(1);
-                        if (version.equals("current")) { //$NON-NLS-1$
-                            mManifestMinSdk = findCurrentAospVersion();
-                        } else {
-                            mManifestMinSdk = SdkVersionInfo.getVersion(version,
-                                    mClient.getTargets());
-                        }
-                        break;
-                    }
-                }
-            } catch (IOException ioe) {
-                mClient.log(ioe, null);
-            }
-        }
-
-        if (!found) {
-            mManifestMinSdk = findCurrentAospVersion();
-        }
-    }
-
-    /** Cache for {@link #findCurrentAospVersion()} */
-    private static AndroidVersion sCurrentVersion;
-
-    /** In an AOSP build environment, identify the currently built image version, if available */
-    private static AndroidVersion findCurrentAospVersion() {
-        if (sCurrentVersion == null) {
-            File versionMk = new File(getAospTop(), "build/core/version_defaults.mk" //$NON-NLS-1$
-                    .replace('/', File.separatorChar));
-
-            if (!versionMk.exists()) {
-                sCurrentVersion = AndroidVersion.DEFAULT;
-                return sCurrentVersion;
-            }
-            int sdkVersion = LOWEST_ACTIVE_API;
-            try {
-                Pattern p = Pattern.compile("PLATFORM_SDK_VERSION\\s*:=\\s*(.*)");
-                List<String> lines = Files.readLines(versionMk, Charsets.UTF_8);
-                for (String line : lines) {
-                    line = line.trim();
-                    Matcher matcher = p.matcher(line);
-                    if (matcher.matches()) {
-                        String version = matcher.group(1);
-                        try {
-                            sdkVersion = Integer.parseInt(version);
-                        } catch (NumberFormatException nfe) {
-                            // pass
-                        }
-                        break;
-                    }
-                }
-            } catch (IOException io) {
-                // pass
-            }
-            sCurrentVersion = new AndroidVersion(sdkVersion, null);
-        }
-
-        return sCurrentVersion;
-    }
-
-    /**
-     * Returns true if this project depends on the given artifact. Note that
-     * the project doesn't have to be a Gradle project; the artifact is just
-     * an identifier for name a specific library, such as com.android.support:support-v4
-     * to identify the support library
-     *
-     * @param artifact the Gradle/Maven name of a library
-     * @return true if the library is installed, false if it is not, and null if
-     *   we're not sure
-     */
-    @Nullable
-    public Boolean dependsOn(@NonNull String artifact) {
-        if (SUPPORT_LIB_ARTIFACT.equals(artifact)) {
-            if (mSupportLib == null) {
-                for (File file : getJavaLibraries(true)) {
-                    String name = file.getName();
-                    if (name.equals("android-support-v4.jar")      //$NON-NLS-1$
-                            || name.startsWith("support-v4-")) {   //$NON-NLS-1$
-                        mSupportLib = true;
-                        break;
-                    }
-                }
-                if (mSupportLib == null) {
-                    for (Project dependency : getDirectLibraries()) {
-                        Boolean b = dependency.dependsOn(artifact);
-                        if (b != null && b) {
-                            mSupportLib = true;
-                            break;
-                        }
-                    }
-                }
-                if (mSupportLib == null) {
-                    mSupportLib = false;
-                }
-            }
-
-            return mSupportLib;
-        } else if (APPCOMPAT_LIB_ARTIFACT.equals(artifact)) {
-            if (mAppCompat == null) {
-                for (File file : getJavaLibraries(true)) {
-                    String name = file.getName();
-                    if (name.startsWith("appcompat-v7-")) { //$NON-NLS-1$
-                        mAppCompat = true;
-                        break;
-                    }
-                }
-                if (mAppCompat == null) {
-                    for (Project dependency : getDirectLibraries()) {
-                        Boolean b = dependency.dependsOn(artifact);
-                        if (b != null && b) {
-                            mAppCompat = true;
-                            break;
-                        }
-                    }
-                }
-                if (mAppCompat == null) {
-                    mAppCompat = false;
-                }
-            }
-
-            return mAppCompat;
-        }
-
-        return null;
-    }
-
-    private List<String> mCachedApplicableDensities;
-
-    /**
-     * Returns the set of applicable densities for this project. If null, there are no density
-     * restrictions and all densities apply.
-     *
-     * @return the list of specific densities that apply in this project, or null if all densities
-     * apply
-     */
-    @Nullable
-    public List<String> getApplicableDensities() {
-        if (mCachedApplicableDensities == null) {
-            // Use the gradle API to set up relevant densities. For example, if the
-            // build.gradle file contains this:
-            // android {
-            //     defaultConfig {
-            //         resConfigs "nodpi", "hdpi"
-            //     }
-            // }
-            // ...then we should only enforce hdpi densities, not all these others!
-            if (isGradleProject() && getGradleProjectModel() != null &&
-                    getCurrentVariant() != null) {
-                Set<String> relevantDensities = Sets.newHashSet();
-                Variant variant = getCurrentVariant();
-                List<String> variantFlavors = variant.getProductFlavors();
-                AndroidProject gradleProjectModel = getGradleProjectModel();
-
-                addResConfigsFromFlavor(relevantDensities, null,
-                        getGradleProjectModel().getDefaultConfig());
-                for (ProductFlavorContainer container : gradleProjectModel.getProductFlavors()) {
-                    addResConfigsFromFlavor(relevantDensities, variantFlavors, container);
-                }
-
-                // Are there any splits that specify densities?
-                if (relevantDensities.isEmpty()) {
-                    AndroidArtifact mainArtifact = variant.getMainArtifact();
-                    Collection<AndroidArtifactOutput> outputs = mainArtifact.getOutputs();
-                    for (AndroidArtifactOutput output : outputs) {
-                        for (OutputFile file : output.getOutputs()) {
-                            final String DENSITY_NAME = OutputFile.FilterType.DENSITY.name();
-                            if (file.getFilterTypes().contains(DENSITY_NAME)) {
-                                for (FilterData data : file.getFilters()) {
-                                    if (DENSITY_NAME.equals(data.getFilterType())) {
-                                        relevantDensities.add(data.getIdentifier());
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                if (!relevantDensities.isEmpty()) {
-                    mCachedApplicableDensities = Lists.newArrayListWithExpectedSize(10);
-                    for (String density : relevantDensities) {
-                        String folder = ResourceFolderType.DRAWABLE.getName() + '-' + density;
-                        mCachedApplicableDensities.add(folder);
-                    }
-                    Collections.sort(mCachedApplicableDensities);
-                } else {
-                    mCachedApplicableDensities = Collections.emptyList();
-                }
-            } else {
-                mCachedApplicableDensities = Collections.emptyList();
-            }
-        }
-
-        return mCachedApplicableDensities.isEmpty() ? null : mCachedApplicableDensities;
-    }
-
-    /**
-     * Returns a super class map for this project. The keys and values are internal
-     * class names (e.g. java/lang/Integer, not java.lang.Integer).
-     * @return a map, possibly empty but never null
-     */
-    @NonNull
-    public Map<String, String> getSuperClassMap() {
-        if (mSuperClassMap == null) {
-            mSuperClassMap = mClient.createSuperClassMap(this);
-        }
-
-        return mSuperClassMap;
-    }
-
-    /**
-     * Adds in the resConfig values specified by the given flavor container, assuming
-     * it's in one of the relevant variantFlavors, into the given set
-     */
-    private static void addResConfigsFromFlavor(@NonNull Set<String> relevantDensities,
-            @Nullable List<String> variantFlavors,
-            @NonNull ProductFlavorContainer container) {
-        ProductFlavor flavor = container.getProductFlavor();
-        if (variantFlavors == null || variantFlavors.contains(flavor.getName())) {
-            if (!flavor.getResourceConfigurations().isEmpty()) {
-                for (String densityName : flavor.getResourceConfigurations()) {
-                    Density density = Density.getEnum(densityName);
-                    if (density != null && density.isRecommended()
-                            && density != Density.NODPI && density != Density.ANYDPI) {
-                        relevantDensities.add(densityName);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns a shared {@link ResourceVisibilityLookup}
-     *
-     * @return a shared provider for looking up resource visibility
-     */
-    @NonNull
-    public ResourceVisibilityLookup getResourceVisibility() {
-        if (mResourceVisibility == null) {
-            if (isGradleProject()) {
-                AndroidProject project = getGradleProjectModel();
-                Variant variant = getCurrentVariant();
-                if (project != null && variant != null) {
-                    mResourceVisibility = mClient.getResourceVisibilityProvider().get(project,
-                            variant);
-
-                } else if (getGradleLibraryModel() != null) {
-                    try {
-                        mResourceVisibility = mClient.getResourceVisibilityProvider()
-                                .get(getGradleLibraryModel());
-                    } catch (Exception ignore) {
-                        // Handle talking to older Gradle plugins (where we don't
-                        // have access to the model version to check up front
-                    }
-                }
-            }
-            if (mResourceVisibility == null) {
-                mResourceVisibility = ResourceVisibilityLookup.NONE;
-            }
-        }
-
-        return mResourceVisibility;
-    }
-
-    /**
-     * Returns the associated client
-     *
-     * @return the client
-     */
-    @NonNull
-    public LintClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns the compile target to use for this project
-     *
-     * @return the compile target to use to build this project
-     */
-    @Nullable
-    public IAndroidTarget getCompileTarget() {
-        return mClient.getCompileTarget(this);
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceContext.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceContext.java
deleted file mode 100644
index 33fd684..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceContext.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.tools.klint.client.api.LintDriver;
-import com.google.common.annotations.Beta;
-
-import java.io.File;
-
-/**
- * A {@link com.android.tools.lint.detector.api.Context} used when checking resource files
- * (both bitmaps and XML files; for XML files a subclass of this context is used:
- * {@link com.android.tools.lint.detector.api.XmlContext}.)
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class ResourceContext extends Context {
-    private final ResourceFolderType mFolderType;
-
-    /**
-     * Construct a new {@link com.android.tools.lint.detector.api.ResourceContext}
-     *
-     * @param driver the driver running through the checks
-     * @param project the project containing the file being checked
-     * @param main the main project if this project is a library project, or
-     *            null if this is not a library project. The main project is
-     *            the root project of all library projects, not necessarily the
-     *            directly including project.
-     * @param file the file being checked
-     * @param folderType the {@link com.android.resources.ResourceFolderType} of this file, if any
-     */
-    public ResourceContext(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File file,
-            @Nullable ResourceFolderType folderType) {
-        super(driver, project, main, file);
-        mFolderType = folderType;
-    }
-
-    /**
-     * Returns the resource folder type of this XML file, if any.
-     *
-     * @return the resource folder type or null
-     */
-    @Nullable
-    public ResourceFolderType getResourceFolderType() {
-        return mFolderType;
-    }
-
-    /**
-     * Returns the folder version. For example, for the file values-v14/foo.xml,
-     * it returns 14.
-     *
-     * @return the folder version, or -1 if no specific version was specified
-     */
-    public int getFolderVersion() {
-        return mDriver.getResourceFolderVersion(file);
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceEvaluator.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceEvaluator.java
deleted file mode 100644
index 9b3368e..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceEvaluator.java
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * 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.klint.detector.api;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.ANDROID_PKG_PREFIX;
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.SdkConstants.CLASS_FRAGMENT;
-import static com.android.SdkConstants.CLASS_RESOURCES;
-import static com.android.SdkConstants.CLASS_V4_FRAGMENT;
-import static com.android.SdkConstants.R_CLASS;
-import static com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX;
-import static com.android.tools.klint.client.api.UastLintUtils.toAndroidReferenceViaResolve;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceUrl;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.AndroidReference;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiAssignmentExpression;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiConditionalExpression;
-import com.intellij.psi.PsiDeclarationStatement;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiExpressionStatement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiLocalVariable;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiModifierListOwner;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiParenthesizedExpression;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiReferenceExpression;
-import com.intellij.psi.PsiStatement;
-import com.intellij.psi.PsiVariable;
-import com.intellij.psi.util.PsiTreeUtil;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UIfExpression;
-import org.jetbrains.uast.UParenthesizedExpression;
-import org.jetbrains.uast.UQualifiedReferenceExpression;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.UReferenceExpression;
-
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Locale;
-
-/** Evaluates constant expressions */
-public class ResourceEvaluator {
-
-    /**
-     * Marker ResourceType used to signify that an expression is of type {@code @ColorInt},
-     * which isn't actually a ResourceType but one we want to specifically compare with.
-     * We're using {@link ResourceType#PUBLIC} because that one won't appear in the R
-     * class (and ResourceType is an enum we can't just create new constants for.)
-     */
-    public static final ResourceType COLOR_INT_MARKER_TYPE = ResourceType.PUBLIC;
-    /**
-     * Marker ResourceType used to signify that an expression is of type {@code @Px},
-     * which isn't actually a ResourceType but one we want to specifically compare with.
-     * We're using {@link ResourceType#DECLARE_STYLEABLE} because that one doesn't
-     * have a corresponding {@code *Res} constant (and ResourceType is an enum we can't
-     * just create new constants for.)
-     */
-    public static final ResourceType PX_MARKER_TYPE = ResourceType.DECLARE_STYLEABLE;
-
-    public static final String COLOR_INT_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "ColorInt"; //$NON-NLS-1$
-    public static final String PX_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "Px"; //$NON-NLS-1$
-    public static final String RES_SUFFIX = "Res";
-    
-    public static final String CLS_TYPED_ARRAY = "android.content.res.TypedArray";
-
-    private final JavaContext mContext;
-    private final JavaEvaluator mEvaluator;
-    
-    private boolean mAllowDereference = true;
-
-    /**
-     * Creates a new resource evaluator
-     *
-     * @param context Java context
-     */
-    public ResourceEvaluator(JavaContext context) {
-        mContext = context;
-        mEvaluator = context.getEvaluator();
-    }
-
-    /**
-     * Whether we allow dereferencing resources when computing constants;
-     * e.g. if we ask for the resource for {@code x} when the code is
-     * {@code x = getString(R.string.name)}, if {@code allowDereference} is
-     * true we'll return R.string.name, otherwise we'll return null.
-     *
-     * @return this for constructor chaining
-     */
-    public ResourceEvaluator allowDereference(boolean allow) {
-        mAllowDereference = allow;
-        return this;
-    }
-
-    /**
-     * Evaluates the given node and returns the resource reference (type and name) it
-     * points to, if any
-     *
-     * @param context Java context
-     * @param element the node to compute the constant value for
-     * @return the corresponding resource url (type and name)
-     */
-    @Nullable
-    public static ResourceUrl getResource(
-            @NonNull JavaContext context,
-            @NonNull PsiElement element) {
-        return new ResourceEvaluator(context).getResource(element);
-    }
-
-    /**
-     * Evaluates the given node and returns the resource reference (type and name) it
-     * points to, if any
-     *
-     * @param context Java context
-     * @param element the node to compute the constant value for
-     * @return the corresponding resource url (type and name)
-     */
-    @Nullable
-    public static ResourceUrl getResource(
-            @NonNull JavaContext context,
-            @NonNull UElement element) {
-        return new ResourceEvaluator(context).getResource(element);
-    }
-
-    /**
-     * Evaluates the given node and returns the resource types implied by the given element,
-     * if any.
-     *
-     * @param context Java context
-     * @param element the node to compute the constant value for
-     * @return the corresponding resource types
-     */
-    @Nullable
-    public static EnumSet<ResourceType> getResourceTypes(
-            @NonNull JavaContext context,
-            @NonNull PsiElement element) {
-        return new ResourceEvaluator(context).getResourceTypes(element);
-    }
-
-    /**
-     * Evaluates the given node and returns the resource types implied by the given element,
-     * if any.
-     *
-     * @param context Java context
-     * @param element the node to compute the constant value for
-     * @return the corresponding resource types
-     */
-    @Nullable
-    public static EnumSet<ResourceType> getResourceTypes(
-            @NonNull JavaContext context,
-            @NonNull UElement element) {
-        return new ResourceEvaluator(context).getResourceTypes(element);
-    }
-
-    /**
-     * Evaluates the given node and returns the resource reference (type and name) it
-     * points to, if any
-     *
-     * @param element the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    @Nullable
-    public ResourceUrl getResource(@Nullable UElement element) {
-        if (element == null) {
-            return null;
-        }
-
-        if (element instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) element;
-            Object known = ConstantEvaluator.evaluate(null, expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return getResource(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return getResource(expression.getElseExpression());
-            }
-        } else if (element instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) element;
-            return getResource(parenthesizedExpression.getExpression());
-        } else if (mAllowDereference && element instanceof UQualifiedReferenceExpression) {
-            UQualifiedReferenceExpression qualifiedExpression = (UQualifiedReferenceExpression) element;
-            UExpression selector = qualifiedExpression.getSelector();
-            if ((selector instanceof UCallExpression)) {
-                UCallExpression call = (UCallExpression) selector;
-                PsiMethod function = call.resolve();
-                PsiClass containingClass = UastUtils.getContainingClass(function);
-                if (function != null && containingClass != null) {
-                    String qualifiedName = containingClass.getQualifiedName();
-                    String name = call.getMethodName();
-                    if ((CLASS_RESOURCES.equals(qualifiedName)
-                            || CLASS_CONTEXT.equals(qualifiedName)
-                            || CLASS_FRAGMENT.equals(qualifiedName)
-                            || CLASS_V4_FRAGMENT.equals(qualifiedName)
-                            || CLS_TYPED_ARRAY.equals(qualifiedName))
-                            && name != null
-                            && name.startsWith("get")) {
-                        List<UExpression> args = call.getValueArguments();
-                        if (!args.isEmpty()) {
-                            return getResource(args.get(0));
-                        }
-                    }
-                }
-            }
-        }
-
-        if (element instanceof UReferenceExpression) {
-            ResourceUrl url = getResourceConstant(element);
-            if (url != null) {
-                return url;
-            }
-            PsiElement resolved = ((UReferenceExpression) element).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                UElement lastAssignment =
-                        UastLintUtils.findLastAssignment(
-                                variable, element, mContext);
-
-                if (lastAssignment != null) {
-                    return getResource(lastAssignment);
-                }
-
-                return null;
-            }
-        }
-
-        return null;
-    }
-    
-    /**
-     * Evaluates the given node and returns the resource reference (type and name) it
-     * points to, if any
-     *
-     * @param element the node to compute the constant value for
-     * @return the corresponding constant value - a String, an Integer, a Float, and so on
-     */
-    
-    @Nullable
-    public ResourceUrl getResource(@Nullable PsiElement element) {
-        if (element == null) {
-            return null;
-        }
-        if (element instanceof PsiConditionalExpression) {
-            PsiConditionalExpression expression = (PsiConditionalExpression) element;
-            Object known = ConstantEvaluator.evaluate(null, expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return getResource(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return getResource(expression.getElseExpression());
-            }
-        } else if (element instanceof PsiParenthesizedExpression) {
-            PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) element;
-            return getResource(parenthesizedExpression.getExpression());
-        } else if (element instanceof PsiMethodCallExpression && mAllowDereference) {
-            PsiMethodCallExpression call = (PsiMethodCallExpression) element;
-            PsiReferenceExpression expression = call.getMethodExpression();
-            PsiMethod method = call.resolveMethod();
-            if (method != null && method.getContainingClass() != null) {
-                String qualifiedName = method.getContainingClass().getQualifiedName();
-                String name = expression.getReferenceName();
-                if ((CLASS_RESOURCES.equals(qualifiedName)
-                        || CLASS_CONTEXT.equals(qualifiedName)
-                        || CLASS_FRAGMENT.equals(qualifiedName)
-                        || CLASS_V4_FRAGMENT.equals(qualifiedName)
-                        || CLS_TYPED_ARRAY.equals(qualifiedName))
-                        && name != null
-                        && name.startsWith("get")) {
-                    PsiExpression[] args = call.getArgumentList().getExpressions();
-                    if (args.length > 0) {
-                        return getResource(args[0]);
-                    }
-                }
-            }
-        } else if (element instanceof PsiReference) {
-            ResourceUrl url = getResourceConstant(element);
-            if (url != null) {
-                return url;
-            }
-            PsiElement resolved = ((PsiReference) element).resolve();
-            if (resolved instanceof PsiField) {
-                url = getResourceConstant(resolved);
-                if (url != null) {
-                    return url;
-                }
-                PsiField field = (PsiField) resolved;
-                if (field.getInitializer() != null) {
-                    return getResource(field.getInitializer());
-                }
-                return null;
-            } else if (resolved instanceof PsiLocalVariable) {
-                PsiLocalVariable variable = (PsiLocalVariable) resolved;
-                PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class,
-                        false);
-                if (statement != null) {
-                    PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement,
-                            PsiStatement.class);
-                    String targetName = variable.getName();
-                    if (targetName == null) {
-                        return null;
-                    }
-                    while (prev != null) {
-                        if (prev instanceof PsiDeclarationStatement) {
-                            PsiDeclarationStatement prevStatement = (PsiDeclarationStatement) prev;
-                            for (PsiElement e : prevStatement.getDeclaredElements()) {
-                                if (variable.equals(e)) {
-                                    return getResource(variable.getInitializer());
-                                }
-                            }
-                        } else if (prev instanceof PsiExpressionStatement) {
-                            PsiExpression expression = ((PsiExpressionStatement) prev)
-                                    .getExpression();
-                            if (expression instanceof PsiAssignmentExpression) {
-                                PsiAssignmentExpression assign
-                                        = (PsiAssignmentExpression) expression;
-                                PsiExpression lhs = assign.getLExpression();
-                                if (lhs instanceof PsiReferenceExpression) {
-                                    PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
-                                    if (targetName.equals(reference.getReferenceName()) &&
-                                            reference.getQualifier() == null) {
-                                        return getResource(assign.getRExpression());
-                                    }
-                                }
-                            }
-                        }
-                        prev = PsiTreeUtil.getPrevSiblingOfType(prev,
-                                PsiStatement.class);
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Evaluates the given node and returns the resource types applicable to the
-     * node, if any.
-     *
-     * @param element the element to compute the types for
-     * @return the corresponding resource types
-     */
-    @Nullable
-    public EnumSet<ResourceType> getResourceTypes(@Nullable UElement element) {
-        if (element == null) {
-            return null;
-        }
-        if (element instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) element;
-            Object known = ConstantEvaluator.evaluate(null, expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return getResourceTypes(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return getResourceTypes(expression.getElseExpression());
-            } else {
-                EnumSet<ResourceType> left = getResourceTypes(
-                        expression.getThenExpression());
-                EnumSet<ResourceType> right = getResourceTypes(
-                        expression.getElseExpression());
-                if (left == null) {
-                    return right;
-                } else if (right == null) {
-                    return left;
-                } else {
-                    EnumSet<ResourceType> copy = EnumSet.copyOf(left);
-                    copy.addAll(right);
-                    return copy;
-                }
-            }
-        } else if (element instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) element;
-            return getResourceTypes(parenthesizedExpression.getExpression());
-        } else if ((element instanceof UQualifiedReferenceExpression && mAllowDereference)
-                || element instanceof UCallExpression) {
-            UElement probablyCallExpression = element;
-            if (element instanceof UQualifiedReferenceExpression) {
-                UQualifiedReferenceExpression qualifiedExpression = 
-                        (UQualifiedReferenceExpression) element;
-                probablyCallExpression = qualifiedExpression.getSelector();
-            }
-            if ((probablyCallExpression instanceof UCallExpression)) {
-                UCallExpression call = (UCallExpression) probablyCallExpression;
-                PsiMethod method = call.resolve();
-                PsiClass containingClass = UastUtils.getContainingClass(method);
-                if (method != null && containingClass != null) {
-                    EnumSet<ResourceType> types = getTypesFromAnnotations(method);
-                    if (types != null) {
-                        return types;
-                    }
-
-                    String qualifiedName = containingClass.getQualifiedName();
-                    String name = call.getMethodName();
-                    if ((CLASS_RESOURCES.equals(qualifiedName)
-                            || CLASS_CONTEXT.equals(qualifiedName)
-                            || CLASS_FRAGMENT.equals(qualifiedName)
-                            || CLASS_V4_FRAGMENT.equals(qualifiedName)
-                            || CLS_TYPED_ARRAY.equals(qualifiedName))
-                            && name != null
-                            && name.startsWith("get")) {
-                        List<UExpression> args = call.getValueArguments();
-                        if (!args.isEmpty()) {
-                            types = getResourceTypes(args.get(0));
-                            if (types != null) {
-                                return types;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (element instanceof UReferenceExpression) {
-            ResourceUrl url = getResourceConstant(element);
-            if (url != null) {
-                return EnumSet.of(url.type);
-            }
-
-            PsiElement resolved = ((UReferenceExpression) element).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                UElement lastAssignment =
-                        UastLintUtils.findLastAssignment(variable, element, mContext);
-
-                if (lastAssignment != null) {
-                    return getResourceTypes(lastAssignment);
-                }
-
-                return null;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Evaluates the given node and returns the resource types applicable to the
-     * node, if any.
-     *
-     * @param element the element to compute the types for
-     * @return the corresponding resource types
-     */
-    @Nullable
-    public EnumSet<ResourceType> getResourceTypes(@Nullable PsiElement element) {
-        if (element == null) {
-            return null;
-        }
-        if (element instanceof PsiConditionalExpression) {
-            PsiConditionalExpression expression = (PsiConditionalExpression) element;
-            Object known = ConstantEvaluator.evaluate(null, expression.getCondition());
-            if (known == Boolean.TRUE && expression.getThenExpression() != null) {
-                return getResourceTypes(expression.getThenExpression());
-            } else if (known == Boolean.FALSE && expression.getElseExpression() != null) {
-                return getResourceTypes(expression.getElseExpression());
-            } else {
-                EnumSet<ResourceType> left = getResourceTypes(
-                        expression.getThenExpression());
-                EnumSet<ResourceType> right = getResourceTypes(
-                        expression.getElseExpression());
-                if (left == null) {
-                    return right;
-                } else if (right == null) {
-                    return left;
-                } else {
-                    EnumSet<ResourceType> copy = EnumSet.copyOf(left);
-                    copy.addAll(right);
-                    return copy;
-                }
-            }
-        } else if (element instanceof PsiParenthesizedExpression) {
-            PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression) element;
-            return getResourceTypes(parenthesizedExpression.getExpression());
-        } else if (element instanceof PsiMethodCallExpression && mAllowDereference) {
-            PsiMethodCallExpression call = (PsiMethodCallExpression) element;
-            PsiReferenceExpression expression = call.getMethodExpression();
-            PsiMethod method = call.resolveMethod();
-            if (method != null && method.getContainingClass() != null) {
-                EnumSet<ResourceType> types = getTypesFromAnnotations(method);
-                if (types != null) {
-                    return types;
-                }
-
-                String qualifiedName = method.getContainingClass().getQualifiedName();
-                String name = expression.getReferenceName();
-                if ((CLASS_RESOURCES.equals(qualifiedName)
-                        || CLASS_CONTEXT.equals(qualifiedName)
-                        || CLASS_FRAGMENT.equals(qualifiedName)
-                        || CLASS_V4_FRAGMENT.equals(qualifiedName)
-                        || CLS_TYPED_ARRAY.equals(qualifiedName))
-                        && name != null
-                        && name.startsWith("get")) {
-                    PsiExpression[] args = call.getArgumentList().getExpressions();
-                    if (args.length > 0) {
-                        types = getResourceTypes(args[0]);
-                        if (types != null) {
-                            return types;
-                        }
-                    }
-                }
-            }
-        } else if (element instanceof PsiReference) {
-            ResourceUrl url = getResourceConstant(element);
-            if (url != null) {
-                return EnumSet.of(url.type);
-            }
-            PsiElement resolved = ((PsiReference) element).resolve();
-            if (resolved instanceof PsiField) {
-                url = getResourceConstant(resolved);
-                if (url != null) {
-                    return EnumSet.of(url.type);
-                }
-                PsiField field = (PsiField) resolved;
-                if (field.getInitializer() != null) {
-                    return getResourceTypes(field.getInitializer());
-                }
-                return null;
-            } else if (resolved instanceof PsiParameter) {
-                return getTypesFromAnnotations((PsiParameter)resolved);
-            } else if (resolved instanceof PsiLocalVariable) {
-                PsiLocalVariable variable = (PsiLocalVariable) resolved;
-                PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class,
-                        false);
-                if (statement != null) {
-                    PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement,
-                            PsiStatement.class);
-                    String targetName = variable.getName();
-                    if (targetName == null) {
-                        return null;
-                    }
-                    while (prev != null) {
-                        if (prev instanceof PsiDeclarationStatement) {
-                            PsiDeclarationStatement prevStatement = (PsiDeclarationStatement) prev;
-                            for (PsiElement e : prevStatement.getDeclaredElements()) {
-                                if (variable.equals(e)) {
-                                    return getResourceTypes(variable.getInitializer());
-                                }
-                            }
-                        } else if (prev instanceof PsiExpressionStatement) {
-                            PsiExpression expression = ((PsiExpressionStatement) prev)
-                                    .getExpression();
-                            if (expression instanceof PsiAssignmentExpression) {
-                                PsiAssignmentExpression assign
-                                        = (PsiAssignmentExpression) expression;
-                                PsiExpression lhs = assign.getLExpression();
-                                if (lhs instanceof PsiReferenceExpression) {
-                                    PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
-                                    if (targetName.equals(reference.getReferenceName()) &&
-                                            reference.getQualifier() == null) {
-                                        return getResourceTypes(assign.getRExpression());
-                                    }
-                                }
-                            }
-                        }
-                        prev = PsiTreeUtil.getPrevSiblingOfType(prev,
-                                PsiStatement.class);
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private EnumSet<ResourceType> getTypesFromAnnotations(PsiModifierListOwner owner) {
-        if (mEvaluator == null) {
-            return null;
-        }
-        for (PsiAnnotation annotation : mEvaluator.getAllAnnotations(owner)) {
-            String signature = annotation.getQualifiedName();
-            if (signature == null) {
-                continue;
-            }
-            if (signature.equals(COLOR_INT_ANNOTATION)) {
-                return EnumSet.of(COLOR_INT_MARKER_TYPE);
-            }
-            if (signature.equals(PX_ANNOTATION)) {
-                return EnumSet.of(PX_MARKER_TYPE);
-            }
-            if (signature.endsWith(RES_SUFFIX)
-                    && signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) {
-                String typeString = signature
-                        .substring(SUPPORT_ANNOTATIONS_PREFIX.length(),
-                                signature.length() - RES_SUFFIX.length())
-                        .toLowerCase(Locale.US);
-                ResourceType type = ResourceType.getEnum(typeString);
-                if (type != null) {
-                    return EnumSet.of(type);
-                } else if (typeString.equals("any")) { // @AnyRes
-                    return getAnyRes();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /** Returns a resource URL based on the field reference in the code */
-    @Nullable
-    public static ResourceUrl getResourceConstant(@NonNull PsiElement node) {
-        // R.type.name
-        if (node instanceof PsiReferenceExpression) {
-            PsiReferenceExpression expression = (PsiReferenceExpression) node;
-            if (expression.getQualifier() instanceof PsiReferenceExpression) {
-                PsiReferenceExpression select = (PsiReferenceExpression) expression.getQualifier();
-                if (select.getQualifier() instanceof PsiReferenceExpression) {
-                    PsiReferenceExpression reference = (PsiReferenceExpression) select
-                            .getQualifier();
-                    if (R_CLASS.equals(reference.getReferenceName())) {
-                        String typeName = select.getReferenceName();
-                        String name = expression.getReferenceName();
-
-                        ResourceType type = ResourceType.getEnum(typeName);
-                        if (type != null && name != null) {
-                            boolean isFramework =
-                                    reference.getQualifier() instanceof PsiReferenceExpression
-                                            && ANDROID_PKG
-                                            .equals(((PsiReferenceExpression) reference.
-                                                    getQualifier()).getReferenceName());
-
-                            return ResourceUrl.create(type, name, isFramework);
-                        }
-                    }
-                }
-            }
-        } else if (node instanceof PsiField) {
-            PsiField field = (PsiField) node;
-            PsiClass typeClass = field.getContainingClass();
-            if (typeClass != null) {
-                PsiClass rClass = typeClass.getContainingClass();
-                if (rClass != null && R_CLASS.equals(rClass.getName())) {
-                    String name = field.getName();
-                    ResourceType type = ResourceType.getEnum(typeClass.getName());
-                    if (type != null && name != null) {
-                        String qualifiedName = rClass.getQualifiedName();
-                        boolean isFramework = qualifiedName != null
-                                && qualifiedName.startsWith(ANDROID_PKG_PREFIX);
-                        return ResourceUrl.create(type, name, isFramework);
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /** Returns a resource URL based on the field reference in the code */
-    @Nullable
-    public static ResourceUrl getResourceConstant(@NonNull UElement node) {
-        AndroidReference androidReference = toAndroidReferenceViaResolve(node);
-        if (androidReference == null) {
-            return null;
-        }
-
-        String name = androidReference.getName();
-        ResourceType type = androidReference.getType();
-        boolean isFramework = androidReference.getPackage().equals("android");
-
-        return ResourceUrl.create(type, name, isFramework);
-    }
-
-    private static EnumSet<ResourceType> getAnyRes() {
-        EnumSet<ResourceType> types = EnumSet.allOf(ResourceType.class);
-        types.remove(ResourceEvaluator.COLOR_INT_MARKER_TYPE);
-        types.remove(ResourceEvaluator.PX_MARKER_TYPE);
-        return types;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceXmlDetector.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceXmlDetector.java
deleted file mode 100644
index 85fdcfc..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ResourceXmlDetector.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.resources.ResourceFolderType;
-import com.google.common.annotations.Beta;
-
-import java.io.File;
-
-/**
- * Specialized detector intended for XML resources. Detectors that apply to XML
- * resources should extend this detector instead since it provides special
- * iteration hooks that are more efficient.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public abstract class ResourceXmlDetector extends Detector implements Detector.XmlScanner {
-    @Override
-    public boolean appliesTo(@NonNull Context context, @NonNull File file) {
-        return LintUtils.isXmlFile(file);
-    }
-
-    /**
-     * Returns whether this detector applies to the given folder type. This
-     * allows the detectors to be pruned from iteration, so for example when we
-     * are analyzing a string value file we don't need to look up detectors
-     * related to layout.
-     *
-     * @param folderType the folder type to be visited
-     * @return true if this detector can apply to resources in folders of the
-     *         given type
-     */
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return true;
-    }
-
-    @Override
-    public void run(@NonNull Context context) {
-        // The infrastructure should never call this method on an xml detector since
-        // it will run the various visitors instead
-        assert false;
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Scope.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Scope.java
deleted file mode 100644
index e8201cf..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Scope.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
-import static com.android.SdkConstants.DOT_CLASS;
-import static com.android.SdkConstants.DOT_GRADLE;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.SdkConstants.DOT_PNG;
-import static com.android.SdkConstants.DOT_PROPERTIES;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
-import static com.android.SdkConstants.OLD_PROGUARD_FILE;
-import static com.android.SdkConstants.RES_FOLDER;
-
-import com.android.annotations.NonNull;
-import com.google.common.annotations.Beta;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-
-/**
- * The scope of a detector is the set of files a detector must consider when
- * performing its analysis. This can be used to determine when issues are
- * potentially obsolete, whether a detector should re-run on a file save, etc.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public enum Scope {
-    /**
-     * The analysis only considers a single XML resource file at a time.
-     * <p>
-     * Issues which are only affected by a single resource file can be checked
-     * for incrementally when a file is edited.
-     */
-    RESOURCE_FILE,
-
-    /**
-     * The analysis only considers a single binary (typically a bitmap) resource file at a time.
-     * <p>
-     * Issues which are only affected by a single resource file can be checked
-     * for incrementally when a file is edited.
-     */
-    BINARY_RESOURCE_FILE,
-
-    /**
-     * The analysis considers the resource folders (which also includes asset folders)
-     */
-    RESOURCE_FOLDER,
-
-    /**
-     * The analysis considers <b>all</b> the resource file. This scope must not
-     * be used in conjunction with {@link #RESOURCE_FILE}; an issue scope is
-     * either considering just a single resource file or all the resources, not
-     * both.
-     */
-    ALL_RESOURCE_FILES,
-
-    /**
-     * The analysis only considers a single Java source file at a time.
-     * <p>
-     * Issues which are only affected by a single Java source file can be
-     * checked for incrementally when a Java source file is edited.
-     */
-    JAVA_FILE,
-
-    /**
-     * The analysis considers <b>all</b> the Java source files together.
-     * <p>
-     * This flag is mutually exclusive with {@link #JAVA_FILE}.
-     */
-    ALL_JAVA_FILES,
-
-    /**
-     * The analysis only considers a single Java class file at a time.
-     * <p>
-     * Issues which are only affected by a single Java class file can be checked
-     * for incrementally when a Java source file is edited and then recompiled.
-     */
-    CLASS_FILE,
-
-    /**
-     * The analysis considers <b>all</b> the Java class files together.
-     * <p>
-     * This flag is mutually exclusive with {@link #CLASS_FILE}.
-     */
-    ALL_CLASS_FILES,
-
-    /** The analysis considers the manifest file */
-    MANIFEST,
-
-    /** The analysis considers the Proguard configuration file */
-    PROGUARD_FILE,
-
-    /**
-     * The analysis considers classes in the libraries for this project. These
-     * will be analyzed before the classes themselves. NOTE: This excludes
-     * provided libraries.
-     */
-    JAVA_LIBRARIES,
-
-    /** The analysis considers a Gradle build file */
-    GRADLE_FILE,
-
-    /** The analysis considers Java property files */
-    PROPERTY_FILE,
-
-    /** The analysis considers test sources as well */
-    TEST_SOURCES,
-
-    /**
-     * Scope for other files. Issues that specify a custom scope will be called unconditionally.
-     * This will call {@link Detector#run(Context)}} on the detectors unconditionally.
-     */
-    OTHER;
-
-    /**
-     * Returns true if the given scope set corresponds to scanning a single file
-     * rather than a whole project
-     *
-     * @param scopes the scope set to check
-     * @return true if the scope set references a single file
-     */
-    public static boolean checkSingleFile(@NonNull EnumSet<Scope> scopes) {
-        int size = scopes.size();
-        if (size == 2) {
-            // When single checking a Java source file, we check both its Java source
-            // and the associated class files
-            return scopes.contains(JAVA_FILE) && scopes.contains(CLASS_FILE);
-        } else {
-            return size == 1 &&
-                (scopes.contains(JAVA_FILE)
-                        || scopes.contains(CLASS_FILE)
-                        || scopes.contains(RESOURCE_FILE)
-                        || scopes.contains(PROGUARD_FILE)
-                        || scopes.contains(PROPERTY_FILE)
-                        || scopes.contains(GRADLE_FILE)
-                        || scopes.contains(MANIFEST));
-        }
-    }
-
-    /**
-     * Returns the intersection of two scope sets
-     *
-     * @param scope1 the first set to intersect
-     * @param scope2 the second set to intersect
-     * @return the intersection of the two sets
-     */
-    @NonNull
-    public static EnumSet<Scope> intersect(
-            @NonNull EnumSet<Scope> scope1,
-            @NonNull EnumSet<Scope> scope2) {
-        EnumSet<Scope> scope = EnumSet.copyOf(scope1);
-        scope.retainAll(scope2);
-
-        return scope;
-    }
-
-    /**
-     * Infers a suitable scope to use from the given projects to be analyzed
-     * @param projects the projects to find a suitable scope for
-     * @return the scope to use
-     */
-    @NonNull
-    public static EnumSet<Scope> infer(@NonNull Collection<Project> projects) {
-        // Infer the scope
-        EnumSet<Scope> scope = EnumSet.noneOf(Scope.class);
-        for (Project project : projects) {
-            List<File> subset = project.getSubset();
-            if (subset != null) {
-                for (File file : subset) {
-                    String name = file.getName();
-                    if (name.equals(ANDROID_MANIFEST_XML)) {
-                        scope.add(MANIFEST);
-                    } else if (name.endsWith(DOT_XML)) {
-                        scope.add(RESOURCE_FILE);
-                    } else if (name.endsWith(".kt")) {
-                        scope.add(JAVA_FILE);
-                    } else if (name.endsWith(DOT_CLASS)) {
-                        scope.add(CLASS_FILE);
-                    } else if (name.endsWith(DOT_GRADLE)) {
-                        scope.add(GRADLE_FILE);
-                    } else if (name.equals(OLD_PROGUARD_FILE)
-                            || name.equals(FN_PROJECT_PROGUARD_FILE)) {
-                        scope.add(PROGUARD_FILE);
-                    } else if (name.endsWith(DOT_PROPERTIES)) {
-                        scope.add(PROPERTY_FILE);
-                    } else if (name.endsWith(DOT_PNG)) {
-                        scope.add(BINARY_RESOURCE_FILE);
-                    } else if (name.equals(RES_FOLDER)
-                            || file.getParent().equals(RES_FOLDER)) {
-                        scope.add(ALL_RESOURCE_FILES);
-                        scope.add(RESOURCE_FILE);
-                        scope.add(BINARY_RESOURCE_FILE);
-                        scope.add(RESOURCE_FOLDER);
-                    }
-                }
-            } else {
-                // Specified a full project: just use the full project scope
-                scope = Scope.ALL;
-                break;
-            }
-        }
-
-        return scope;
-    }
-
-    /** All scopes: running lint on a project will check these scopes */
-    public static final EnumSet<Scope> ALL = EnumSet.allOf(Scope.class);
-    /** Scope-set used for detectors which are affected by a single resource file */
-    public static final EnumSet<Scope> RESOURCE_FILE_SCOPE = EnumSet.of(RESOURCE_FILE);
-    /** Scope-set used for detectors which are affected by a single resource folder */
-    public static final EnumSet<Scope> RESOURCE_FOLDER_SCOPE = EnumSet.of(RESOURCE_FOLDER);
-    /** Scope-set used for detectors which scan all resources */
-    public static final EnumSet<Scope> ALL_RESOURCES_SCOPE = EnumSet.of(ALL_RESOURCE_FILES);
-    /** Scope-set used for detectors which are affected by a single Java source file */
-    public static final EnumSet<Scope> JAVA_FILE_SCOPE = EnumSet.of(JAVA_FILE);
-    /** Scope-set used for detectors which are affected by a single Java class file */
-    public static final EnumSet<Scope> CLASS_FILE_SCOPE = EnumSet.of(CLASS_FILE);
-    /** Scope-set used for detectors which are affected by a single Gradle build file */
-    public static final EnumSet<Scope> GRADLE_SCOPE = EnumSet.of(GRADLE_FILE);
-    /** Scope-set used for detectors which are affected by the manifest only */
-    public static final EnumSet<Scope> MANIFEST_SCOPE = EnumSet.of(MANIFEST);
-    /** Scope-set used for detectors which correspond to some other context */
-    public static final EnumSet<Scope> OTHER_SCOPE = EnumSet.of(OTHER);
-    /** Scope-set used for detectors which are affected by a single ProGuard class file */
-    public static final EnumSet<Scope> PROGUARD_SCOPE = EnumSet.of(PROGUARD_FILE);
-    /** Scope-set used for detectors which correspond to property files */
-    public static final EnumSet<Scope> PROPERTY_SCOPE = EnumSet.of(PROPERTY_FILE);
-    /** Resource XML files and manifest files */
-    public static final EnumSet<Scope> MANIFEST_AND_RESOURCE_SCOPE =
-            EnumSet.of(Scope.MANIFEST, Scope.RESOURCE_FILE);
-    /** Scope-set used for detectors which are affected by single XML and Java source files */
-    public static final EnumSet<Scope> JAVA_AND_RESOURCE_FILES =
-            EnumSet.of(RESOURCE_FILE, JAVA_FILE);
-    /** Scope-set used for analyzing individual class files and all resource files */
-    public static final EnumSet<Scope> CLASS_AND_ALL_RESOURCE_FILES =
-            EnumSet.of(ALL_RESOURCE_FILES, CLASS_FILE);
-    /** Scope-set used for analyzing all class files, including those in libraries */
-    public static final EnumSet<Scope> ALL_CLASSES_AND_LIBRARIES =
-            EnumSet.of(Scope.ALL_CLASS_FILES, Scope.JAVA_LIBRARIES);
-    /** Scope-set used for detectors which are affected by Java libraries */
-    public static final EnumSet<Scope> JAVA_LIBRARY_SCOPE = EnumSet.of(JAVA_LIBRARIES);
-    /** Scope-set used for detectors which are affected by a single binary resource file */
-    public static final EnumSet<Scope> BINARY_RESOURCE_FILE_SCOPE =
-            EnumSet.of(BINARY_RESOURCE_FILE);
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Severity.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Severity.java
deleted file mode 100644
index c1de962..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Severity.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.annotations.Beta;
-
-/**
- * Severity of an issue found by lint
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public enum Severity {
-    /**
-     * Fatal: Use sparingly because a warning marked as fatal will be
-     * considered critical and will abort Export APK etc in ADT
-     */
-    @NonNull
-    FATAL("Fatal"),
-
-    /**
-     * Errors: The issue is known to be a real error that must be addressed.
-     */
-    @NonNull
-    ERROR("Error"),
-
-    /**
-     * Warning: Probably a problem.
-     */
-    @NonNull
-    WARNING("Warning"),
-
-    /**
-     * Information only: Might not be a problem, but the check has found
-     * something interesting to say about the code.
-     */
-    @NonNull
-    INFORMATIONAL("Information"),
-
-    /**
-     * Ignore: The user doesn't want to see this issue
-     */
-    @NonNull
-    IGNORE("Ignore");
-
-    @NonNull
-    private final String mDisplay;
-
-    Severity(@NonNull String display) {
-        mDisplay = display;
-    }
-
-    /**
-     * Returns a description of this severity suitable for display to the user
-     *
-     * @return a description of the severity
-     */
-    @NonNull
-    public String getDescription() {
-        return mDisplay;
-    }
-
-    /** Returns the name of this severity */
-    @NonNull
-    public String getName() {
-        return name();
-    }
-
-    /**
-     * Looks up the severity corresponding to a given named severity. The severity
-     * string should be one returned by {@link #toString()}
-     *
-     * @param name the name to look up
-     * @return the corresponding severity, or null if it is not a valid severity name
-     */
-    @Nullable
-    public static Severity fromName(@NonNull String name) {
-        for (Severity severity : values()) {
-            if (severity.name().equalsIgnoreCase(name)) {
-                return severity;
-            }
-        }
-
-        return null;
-    }
-}
\ No newline at end of file
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Speed.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Speed.java
deleted file mode 100644
index b790a1a..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Speed.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.google.common.annotations.Beta;
-
-/**
- * Enum which describes the different computation speeds of various detectors
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public enum Speed {
-    /** The detector can run very quickly */
-    FAST("Fast"),
-
-    /** The detector runs reasonably fast */
-    NORMAL("Normal"),
-
-    /** The detector might take a long time to run */
-    SLOW("Slow"),
-
-    /** The detector might take a huge amount of time to run */
-    REALLY_SLOW("Really Slow");
-
-    private final String mDisplayName;
-
-    Speed(@NonNull String displayName) {
-        mDisplayName = displayName;
-    }
-
-    /**
-     * Returns the user-visible description of the speed of the given
-     * detector
-     *
-     * @return the description of the speed to display to the user
-     */
-    @NonNull
-    public String getDisplayName() {
-        return mDisplayName;
-    }
-}
\ No newline at end of file
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TextFormat.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TextFormat.java
deleted file mode 100644
index c081583..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TextFormat.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.utils.SdkUtils;
-import com.android.utils.XmlUtils;
-
-/**
- * Lint error message, issue explanations and location descriptions
- * are described in a {@link #RAW} format which looks similar to text
- * but which can contain bold, symbols and links. These issues can
- * also be converted to plain text and to HTML markup, using the
- * {@link #convertTo(String, TextFormat)} method.
- *
- * @see Issue#getExplanation(TextFormat)
- * @see Issue#getBriefDescription(TextFormat)
- */
-public enum TextFormat {
-    /**
-     * Raw output format which is similar to text but allows some markup:
-     * <ul>
-     * <li>HTTP urls (http://...)
-     * <li>Sentences immediately surrounded by * will be shown as bold.
-     * <li>Sentences immediately surrounded by ` will be shown using monospace
-     * fonts
-     * </ul>
-     * Furthermore, newlines are converted to br's when converting newlines.
-     * Note: It does not insert {@code <html>} tags around the fragment for HTML output.
-     * <p>
-     * TODO: Consider switching to the restructured text format -
-     *  http://docutils.sourceforge.net/docs/user/rst/quickstart.html
-     */
-    RAW,
-
-    /**
-     * Plain text output
-     */
-    TEXT,
-
-    /**
-     * HTML formatted output (note: does not include surrounding {@code <html></html>} tags)
-     */
-    HTML,
-
-    /**
-     * HTML formatted output (note: does not include surrounding {@code <html></html>} tags).
-     * This is like {@link #HTML}, but it does not escape unicode characters with entities.
-     * <p>
-     * (This is used for example in the IDE, where some partial HTML support in some
-     * label widgets support some HTML markup, but not numeric code character entities.)
-     */
-    HTML_WITH_UNICODE;
-
-    /**
-     * Converts the given text to HTML
-     *
-     * @param text the text to format
-     * @return the corresponding text formatted as HTML
-     */
-    @NonNull
-    public String toHtml(@NonNull String text) {
-        return convertTo(text, HTML);
-    }
-
-    /**
-     * Converts the given text to plain text
-     *
-     * @param text the tetx to format
-     * @return the corresponding text formatted as HTML
-     */
-    @NonNull
-    public String toText(@NonNull String text) {
-        return convertTo(text, TEXT);
-    }
-
-    /**
-     * Converts the given message to the given format. Note that some
-     * conversions are lossy; e.g. once converting away from the raw format
-     * (which contains all the markup) you can't convert back to it.
-     * Note that you can convert to the format it's already in; that just
-     * returns the same string.
-     *
-     * @param message the message to convert
-     * @param to the format to convert to
-     * @return a converted message
-     */
-    public String convertTo(@NonNull String message, @NonNull TextFormat to) {
-        if (this == to) {
-            return message;
-        }
-        switch (this) {
-            case RAW: {
-                switch (to) {
-                    case RAW:
-                        return message;
-                    case TEXT:
-                    case HTML:
-                    case HTML_WITH_UNICODE:
-                        return to.fromRaw(message);
-                }
-            }
-            case TEXT: {
-                switch (to) {
-                    case TEXT:
-                    case RAW:
-                        return message;
-                    case HTML:
-                    case HTML_WITH_UNICODE:
-                        return XmlUtils.toXmlTextValue(message);
-                }
-            }
-            case HTML: {
-                switch (to) {
-                    case HTML:
-                        return message;
-                    case HTML_WITH_UNICODE:
-                        return removeNumericEntities(message);
-                    case RAW:
-                    case TEXT: {
-                        return to.fromHtml(message);
-
-                    }
-                }
-            }
-            case HTML_WITH_UNICODE: {
-                switch (to) {
-                    case HTML:
-                    case HTML_WITH_UNICODE:
-                        return message;
-                    case RAW:
-                    case TEXT: {
-                        return to.fromHtml(message);
-
-                    }
-                }
-            }
-        }
-        return message;
-    }
-
-    /** Converts to this output format from the given HTML-format text */
-    @NonNull
-    private String fromHtml(@NonNull String html) {
-        assert this == RAW || this == TEXT : this;
-
-        // Drop all tags; replace all entities, insert newlines
-        // (this won't do wrapping)
-        StringBuilder sb = new StringBuilder(html.length());
-        boolean inPre = false;
-        for (int i = 0, n = html.length(); i < n; i++) {
-            char c = html.charAt(i);
-            if (c == '<') {
-                // Strip comments
-                if (html.startsWith("<!--", i)) {
-                    int end = html.indexOf("-->", i);
-                    if (end == -1) {
-                        break; // Unclosed comment
-                    } else {
-                        i = end + 2;
-                    }
-                    continue;
-                }
-                // Tags: scan forward to the end
-                int begin;
-                boolean isEndTag = false;
-                if (html.startsWith("</", i)) {
-                    begin = i + 2;
-                    isEndTag = true;
-                } else {
-                    begin = i + 1;
-                }
-                i = html.indexOf('>', i);
-                if (i == -1) {
-                    // Unclosed tag
-                    break;
-                }
-                int end = i;
-                if (html.charAt(i - 1) == '/') {
-                    end--;
-                    isEndTag = true;
-                }
-                // TODO: Handle <pre> such that we don't collapse spaces and reformat there!
-                // (We do need to strip out tags and expand entities)
-                String tag = html.substring(begin, end).trim();
-                if (tag.equalsIgnoreCase("br")) {
-                    sb.append('\n');
-                } else if (tag.equalsIgnoreCase("p") // Most common block tags
-                           || tag.equalsIgnoreCase("div")
-                           || tag.equalsIgnoreCase("pre")
-                           || tag.equalsIgnoreCase("blockquote")
-                           || tag.equalsIgnoreCase("dl")
-                           || tag.equalsIgnoreCase("dd")
-                           || tag.equalsIgnoreCase("dt")
-                           || tag.equalsIgnoreCase("ol")
-                           || tag.equalsIgnoreCase("ul")
-                           || tag.equalsIgnoreCase("li")
-                            || tag.length() == 2 && tag.startsWith("h")
-                                    && Character.isDigit(tag.charAt(1))) {
-                    // Block tag: ensure new line
-                    if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '\n') {
-                        sb.append('\n');
-                    }
-                    if (tag.equals("li") && !isEndTag) {
-                        sb.append("* ");
-                    }
-                    if (tag.equalsIgnoreCase("pre")) {
-                        inPre = !isEndTag;
-                    }
-                }
-            } else if (c == '&') {
-                int end = html.indexOf(';', i);
-                if (end > i) {
-                    String entity = html.substring(i, end + 1);
-                    String s = XmlUtils.fromXmlAttributeValue(entity);
-                    if (s.startsWith("&")) {
-                        // Not an XML entity; for example, &nbsp;
-                        // Sadly Guava's HtmlEscapes don't handle this either.
-                        if (entity.equalsIgnoreCase("&nbsp;")) {
-                            s = " ";
-                        } else if (entity.startsWith("&#")) {
-                            try {
-                                int value = Integer.parseInt(entity.substring(2));
-                                s = Character.toString((char)value);
-                            } catch (NumberFormatException ignore) {
-                            }
-                        }
-                    }
-                    sb.append(s);
-                    i = end;
-                } else {
-                    sb.append(c);
-                }
-            } else if (Character.isWhitespace(c)) {
-                if (inPre) {
-                    sb.append(c);
-                } else if (sb.length() == 0
-                                || !Character.isWhitespace(sb.charAt(sb.length() - 1))) {
-                    sb.append(' ');
-                }
-            } else {
-                sb.append(c);
-            }
-        }
-
-        String s = sb.toString();
-
-        // Line-wrap
-        s = SdkUtils.wrap(s, 60, null);
-
-        return s;
-    }
-
-    private static final String HTTP_PREFIX = "http://"; //$NON-NLS-1$
-
-    /** Converts to this output format from the given raw-format text */
-    @NonNull
-    private String fromRaw(@NonNull String text) {
-        assert this == HTML || this == HTML_WITH_UNICODE || this == TEXT : this;
-        StringBuilder sb = new StringBuilder(3 * text.length() / 2);
-        boolean html = this == HTML || this == HTML_WITH_UNICODE;
-        boolean escapeUnicode = this == HTML;
-
-        char prev = 0;
-        int flushIndex = 0;
-        int n = text.length();
-        for (int i = 0; i < n; i++) {
-            char c = text.charAt(i);
-            if ((c == '*' || c == '`') && i < n - 1) {
-                // Scout ahead for range end
-                if (!Character.isLetterOrDigit(prev)
-                        && !Character.isWhitespace(text.charAt(i + 1))) {
-                    // Found * or ` immediately before a letter, and not in the middle of a word
-                    // Find end
-                    int end = text.indexOf(c, i + 1);
-                    if (end != -1 && (end == n - 1 || !Character.isLetter(text.charAt(end + 1)))) {
-                        if (i > flushIndex) {
-                            appendEscapedText(sb, text, html, flushIndex, i, escapeUnicode);
-                        }
-                        if (html) {
-                            String tag = c == '*' ? "b" : "code"; //$NON-NLS-1$ //$NON-NLS-2$
-                            sb.append('<').append(tag).append('>');
-                            appendEscapedText(sb, text, html, i + 1, end, escapeUnicode);
-                            sb.append('<').append('/').append(tag).append('>');
-                        } else {
-                            appendEscapedText(sb, text, html, i + 1, end, escapeUnicode);
-                        }
-                        flushIndex = end + 1;
-                        i = flushIndex - 1; // -1: account for the i++ in the loop
-                    }
-                }
-            } else if (html && c == 'h' && i < n - 1 && text.charAt(i + 1) == 't'
-                    && text.startsWith(HTTP_PREFIX, i) && !Character.isLetterOrDigit(prev)) {
-                // Find url end
-                int end = i + HTTP_PREFIX.length();
-                while (end < n) {
-                    char d = text.charAt(end);
-                    if (Character.isWhitespace(d)) {
-                        break;
-                    }
-                    end++;
-                }
-                char last = text.charAt(end - 1);
-                if (last == '.' || last == ')' || last == '!') {
-                    end--;
-                }
-                if (end > i + HTTP_PREFIX.length()) {
-                    if (i > flushIndex) {
-                        appendEscapedText(sb, text, html, flushIndex, i, escapeUnicode);
-                    }
-
-                    String url = text.substring(i, end);
-                    sb.append("<a href=\"");        //$NON-NLS-1$
-                    sb.append(url);
-                    sb.append('"').append('>');
-                    sb.append(url);
-                    sb.append("</a>");              //$NON-NLS-1$
-
-                    flushIndex = end;
-                    i = flushIndex - 1; // -1: account for the i++ in the loop
-                }
-            }
-            prev = c;
-        }
-
-        if (flushIndex < n) {
-            appendEscapedText(sb, text, html, flushIndex, n, escapeUnicode);
-        }
-
-        return sb.toString();
-    }
-
-    private static String removeNumericEntities(@NonNull String html) {
-        if (!html.contains("&#")) {
-            return html;
-        }
-
-        StringBuilder sb = new StringBuilder(html.length());
-        for (int i = 0, n = html.length(); i < n; i++) {
-            char c = html.charAt(i);
-            if (c == '&' && i < n - 1 && html.charAt(i + 1) == '#') {
-                int end = html.indexOf(';', i + 2);
-                if (end != -1) {
-                    String decimal = html.substring(i + 2, end);
-                    try {
-                        c = (char)Integer.parseInt(decimal);
-                        sb.append(c);
-                        i = end;
-                        continue;
-                    } catch (NumberFormatException ignore) {
-                        // fall through to not escape this
-                    }
-                }
-            }
-            sb.append(c);
-        }
-
-        return sb.toString();
-    }
-
-    private static void appendEscapedText(@NonNull StringBuilder sb, @NonNull String text,
-            boolean html, int start, int end, boolean escapeUnicode) {
-        if (html) {
-            for (int i = start; i < end; i++) {
-                char c = text.charAt(i);
-                if (c == '<') {
-                    sb.append("&lt;");                                   //$NON-NLS-1$
-                } else if (c == '&') {
-                    sb.append("&amp;");                                  //$NON-NLS-1$
-                } else if (c == '\n') {
-                    sb.append("<br/>\n");
-                } else {
-                    if (c > 255 && escapeUnicode) {
-                        sb.append("&#");                                 //$NON-NLS-1$
-                        sb.append(Integer.toString(c));
-                        sb.append(';');
-                    } else if (c == '\u00a0') {
-                        sb.append("&nbsp;");                             //$NON-NLS-1$
-                    } else {
-                        sb.append(c);
-                    }
-                }
-            }
-        } else {
-            for (int i = start; i < end; i++) {
-                char c = text.charAt(i);
-                sb.append(c);
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TypeEvaluator.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TypeEvaluator.java
deleted file mode 100644
index 74afe26..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/TypeEvaluator.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.detector.api;
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_BOOLEAN;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_CHAR;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_DOUBLE;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_FLOAT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_INT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_LONG;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-import static com.android.tools.klint.detector.api.JavaContext.getParentOfType;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaParser.DefaultTypeDescriptor;
-import com.android.tools.klint.client.api.JavaParser.ResolvedClass;
-import com.android.tools.klint.client.api.JavaParser.ResolvedField;
-import com.android.tools.klint.client.api.JavaParser.ResolvedMethod;
-import com.android.tools.klint.client.api.JavaParser.ResolvedNode;
-import com.android.tools.klint.client.api.JavaParser.ResolvedVariable;
-import com.android.tools.klint.client.api.JavaParser.TypeDescriptor;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.intellij.psi.PsiAssignmentExpression;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiDeclarationStatement;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiExpressionStatement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiLocalVariable;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiReferenceExpression;
-import com.intellij.psi.PsiStatement;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.util.PsiTreeUtil;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UVariable;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-
-import java.util.ListIterator;
-
-import lombok.ast.BinaryExpression;
-import lombok.ast.BinaryOperator;
-import lombok.ast.BooleanLiteral;
-import lombok.ast.Cast;
-import lombok.ast.CharLiteral;
-import lombok.ast.Expression;
-import lombok.ast.ExpressionStatement;
-import lombok.ast.FloatingPointLiteral;
-import lombok.ast.InlineIfExpression;
-import lombok.ast.IntegralLiteral;
-import lombok.ast.Literal;
-import lombok.ast.Node;
-import lombok.ast.NullLiteral;
-import lombok.ast.Statement;
-import lombok.ast.StringLiteral;
-import lombok.ast.UnaryExpression;
-import lombok.ast.VariableDeclaration;
-import lombok.ast.VariableDefinition;
-import lombok.ast.VariableDefinitionEntry;
-import lombok.ast.VariableReference;
-
-/**
- * Evaluates the types of nodes. This goes deeper than
- * {@link JavaContext#getType(Node)} in that it analyzes the
- * flow and for example figures out that if you ask for the type of {@code var}
- * in this code snippet:
- * <pre>
- *     Object o = new StringBuilder();
- *     Object var = o;
- * </pre>
- * it will return "java.lang.StringBuilder".
- * <p>
- * <b>NOTE:</b> This type evaluator does not (yet) compute the correct
- * types when involving implicit type conversions, so be careful
- * if using this for primitives; e.g. for "int * long" it might return
- * the type "int".
- */
-public class TypeEvaluator {
-    private final JavaContext mContext;
-
-    /**
-     * Creates a new constant evaluator
-     *
-     * @param context the context to use to resolve field references, if any
-     */
-    public TypeEvaluator(@Nullable JavaContext context) {
-        mContext = context;
-    }
-
-
-    /**
-     * Returns the inferred type of the given node
-     * @deprecated Use {@link #evaluate(PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public TypeDescriptor evaluate(@NonNull Node node) {
-        ResolvedNode resolved = null;
-        if (mContext != null) {
-            resolved = mContext.resolve(node);
-        }
-        if (resolved instanceof ResolvedMethod) {
-            TypeDescriptor type;
-            ResolvedMethod method = (ResolvedMethod) resolved;
-            if (method.isConstructor()) {
-                ResolvedClass containingClass = method.getContainingClass();
-                type = containingClass.getType();
-            } else {
-                type = method.getReturnType();
-            }
-            return type;
-        }
-        if (resolved instanceof ResolvedField) {
-            ResolvedField field = (ResolvedField) resolved;
-            Node astNode = field.findAstNode();
-            if (astNode instanceof VariableDeclaration) {
-                VariableDeclaration declaration = (VariableDeclaration)astNode;
-                VariableDefinition definition = declaration.astDefinition();
-                if (definition != null) {
-                    VariableDefinitionEntry first = definition.astVariables().first();
-                    if (first != null) {
-                        Expression initializer = first.astInitializer();
-                        if (initializer != null) {
-                            TypeDescriptor type = evaluate(initializer);
-                            if (type != null) {
-                                return type;
-                            }
-                        }
-                    }
-                }
-            }
-            return field.getType();
-        }
-
-        if (node instanceof VariableReference) {
-            Statement statement = getParentOfType(node, Statement.class, false);
-            if (statement != null) {
-                ListIterator<Node> iterator = statement.getParent().getChildren().listIterator();
-                while (iterator.hasNext()) {
-                    if (iterator.next() == statement) {
-                        if (iterator.hasPrevious()) { // should always be true
-                            iterator.previous();
-                        }
-                        break;
-                    }
-                }
-
-                String targetName = ((VariableReference) node).astIdentifier().astValue();
-                while (iterator.hasPrevious()) {
-                    Node previous = iterator.previous();
-                    if (previous instanceof VariableDeclaration) {
-                        VariableDeclaration declaration = (VariableDeclaration) previous;
-                        VariableDefinition definition = declaration.astDefinition();
-                        for (VariableDefinitionEntry entry : definition.astVariables()) {
-                            if (entry.astInitializer() != null && entry.astName().astValue()
-                                    .equals(targetName)) {
-                                return evaluate(entry.astInitializer());
-                            }
-                        }
-                    } else if (previous instanceof ExpressionStatement) {
-                        ExpressionStatement expressionStatement = (ExpressionStatement) previous;
-                        Expression expression = expressionStatement.astExpression();
-                        if (expression instanceof BinaryExpression &&
-                                ((BinaryExpression) expression).astOperator()
-                                        == BinaryOperator.ASSIGN) {
-                            BinaryExpression binaryExpression = (BinaryExpression) expression;
-                            if (targetName.equals(binaryExpression.astLeft().toString())) {
-                                return evaluate(binaryExpression.astRight());
-                            }
-                        }
-                    }
-                }
-            }
-        } else if (node instanceof Cast) {
-            Cast cast = (Cast) node;
-            if (mContext != null) {
-                ResolvedNode typeReference = mContext.resolve(cast.astTypeReference());
-                if (typeReference instanceof ResolvedClass) {
-                    return ((ResolvedClass) typeReference).getType();
-                }
-            }
-            TypeDescriptor viewType = evaluate(cast.astOperand());
-            if (viewType != null) {
-                return viewType;
-            }
-        } else if (node instanceof Literal) {
-            if (node instanceof NullLiteral) {
-                return null;
-            } else if (node instanceof BooleanLiteral) {
-                return new DefaultTypeDescriptor(TYPE_BOOLEAN);
-            } else if (node instanceof StringLiteral) {
-                return new DefaultTypeDescriptor(TYPE_STRING);
-            } else if (node instanceof CharLiteral) {
-                return new DefaultTypeDescriptor(TYPE_CHAR);
-            } else if (node instanceof IntegralLiteral) {
-                IntegralLiteral literal = (IntegralLiteral) node;
-                // Don't combine to ?: since that will promote astIntValue to a long
-                if (literal.astMarkedAsLong()) {
-                    return new DefaultTypeDescriptor(TYPE_LONG);
-                } else {
-                    return new DefaultTypeDescriptor(TYPE_INT);
-                }
-            } else if (node instanceof FloatingPointLiteral) {
-                FloatingPointLiteral literal = (FloatingPointLiteral) node;
-                // Don't combine to ?: since that will promote astFloatValue to a double
-                if (literal.astMarkedAsFloat()) {
-                    return new DefaultTypeDescriptor(TYPE_FLOAT);
-                } else {
-                    return new DefaultTypeDescriptor(TYPE_DOUBLE);
-                }
-            }
-        } else if (node instanceof UnaryExpression) {
-            return evaluate(((UnaryExpression) node).astOperand());
-        } else if (node instanceof InlineIfExpression) {
-            InlineIfExpression expression = (InlineIfExpression) node;
-            if (expression.astIfTrue() != null) {
-                return evaluate(expression.astIfTrue());
-            } else if (expression.astIfFalse() != null) {
-                return evaluate(expression.astIfFalse());
-            }
-        } else if (node instanceof BinaryExpression) {
-            BinaryExpression expression = (BinaryExpression) node;
-            BinaryOperator operator = expression.astOperator();
-            switch (operator) {
-                case LOGICAL_OR:
-                case LOGICAL_AND:
-                case EQUALS:
-                case NOT_EQUALS:
-                case GREATER:
-                case GREATER_OR_EQUAL:
-                case LESS:
-                case LESS_OR_EQUAL:
-                    return new DefaultTypeDescriptor(TYPE_BOOLEAN);
-            }
-
-            TypeDescriptor type = evaluate(expression.astLeft());
-            if (type != null) {
-                return type;
-            }
-            return evaluate(expression.astRight());
-        }
-
-        if (resolved instanceof ResolvedVariable) {
-            ResolvedVariable variable = (ResolvedVariable) resolved;
-            return variable.getType();
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the inferred type of the given node
-     */
-    @Nullable
-    public PsiType evaluate(@Nullable PsiElement node) {
-        if (node == null) {
-            return null;
-        }
-
-        PsiElement resolved = null;
-        if (node instanceof PsiReference) {
-            resolved = ((PsiReference) node).resolve();
-        }
-        if (resolved instanceof PsiMethod) {
-            PsiMethod method = (PsiMethod) resolved;
-            if (method.isConstructor()) {
-                PsiClass containingClass = method.getContainingClass();
-                if (containingClass != null && mContext != null) {
-                    return mContext.getEvaluator().getClassType(containingClass);
-                }
-            } else {
-                return method.getReturnType();
-            }
-        }
-
-        if (resolved instanceof PsiField) {
-            PsiField field = (PsiField) resolved;
-            if (field.getInitializer() != null) {
-                PsiType type = evaluate(field.getInitializer());
-                if (type != null) {
-                    return type;
-                }
-            }
-            return field.getType();
-        } else if (resolved instanceof PsiLocalVariable) {
-            PsiLocalVariable variable = (PsiLocalVariable) resolved;
-            PsiStatement statement = PsiTreeUtil.getParentOfType(node, PsiStatement.class,
-                    false);
-            if (statement != null) {
-                PsiStatement prev = PsiTreeUtil.getPrevSiblingOfType(statement,
-                        PsiStatement.class);
-                String targetName = variable.getName();
-                if (targetName == null) {
-                    return null;
-                }
-                while (prev != null) {
-                    if (prev instanceof PsiDeclarationStatement) {
-                        for (PsiElement element : ((PsiDeclarationStatement)prev).getDeclaredElements()) {
-                            if (variable.equals(element)) {
-                                return evaluate(variable.getInitializer());
-                            }
-                        }
-                    } else if (prev instanceof PsiExpressionStatement) {
-                        PsiExpression expression = ((PsiExpressionStatement)prev).getExpression();
-                        if (expression instanceof PsiAssignmentExpression) {
-                            PsiAssignmentExpression assign = (PsiAssignmentExpression) expression;
-                            PsiExpression lhs = assign.getLExpression();
-                            if (lhs instanceof PsiReferenceExpression) {
-                                PsiReferenceExpression reference = (PsiReferenceExpression) lhs;
-                                if (targetName.equals(reference.getReferenceName()) &&
-                                        reference.getQualifier() == null) {
-                                    return evaluate(assign.getRExpression());
-                                }
-                            }
-                        }
-                    }
-                    prev = PsiTreeUtil.getPrevSiblingOfType(prev,
-                            PsiStatement.class);
-                }
-            }
-
-            return variable.getType();
-        } else if (node instanceof PsiExpression) {
-            PsiExpression expression = (PsiExpression) node;
-            return expression.getType();
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static PsiType evaluate(@NonNull JavaContext context, @Nullable UElement node) {
-        if (node == null) {
-            return null;
-        }
-        
-        UElement resolved = node;
-        if (resolved instanceof UReferenceExpression) {
-            resolved = UastUtils.tryResolveUDeclaration(resolved, context.getUastContext());
-        }
-        
-        if (resolved instanceof UMethod) {
-            return ((UMethod) resolved).getPsi().getReturnType();
-        } else if (resolved instanceof UVariable) {
-            UVariable variable = (UVariable) resolved; 
-            UElement lastAssignment = UastLintUtils.findLastAssignment(variable, node, context);
-            if (lastAssignment != null) {
-                return evaluate(context, lastAssignment);
-            }
-            return variable.getType();
-        } else if (resolved instanceof UCallExpression) {
-            if (UastExpressionUtils.isMethodCall(resolved)) {
-                PsiMethod resolvedMethod = ((UCallExpression) resolved).resolve();
-                return resolvedMethod != null ? resolvedMethod.getReturnType() : null;
-            } else {
-                return ((UCallExpression) resolved).getExpressionType();
-            }
-        } else if (resolved instanceof UExpression) {
-            return ((UExpression) resolved).getExpressionType();
-        }
-
-        return null;
-    }
-
-    /**
-     * Evaluates the given node and returns the likely type of the instance. Convenience
-     * wrapper which creates a new {@linkplain TypeEvaluator}, evaluates the node and returns
-     * the result.
-     *
-     * @param context the context to use to resolve field references, if any
-     * @param node    the node to compute the type for
-     * @return the corresponding type descriptor, if found
-     * @deprecated Use {@link #evaluate(JavaContext, PsiElement)} instead
-     */
-    @Deprecated
-    @Nullable
-    public static TypeDescriptor evaluate(@NonNull JavaContext context, @NonNull Node node) {
-        return new TypeEvaluator(context).evaluate(node);
-    }
-
-    /**
-     * Evaluates the given node and returns the likely type of the instance. Convenience
-     * wrapper which creates a new {@linkplain TypeEvaluator}, evaluates the node and returns
-     * the result.
-     *
-     * @param context the context to use to resolve field references, if any
-     * @param node    the node to compute the type for
-     * @return the corresponding type descriptor, if found
-     */
-    @Nullable
-    public static PsiType evaluate(@NonNull JavaContext context, @NonNull PsiElement node) {
-        return new TypeEvaluator(context).evaluate(node);
-    }
-}
diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/XmlContext.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/XmlContext.java
deleted file mode 100644
index ee16bab..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/XmlContext.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.detector.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.XmlParser;
-import com.google.common.annotations.Beta;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.File;
-
-/**
- * A {@link Context} used when checking XML files.
- * <p>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class XmlContext extends ResourceContext {
-    static final String SUPPRESS_COMMENT_PREFIX = "<!--suppress "; //$NON-NLS-1$
-
-    /** The XML parser */
-    private final XmlParser mParser;
-    /** The XML document */
-    public Document document;
-
-    /**
-     * Construct a new {@link XmlContext}
-     *
-     * @param driver the driver running through the checks
-     * @param project the project containing the file being checked
-     * @param main the main project if this project is a library project, or
-     *            null if this is not a library project. The main project is
-     *            the root project of all library projects, not necessarily the
-     *            directly including project.
-     * @param file the file being checked
-     * @param folderType the {@link ResourceFolderType} of this file, if any
-     */
-    public XmlContext(
-            @NonNull LintDriver driver,
-            @NonNull Project project,
-            @Nullable Project main,
-            @NonNull File file,
-            @Nullable ResourceFolderType folderType,
-            @NonNull XmlParser parser) {
-        super(driver, project, main, file, folderType);
-        mParser = parser;
-    }
-
-    /**
-     * Returns the location for the given node, which may be an element or an attribute.
-     *
-     * @param node the node to look up the location for
-     * @return the location for the node
-     */
-    @NonNull
-    public Location getLocation(@NonNull Node node) {
-        return mParser.getLocation(this, node);
-    }
-
-    /**
-     * Returns the location for name-portion of the given element or attribute.
-     *
-     * @param node the node to look up the location for
-     * @return the location for the node
-     */
-    @NonNull
-    public Location getNameLocation(@NonNull Node node) {
-        return mParser.getNameLocation(this, node);
-    }
-
-    /**
-     * Returns the location for value-portion of the given attribute
-     *
-     * @param node the node to look up the location for
-     * @return the location for the node
-     */
-    @NonNull
-    public Location getValueLocation(@NonNull Attr node) {
-        return mParser.getValueLocation(this, node);
-    }
-
-    /**
-     * Creates a new location within an XML text node
-     *
-     * @param textNode the text node
-     * @param begin the start offset within the text node (inclusive)
-     * @param end the end offset within the text node (exclusive)
-     * @return a new location
-     */
-    @NonNull
-    public Location getLocation(@NonNull Node textNode, int begin, int end) {
-        assert textNode.getNodeType() == Node.TEXT_NODE;
-        return mParser.getLocation(this, textNode, begin, end);
-    }
-
-    @NonNull
-    public XmlParser getParser() {
-        return mParser;
-    }
-
-    /**
-     * Reports an issue applicable to a given DOM node. The DOM node is used as the
-     * scope to check for suppress lint annotations.
-     *
-     * @param issue the issue to report
-     * @param scope the DOM node scope the error applies to. The lint infrastructure
-     *    will check whether there are suppress directives on this node (or its enclosing
-     *    nodes) and if so suppress the warning without involving the client.
-     * @param location the location of the issue, or null if not known
-     * @param message the message for this warning
-     */
-    public void report(
-            @NonNull Issue issue,
-            @Nullable Node scope,
-            @NonNull Location location,
-            @NonNull String message) {
-        if (scope != null && mDriver.isSuppressed(this, issue, scope)) {
-            return;
-        }
-        super.report(issue, location, message);
-    }
-
-    /**
-     * Report an error.
-     * Like {@link #report(Issue, org.w3c.dom.Node, Location, String)} but with
-     * a now-unused data parameter at the end.
-     *
-     * @deprecated Use {@link #report(Issue, org.w3c.dom.Node, Location, String)} instead;
-     *    this method is here for custom rule compatibility
-     */
-    @SuppressWarnings("UnusedDeclaration") // Potentially used by external existing custom rules
-    @Deprecated
-    public void report(
-            @NonNull Issue issue,
-            @Nullable Node scope,
-            @NonNull Location location,
-            @NonNull String message,
-            @SuppressWarnings("UnusedParameters") @Nullable Object data) {
-        report(issue, scope, location, message);
-    }
-
-    @Override
-    public void report(
-            @NonNull Issue issue,
-            @NonNull Location location,
-            @NonNull String message) {
-        // Warn if clients use the non-scoped form? No, there are cases where an
-        //  XML detector's error isn't applicable to one particular location (or it's
-        //  not feasible to compute it cheaply)
-        //mDriver.getClient().log(null, "Warning: Issue " + issue
-        //        + " was reported without a scope node: Can't be suppressed.");
-
-        // For now just check the document root itself
-        if (document != null && mDriver.isSuppressed(this, issue, document)) {
-            return;
-        }
-
-        super.report(issue, location, message);
-    }
-
-    @Override
-    @Nullable
-    protected String getSuppressCommentPrefix() {
-        return SUPPRESS_COMMENT_PREFIX;
-    }
-
-    public boolean isSuppressedWithComment(@NonNull Node node, @NonNull Issue issue) {
-        // Check whether there is a comment marker
-        String contents = getContents();
-        assert contents != null; // otherwise we wouldn't be here
-
-        int start = mParser.getNodeStartOffset(this, node);
-        if (start != -1) {
-            return isSuppressedWithComment(start, issue);
-        }
-
-        return false;
-    }
-
-    @NonNull
-    public Location.Handle createLocationHandle(@NonNull Node node) {
-        return mParser.createLocationHandle(this, node);
-    }
-}
diff --git a/plugins/lint/lint-checks/lint-checks.iml b/plugins/lint/lint-checks/lint-checks.iml
deleted file mode 100644
index 7f00be7..0000000
--- a/plugins/lint/lint-checks/lint-checks.iml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module" module-name="android-annotations" />
-    <orderEntry type="module" module-name="lint-api" />
-    <orderEntry type="module" module-name="lint-idea" />
-    <orderEntry type="library" name="android-plugin" level="project" />
-    <orderEntry type="library" name="guava" level="project" />
-    <orderEntry type="library" name="intellij-core" level="project" />
-    <orderEntry type="library" name="kotlin-runtime" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AddJavascriptInterfaceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AddJavascriptInterfaceDetector.java
deleted file mode 100644
index 2be12a36..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AddJavascriptInterfaceDetector.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_OBJECT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Ensures that addJavascriptInterface is not called for API levels below 17.
- */
-public class AddJavascriptInterfaceDetector extends Detector implements Detector.UastScanner {
-    public static final Issue ISSUE = Issue.create(
-            "AddJavascriptInterface", //$NON-NLS-1$
-            "addJavascriptInterface Called",
-            "For applications built for API levels below 17, `WebView#addJavascriptInterface` "
-                    + "presents a security hazard as JavaScript on the target web page has the "
-                    + "ability to use reflection to access the injected object's public fields and "
-                    + "thus manipulate the host application in unintended ways.",
-            Category.SECURITY,
-            9,
-            Severity.WARNING,
-            new Implementation(
-                    AddJavascriptInterfaceDetector.class,
-                    Scope.JAVA_FILE_SCOPE)).
-            addMoreInfo(
-                    "https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/");
-
-    private static final String WEB_VIEW = "android.webkit.WebView"; //$NON-NLS-1$
-    private static final String ADD_JAVASCRIPT_INTERFACE = "addJavascriptInterface"; //$NON-NLS-1$
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(ADD_JAVASCRIPT_INTERFACE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        // Ignore the issue if we never build for any API less than 17.
-        if (context.getMainProject().getMinSdk() >= 17) {
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!evaluator.methodMatches(method, WEB_VIEW, true, TYPE_OBJECT, TYPE_STRING)) {
-            return;
-        }
-
-        String message = "`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: " +
-                "JavaScript can use reflection to manipulate application";
-        UElement reportElement = call.getMethodIdentifier();
-        if (reportElement == null) {
-            reportElement = call;
-        }
-        context.reportUast(ISSUE, reportElement, context.getUastNameLocation(reportElement), message);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlarmDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlarmDetector.java
deleted file mode 100644
index 823b408..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlarmDetector.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Makes sure that alarms are handled correctly
- */
-public class AlarmDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            AlarmDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Alarm set too soon/frequently  */
-    public static final Issue ISSUE = Issue.create(
-            "ShortAlarm", //$NON-NLS-1$
-            "Short or Frequent Alarm",
-
-            "Frequent alarms are bad for battery life. As of API 22, the `AlarmManager` " +
-            "will override near-future and high-frequency alarm requests, delaying the alarm " +
-            "at least 5 seconds into the future and ensuring that the repeat interval is at " +
-            "least 60 seconds.\n" +
-            "\n" +
-            "If you really need to do work sooner than 5 seconds, post a delayed message " +
-            "or runnable to a Handler.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Constructs a new {@link AlarmDetector} check */
-    public AlarmDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("setRepeating");
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isMemberInClass(method, "android.app.AlarmManager") &&
-                evaluator.getParameterCount(method) == 4) {
-            ensureAtLeast(context, node, 1, 5000L);
-            ensureAtLeast(context, node, 2, 60000L);
-        }
-    }
-
-    private static void ensureAtLeast(@NonNull JavaContext context,
-            @NonNull UCallExpression node, int parameter, long min) {
-        UExpression argument = node.getValueArguments().get(parameter);
-        long value = getLongValue(context, argument);
-        if (value < min) {
-            String message = String.format("Value will be forced up to %1$d as of Android 5.1; "
-                    + "don't rely on this to be exact", min);
-            context.report(ISSUE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    private static long getLongValue(
-            @NonNull JavaContext context,
-            @NonNull UExpression argument) {
-        Object value = ConstantEvaluator.evaluate(context, argument);
-        if (value instanceof Number) {
-            return ((Number)value).longValue();
-        }
-
-        return Long.MAX_VALUE;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AllowAllHostnameVerifierDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AllowAllHostnameVerifierDetector.java
deleted file mode 100644
index 6fe09fa..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AllowAllHostnameVerifierDetector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-public class AllowAllHostnameVerifierDetector extends Detector implements Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION =
-            new Implementation(AllowAllHostnameVerifierDetector.class,
-                    Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue ISSUE = Issue.create("AllowAllHostnameVerifier",
-            "Insecure HostnameVerifier",
-            "This check looks for use of HostnameVerifier implementations " +
-            "whose `verify` method always returns true (thus trusting any hostname) " +
-            "which could result in insecure network traffic caused by trusting arbitrary " +
-            "hostnames in TLS/SSL certificates presented by peers.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    @Nullable @SuppressWarnings("javadoc")
-    public List<String> getApplicableConstructorTypes() {
-        return Collections.singletonList("org.apache.http.conn.ssl.AllowAllHostnameVerifier");
-    }
-
-    @Override
-    public void visitConstructor(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod constructor) {
-        Location location = context.getUastLocation(node);
-        context.report(ISSUE, node, location,
-                "Using the AllowAllHostnameVerifier HostnameVerifier is unsafe " +
-                        "because it always returns true, which could cause insecure network " +
-                        "traffic due to trusting TLS/SSL server certificates for wrong " +
-                        "hostnames");
-    }
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList("setHostnameVerifier", "setDefaultHostnameVerifier");
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.methodMatches(method, null, false, "javax.net.ssl.HostnameVerifier")) {
-            UExpression argument = node.getValueArguments().get(0);
-            PsiElement resolvedArgument = UastUtils.tryResolve(argument);
-            if (resolvedArgument instanceof PsiField) {
-                PsiField field = (PsiField) resolvedArgument;
-                if ("ALLOW_ALL_HOSTNAME_VERIFIER".equals(field.getName())) {
-                    Location location = context.getUastLocation(argument);
-                    String message = "Using the ALLOW_ALL_HOSTNAME_VERIFIER HostnameVerifier "
-                            + "is unsafe because it always returns true, which could cause "
-                            + "insecure network traffic due to trusting TLS/SSL server "
-                            + "certificates for wrong hostnames";
-                    context.report(ISSUE, argument, location, message);
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java
deleted file mode 100644
index 7a67588..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ATTR_SHOW_AS_ACTION;
-import static com.android.SdkConstants.VALUE_ALWAYS;
-import static com.android.SdkConstants.VALUE_IF_ROOM;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.ResourceXmlDetector;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Check which looks for usage of showAsAction="always" in menus (or
- * MenuItem.SHOW_AS_ACTION_ALWAYS in code), which is usually a style guide violation.
- * (Use ifRoom instead).
- */
-public class AlwaysShowActionDetector extends ResourceXmlDetector implements
-        Detector.UastScanner {
-
-    /** The main issue discovered by this detector */
-    @SuppressWarnings("unchecked")
-    public static final Issue ISSUE = Issue.create(
-            "AlwaysShowAction", //$NON-NLS-1$
-            "Usage of `showAsAction=always`",
-
-            "Using `showAsAction=\"always\"` in menu XML, or `MenuItem.SHOW_AS_ACTION_ALWAYS` in " +
-            "Java code is usually a deviation from the user interface style guide." +
-            "Use `ifRoom` or the corresponding `MenuItem.SHOW_AS_ACTION_IF_ROOM` instead.\n" +
-            "\n" +
-            "If `always` is used sparingly there are usually no problems and behavior is " +
-            "roughly equivalent to `ifRoom` but with preference over other `ifRoom` " +
-            "items. Using it more than twice in the same menu is a bad idea.\n" +
-            "\n" +
-            "This check looks for menu XML files that contain more than two `always` " +
-            "actions, or some `always` actions and no `ifRoom` actions. In Java code, " +
-            "it looks for projects that contain references to `MenuItem.SHOW_AS_ACTION_ALWAYS` " +
-            "and no references to `MenuItem.SHOW_AS_ACTION_IF_ROOM`.",
-
-            Category.USABILITY,
-            3,
-            Severity.WARNING,
-            new Implementation(
-                    AlwaysShowActionDetector.class,
-                    Scope.JAVA_AND_RESOURCE_FILES,
-                    Scope.RESOURCE_FILE_SCOPE))
-            .addMoreInfo("http://developer.android.com/design/patterns/actionbar.html"); //$NON-NLS-1$
-
-    /** List of showAsAction attributes appearing in the current menu XML file */
-    private List<Attr> mFileAttributes;
-    /** If at least one location has been marked ignore in this file, ignore all */
-    private boolean mIgnoreFile;
-    /** List of locations of MenuItem.SHOW_AS_ACTION_ALWAYS references in Java code */
-    private List<Location> mAlwaysFields;
-    /** True if references to MenuItem.SHOW_AS_ACTION_IF_ROOM were found */
-    private boolean mHasIfRoomRefs;
-
-    /** Constructs a new {@link AlwaysShowActionDetector} */
-    public AlwaysShowActionDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.MENU;
-    }
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        return Collections.singletonList(ATTR_SHOW_AS_ACTION);
-    }
-
-    @Override
-    public void beforeCheckFile(@NonNull Context context) {
-        mFileAttributes = null;
-    }
-
-    @Override
-    public void afterCheckFile(@NonNull Context context) {
-        if (mIgnoreFile) {
-            mFileAttributes = null;
-            return;
-        }
-        if (mFileAttributes != null) {
-            assert context instanceof XmlContext; // mFileAttributes is only set in XML files
-
-            List<Attr> always = new ArrayList<Attr>();
-            List<Attr> ifRoom = new ArrayList<Attr>();
-            for (Attr attribute : mFileAttributes) {
-                String value = attribute.getValue();
-                if (value.equals(VALUE_ALWAYS)) {
-                    always.add(attribute);
-                } else if (value.equals(VALUE_IF_ROOM)) {
-                    ifRoom.add(attribute);
-                } else if (value.indexOf('|') != -1) {
-                    String[] flags = value.split("\\|"); //$NON-NLS-1$
-                    for (String flag : flags) {
-                        if (flag.equals(VALUE_ALWAYS)) {
-                            always.add(attribute);
-                            break;
-                        } else if (flag.equals(VALUE_IF_ROOM)) {
-                            ifRoom.add(attribute);
-                            break;
-                        }
-                    }
-                }
-            }
-
-            if (!always.isEmpty() && mFileAttributes.size() > 1) {
-                // Complain if you're using more than one "always", or if you're
-                // using "always" and aren't using "ifRoom" at all (and provided you
-                // have more than a single item)
-                if (always.size() > 2 || ifRoom.isEmpty()) {
-                    XmlContext xmlContext = (XmlContext) context;
-                    Location location = null;
-                    for (int i = always.size() - 1; i >= 0; i--) {
-                        Location next = location;
-                        location = xmlContext.getLocation(always.get(i));
-                        if (next != null) {
-                            location.setSecondary(next);
-                        }
-                    }
-                    if (location != null) {
-                        context.report(ISSUE, location,
-                                "Prefer \"`ifRoom`\" instead of \"`always`\"");
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mAlwaysFields != null && !mHasIfRoomRefs) {
-            for (Location location : mAlwaysFields) {
-                context.report(ISSUE, location,
-                    "Prefer \"`SHOW_AS_ACTION_IF_ROOM`\" instead of \"`SHOW_AS_ACTION_ALWAYS`\"");
-            }
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        if (context.getDriver().isSuppressed(context, ISSUE, attribute)) {
-            mIgnoreFile = true;
-            return;
-        }
-
-        if (mFileAttributes == null) {
-            mFileAttributes = new ArrayList<Attr>();
-        }
-        mFileAttributes.add(attribute);
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableReferenceNames() {
-        return Arrays.asList("SHOW_AS_ACTION_IF_ROOM", "SHOW_AS_ACTION_ALWAYS");
-    }
-
-    @Override
-    public void visitReference(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UReferenceExpression reference, @NonNull PsiElement resolved) {
-        if (resolved instanceof PsiField
-                && JavaEvaluator.isMemberInClass((PsiField) resolved,
-                "android.view.MenuItem")) {
-            if ("SHOW_AS_ACTION_ALWAYS".equals(((PsiField) resolved).getName())) {
-                if (context.getDriver().isSuppressed(context, ISSUE, reference)) {
-                    return;
-                }
-                if (mAlwaysFields == null) {
-                    mAlwaysFields = new ArrayList<Location>();
-                }
-                mAlwaysFields.add(context.getUastLocation(reference));
-            } else {
-                mHasIfRoomRefs = true;
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AndroidAutoDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AndroidAutoDetector.java
deleted file mode 100644
index 6a7cca0..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AndroidAutoDetector.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.TAG_INTENT_FILTER;
-import static com.android.SdkConstants.TAG_SERVICE;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-import static com.android.xml.AndroidManifest.NODE_ACTION;
-import static com.android.xml.AndroidManifest.NODE_APPLICATION;
-import static com.android.xml.AndroidManifest.NODE_METADATA;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.ResourceXmlDetector;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.intellij.psi.JavaRecursiveElementVisitor;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-
-/**
- * Detector for Android Auto issues.
- * <p> Uses a {@code <meta-data>} tag with a {@code name="com.google.android.gms.car.application"}
- * as a trigger for validating Automotive specific issues.
- */
-public class AndroidAutoDetector extends ResourceXmlDetector
-        implements XmlScanner, Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    public static final Implementation IMPL = new Implementation(
-            AndroidAutoDetector.class,
-            EnumSet.of(Scope.RESOURCE_FILE, Scope.MANIFEST, Scope.JAVA_FILE),
-            Scope.RESOURCE_FILE_SCOPE);
-
-    /** Invalid attribute for uses tag.*/
-    public static final Issue INVALID_USES_TAG_ISSUE = Issue.create(
-            "InvalidUsesTagAttribute", //$NON-NLS-1$
-            "Invalid `name` attribute for `uses` element.",
-            "The <uses> element in `<automotiveApp>` should contain a " +
-            "valid value for the `name` attribute.\n" +
-            "Valid values are `media` or `notification`.",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            IMPL).addMoreInfo(
-            "https://developer.android.com/training/auto/start/index.html#auto-metadata");
-
-    /** Missing MediaBrowserService action */
-    public static final Issue MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE = Issue.create(
-            "MissingMediaBrowserServiceIntentFilter", //$NON-NLS-1$
-            "Missing intent-filter with action `android.media.browse.MediaBrowserService`.",
-            "An Automotive Media App requires an exported service that extends " +
-            "`android.service.media.MediaBrowserService` with an " +
-            "`intent-filter` for the action `android.media.browse.MediaBrowserService` " +
-            "to be able to browse and play media.\n" +
-            "To do this, add\n" +
-            "`<intent-filter>`\n" +
-            "    `<action android:name=\"android.media.browse.MediaBrowserService\" />`\n" +
-            "`</intent-filter>`\n to the service that extends " +
-            "`android.service.media.MediaBrowserService`",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            IMPL).addMoreInfo(
-            "https://developer.android.com/training/auto/audio/index.html#config_manifest");
-
-    /** Missing intent-filter for Media Search. */
-    public static final Issue MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH = Issue.create(
-            "MissingIntentFilterForMediaSearch", //$NON-NLS-1$
-            "Missing intent-filter with action `android.media.action.MEDIA_PLAY_FROM_SEARCH`",
-            "To support voice searches on Android Auto, you should also register an " +
-            "`intent-filter` for the action `android.media.action.MEDIA_PLAY_FROM_SEARCH`" +
-            ".\nTo do this, add\n" +
-            "`<intent-filter>`\n" +
-            "    `<action android:name=\"android.media.action.MEDIA_PLAY_FROM_SEARCH\" />`\n" +
-            "`</intent-filter>`\n" +
-            "to your `<activity>` or `<service>`.",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            IMPL).addMoreInfo(
-            "https://developer.android.com/training/auto/audio/index.html#support_voice");
-
-    /** Missing implementation of MediaSession.Callback#onPlayFromSearch*/
-    public static final Issue MISSING_ON_PLAY_FROM_SEARCH = Issue.create(
-            "MissingOnPlayFromSearch", //$NON-NLS-1$
-            "Missing `onPlayFromSearch`.",
-            "To support voice searches on Android Auto, in addition to adding an " +
-            "`intent-filter` for the action `onPlayFromSearch`," +
-            " you also need to override and implement " +
-            "`onPlayFromSearch(String query, Bundle bundle)`",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            IMPL).addMoreInfo(
-            "https://developer.android.com/training/auto/audio/index.html#support_voice");
-
-    private static final String CAR_APPLICATION_METADATA_NAME =
-            "com.google.android.gms.car.application"; //$NON-NLS-1$
-    private static final String VAL_NAME_MEDIA = "media"; //$NON-NLS-1$
-    private static final String VAL_NAME_NOTIFICATION = "notification"; //$NON-NLS-1$
-    private static final String TAG_AUTOMOTIVE_APP = "automotiveApp"; //$NON-NLS-1$
-    private static final String ATTR_RESOURCE = "resource"; //$NON-NLS-1$
-    private static final String TAG_USES = "uses"; //$NON-NLS-1$
-    private static final String ACTION_MEDIA_BROWSER_SERVICE =
-            "android.media.browse.MediaBrowserService"; //$NON-NLS-1$
-    private static final String ACTION_MEDIA_PLAY_FROM_SEARCH =
-            "android.media.action.MEDIA_PLAY_FROM_SEARCH"; //$NON-NLS-1$
-    private static final String CLASS_MEDIA_SESSION_CALLBACK =
-            "android.media.session.MediaSession.Callback"; //$NON-NLS-1$
-    private static final String CLASS_V4MEDIA_SESSION_COMPAT_CALLBACK =
-            "android.support.v4.media.session.MediaSessionCompat.Callback"; //$NON-NLS-1$
-    private static final String METHOD_MEDIA_SESSION_PLAY_FROM_SEARCH =
-            "onPlayFromSearch"; //$NON-NLS-1$
-    private static final String BUNDLE_ARG = "android.os.Bundle"; //$NON-NLS-1$
-
-    /**
-     * Indicates whether we identified that the current app is an automotive app and
-     * that we should validate all the automotive specific issues.
-     */
-    private boolean mDoAutomotiveAppCheck;
-
-    /** Indicates that a {@link #ACTION_MEDIA_BROWSER_SERVICE} intent-filter action was found. */
-    private boolean mMediaIntentFilterFound;
-
-    /** Indicates that a {@link #ACTION_MEDIA_PLAY_FROM_SEARCH} intent-filter action was found. */
-    private boolean mMediaSearchIntentFilterFound;
-
-    /** The resource file name deduced by the meta-data resource value */
-    private String mAutomotiveResourceFileName;
-
-    /** Indicates whether this app is an automotive Media App. */
-    private boolean mIsAutomotiveMediaApp;
-
-    /** {@link Location.Handle} to the application element */
-    private Location.Handle mMainApplicationHandle;
-
-    /** Constructs a new {@link AndroidAutoDetector} check */
-    public AndroidAutoDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        // We only need to check the meta data resource file in res/xml if any.
-        return folderType == ResourceFolderType.XML;
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(
-                TAG_AUTOMOTIVE_APP, // Root element of a declared automotive descriptor.
-                NODE_METADATA,      // meta-data from AndroidManifest.xml
-                TAG_SERVICE,        // service from AndroidManifest.xml
-                TAG_INTENT_FILTER,  // Any declared intent-filter from AndroidManifest.xml
-                NODE_APPLICATION    // Used for storing the application element/location.
-        );
-    }
-
-    @Override
-    public void beforeCheckProject(@NonNull Context context) {
-        mIsAutomotiveMediaApp = false;
-        mAutomotiveResourceFileName = null;
-        mMediaIntentFilterFound = false;
-        mMediaSearchIntentFilterFound = false;
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        String tagName = element.getTagName();
-        if (NODE_METADATA.equals(tagName) && !mDoAutomotiveAppCheck) {
-            checkAutoMetadataTag(element);
-        } else if (TAG_AUTOMOTIVE_APP.equals(tagName)) {
-            checkAutomotiveAppElement(context, element);
-        } else if (NODE_APPLICATION.equals(tagName)) {
-            // Disable reporting the error if the Issue was suppressed at
-            // the application level.
-            if (context.getMainProject() == context.getProject()
-                    && !context.getProject().isLibrary()) {
-                mMainApplicationHandle = context.createLocationHandle(element);
-                mMainApplicationHandle.setClientData(element);
-            }
-        } else if (TAG_SERVICE.equals(tagName)) {
-            checkServiceForBrowserServiceIntentFilter(element);
-        } else if (TAG_INTENT_FILTER.equals(tagName)) {
-            checkForMediaSearchIntentFilter(element);
-        }
-    }
-
-    private void checkAutoMetadataTag(Element element) {
-        String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-
-        if (CAR_APPLICATION_METADATA_NAME.equals(name)) {
-            String autoFileName = element.getAttributeNS(ANDROID_URI, ATTR_RESOURCE);
-
-            if (autoFileName != null && autoFileName.startsWith("@xml/")) { //$NON-NLS-1$
-                // Store the fact that we need to check all the auto issues.
-                mDoAutomotiveAppCheck = true;
-                mAutomotiveResourceFileName =
-                        autoFileName.substring("@xml/".length()) + DOT_XML; //$NON-NLS-1$
-            }
-        }
-    }
-
-    private void checkAutomotiveAppElement(XmlContext context, Element element) {
-        // Indicates whether the current file matches the resource that was registered
-        // in AndroidManifest.xml.
-        boolean isMetadataResource =
-                mAutomotiveResourceFileName != null
-                && mAutomotiveResourceFileName.equals(context.file.getName());
-
-        for (Element child : LintUtils.getChildren(element)) {
-
-            if (TAG_USES.equals(child.getTagName())) {
-                String attrValue = child.getAttribute(ATTR_NAME);
-                if (VAL_NAME_MEDIA.equals(attrValue)) {
-                    mIsAutomotiveMediaApp |= isMetadataResource;
-                } else if (!VAL_NAME_NOTIFICATION.equals(attrValue)
-                        && context.isEnabled(INVALID_USES_TAG_ISSUE)) {
-                    // Error invalid value for attribute.
-                    Attr node = child.getAttributeNode(ATTR_NAME);
-                    if (node == null) {
-                        // no name specified
-                        continue;
-                    }
-                    context.report(INVALID_USES_TAG_ISSUE, node,
-                            context.getLocation(node),
-                            "Expecting one of `" + VAL_NAME_MEDIA + "` or `" +
-                            VAL_NAME_NOTIFICATION + "` for the name " +
-                            "attribute in " + TAG_USES + " tag.");
-                }
-            }
-        }
-        // Report any errors that we have collected that can be shown to the user
-        // once we determine that this is an Automotive Media App.
-        if (mIsAutomotiveMediaApp
-                && !context.getProject().isLibrary()
-                && mMainApplicationHandle != null
-                && mDoAutomotiveAppCheck) {
-
-            Element node = (Element) mMainApplicationHandle.getClientData();
-
-            if (!mMediaIntentFilterFound
-                    && context.isEnabled(MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE)) {
-                context.report(MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE, node,
-                        mMainApplicationHandle.resolve(),
-                        "Missing `intent-filter` for action " +
-                                "`android.media.browse.MediaBrowserService` that is required for " +
-                                "android auto support");
-            }
-            if (!mMediaSearchIntentFilterFound
-                    && context.isEnabled(MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH)) {
-                context.report(MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH, node,
-                        mMainApplicationHandle.resolve(),
-                        "Missing `intent-filter` for action " +
-                                "`android.media.action.MEDIA_PLAY_FROM_SEARCH`.");
-            }
-        }
-    }
-
-    private void checkServiceForBrowserServiceIntentFilter(Element element) {
-        if (TAG_SERVICE.equals(element.getTagName())
-                && !mMediaIntentFilterFound) {
-
-            for (Element child : LintUtils.getChildren(element)) {
-                String tagName = child.getTagName();
-                if (TAG_INTENT_FILTER.equals(tagName)) {
-                    for (Element filterChild : LintUtils.getChildren(child)) {
-                        if (NODE_ACTION.equals(filterChild.getTagName())) {
-                            String actionValue = filterChild.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                            if (ACTION_MEDIA_BROWSER_SERVICE.equals(actionValue)) {
-                                mMediaIntentFilterFound = true;
-                                return;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkForMediaSearchIntentFilter(Element element) {
-        if (!mMediaSearchIntentFilterFound) {
-
-            for (Element filterChild : LintUtils.getChildren(element)) {
-                if (NODE_ACTION.equals(filterChild.getTagName())) {
-                    String actionValue = filterChild.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                    if (ACTION_MEDIA_PLAY_FROM_SEARCH.equals(actionValue)) {
-                        mMediaSearchIntentFilterFound = true;
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    // Implementation of the UastScanner
-
-    @Override
-    @Nullable
-    public List<String> applicableSuperClasses() {
-        // We currently enable scanning only for media apps.
-        return mIsAutomotiveMediaApp ?
-                Arrays.asList(CLASS_MEDIA_SESSION_CALLBACK,
-                        CLASS_V4MEDIA_SESSION_COMPAT_CALLBACK)
-                : null;
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        // Only check classes that are not declared abstract.
-        if (!context.getEvaluator().isAbstract(declaration)) {
-            MediaSessionCallbackVisitor visitor = new MediaSessionCallbackVisitor(context);
-            declaration.accept(visitor);
-            if (!visitor.isPlayFromSearchMethodFound()
-                    && context.isEnabled(MISSING_ON_PLAY_FROM_SEARCH)) {
-
-                context.reportUast(MISSING_ON_PLAY_FROM_SEARCH, declaration,
-                        context.getUastNameLocation(declaration),
-                        "This class does not override `" +
-                                METHOD_MEDIA_SESSION_PLAY_FROM_SEARCH + "` from `MediaSession.Callback`" +
-                                " The method should be overridden and implemented to support " +
-                                "Voice search on Android Auto.");
-            }
-        }
-    }
-
-    /**
-     * A Visitor class to search for {@code MediaSession.Callback#onPlayFromSearch(..)}
-     * method declaration.
-     */
-    private static class MediaSessionCallbackVisitor extends JavaRecursiveElementVisitor {
-
-        private final JavaContext mContext;
-
-        private boolean mOnPlayFromSearchFound;
-
-        public MediaSessionCallbackVisitor(JavaContext context) {
-            this.mContext = context;
-        }
-
-        public boolean isPlayFromSearchMethodFound() {
-            return mOnPlayFromSearchFound;
-        }
-
-        @Override
-        public void visitMethod(PsiMethod method) {
-            super.visitMethod(method);
-            if (METHOD_MEDIA_SESSION_PLAY_FROM_SEARCH.equals(method.getName())
-                    && mContext.getEvaluator().parametersMatch(method, TYPE_STRING,
-                    BUNDLE_ARG)) {
-                mOnPlayFromSearchFound = true;
-            }
-        }
-    }
-
-    // Used by the IDE to show errors.
-    @SuppressWarnings("unused")
-    @NonNull
-    public static String[] getAllowedAutomotiveAppTypes() {
-        return new String[]{VAL_NAME_MEDIA, VAL_NAME_NOTIFICATION};
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java
deleted file mode 100644
index 379fb18..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.ExternalReferenceExpression;
-import com.android.tools.klint.client.api.IssueRegistry;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.java.JavaUAnnotation;
-import org.jetbrains.uast.java.JavaUTypeCastExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.*;
-
-import static com.android.SdkConstants.*;
-import static com.android.tools.klint.checks.PermissionRequirement.getAnnotationBooleanValue;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.*;
-import static com.android.tools.klint.client.api.JavaParser.*;
-import static com.android.tools.klint.detector.api.LintUtils.getAutoBoxedType;
-import static com.android.tools.klint.detector.api.ResourceEvaluator.*;
-
-/**
- * Checks annotations to make sure they are valid
- */
-public class AnnotationDetector extends Detector implements Detector.UastScanner {
-
-    public static final Implementation IMPLEMENTATION = new Implementation(
-            AnnotationDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Placing SuppressLint on a local variable doesn't work for class-file based checks */
-    public static final Issue INSIDE_METHOD = Issue.create(
-            "LocalSuppress", //$NON-NLS-1$
-            "@SuppressLint on invalid element",
-
-            "The `@SuppressAnnotation` is used to suppress Lint warnings in Java files. However, " +
-            "while many lint checks analyzes the Java source code, where they can find " +
-            "annotations on (for example) local variables, some checks are analyzing the " +
-            "`.class` files. And in class files, annotations only appear on classes, fields " +
-            "and methods. Annotations placed on local variables disappear. If you attempt " +
-            "to suppress a lint error for a class-file based lint check, the suppress " +
-            "annotation not work. You must move the annotation out to the surrounding method.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** Incorrectly using a support annotation */
-    @SuppressWarnings("WeakerAccess")
-    public static final Issue ANNOTATION_USAGE = Issue.create(
-            "SupportAnnotationUsage", //$NON-NLS-1$
-            "Incorrect support annotation usage",
-
-            "This lint check makes sure that the support annotations (such as " +
-            "`@IntDef` and `@ColorInt`) are used correctly. For example, it's an " +
-            "error to specify an `@IntRange` where the `from` value is higher than " +
-            "the `to` value.",
-
-            Category.CORRECTNESS,
-            2,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** IntDef annotations should be unique */
-    public static final Issue UNIQUE = Issue.create(
-            "UniqueConstants", //$NON-NLS-1$
-            "Overlapping Enumeration Constants",
-
-            "The `@IntDef` annotation allows you to " +
-            "create a light-weight \"enum\" or type definition. However, it's possible to " +
-            "accidentally specify the same value for two or more of the values, which can " +
-            "lead to hard-to-detect bugs. This check looks for this scenario and flags any " +
-            "repeated constants.\n" +
-            "\n" +
-            "In some cases, the repeated constant is intentional (for example, renaming a " +
-            "constant to a more intuitive name, and leaving the old name in place for " +
-            "compatibility purposes.)  In that case, simply suppress this check by adding a " +
-            "`@SuppressLint(\"UniqueConstants\")` annotation.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** Flags should typically be specified as bit shifts */
-    public static final Issue FLAG_STYLE = Issue.create(
-            "ShiftFlags", //$NON-NLS-1$
-            "Dangerous Flag Constant Declaration",
-
-            "When defining multiple constants for use in flags, the recommended style is " +
-            "to use the form `1 << 2`, `1 << 3`, `1 << 4` and so on to ensure that the " +
-            "constants are unique and non-overlapping.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** All IntDef constants should be included in switch */
-    public static final Issue SWITCH_TYPE_DEF = Issue.create(
-            "SwitchIntDef", //$NON-NLS-1$
-            "Missing @IntDef in Switch",
-
-            "This check warns if a `switch` statement does not explicitly include all " +
-            "the values declared by the typedef `@IntDef` declaration.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Constructs a new {@link AnnotationDetector} check */
-    public AnnotationDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    /**
-     * Set of fields we've already warned about {@link #FLAG_STYLE} for; these can
-     * be referenced multiple times, so we should only flag them once
-     */
-    private Set<PsiElement> mWarnedFlags;
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        List<Class<? extends UElement>> types = new ArrayList<Class<? extends UElement>>(2);
-        types.add(UAnnotation.class);
-        types.add(USwitchExpression.class);
-        return types;
-    }
-
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new AnnotationChecker(context);
-    }
-
-    private class AnnotationChecker extends AbstractUastVisitor {
-
-        private final JavaContext mContext;
-
-        private AnnotationChecker(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitAnnotation(@NonNull UAnnotation annotation) {
-            String type = annotation.getQualifiedName();
-            if (type == null || type.startsWith("java.lang.")) {
-                return false;
-            }
-
-            if (FQCN_SUPPRESS_LINT.equals(type)) {
-                UElement parent = annotation.getUastParent();
-                if (parent == null) {
-                    return false;
-                }
-                // Only flag local variables and parameters (not classes, fields and methods)
-                if (!(parent instanceof UDeclarationsExpression
-                      || parent instanceof ULocalVariable
-                      || parent instanceof UParameter)) {
-                    return false;
-                }
-                List<UNamedExpression> attributes = annotation.getAttributeValues();
-                if (attributes.size() == 1) {
-                    UNamedExpression attribute = attributes.get(0);
-                    UExpression value = attribute.getExpression();
-                    if (value instanceof ULiteralExpression) {
-                        Object v = ((ULiteralExpression) value).getValue();
-                        if (v instanceof String) {
-                            String id = (String) v;
-                            checkSuppressLint(annotation, id);
-                        }
-                    } else if (value instanceof PsiArrayInitializerMemberValue) {
-                        PsiArrayInitializerMemberValue initializer =
-                                (PsiArrayInitializerMemberValue) value;
-                        for (PsiAnnotationMemberValue expression : initializer.getInitializers()) {
-                            if (expression instanceof PsiLiteral) {
-                                Object v = ((PsiLiteral) expression).getValue();
-                                if (v instanceof String) {
-                                    String id = (String) v;
-                                    if (!checkSuppressLint(annotation, id)) {
-                                        return false;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            } else if (type.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) {
-                if (CHECK_RESULT_ANNOTATION.equals(type)) {
-                    // Check that the return type of this method is not void!
-                    if (annotation.getUastParent() instanceof UMethod) {
-                        UMethod method = (UMethod) annotation.getUastParent();
-                        if (!method.isConstructor()
-                            && PsiType.VOID.equals(method.getReturnType())) {
-                            mContext.report(ANNOTATION_USAGE, annotation.getPsi(),
-                                            mContext.getLocation(annotation.getPsi()),
-                                            "@CheckResult should not be specified on `void` methods");
-                        }
-                    }
-                } else if (INT_RANGE_ANNOTATION.equals(type)
-                           || FLOAT_RANGE_ANNOTATION.equals(type)) {
-                    // Check that the annotated element's type is int or long.
-                    // Also make sure that from <= to.
-                    boolean invalid;
-                    if (INT_RANGE_ANNOTATION.equals(type)) {
-                        checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
-
-                        long from = getLongAttribute(annotation, ATTR_FROM, Long.MIN_VALUE);
-                        long to = getLongAttribute(annotation, ATTR_TO, Long.MAX_VALUE);
-                        invalid = from > to;
-                    } else {
-                        checkTargetType(annotation, TYPE_FLOAT, TYPE_DOUBLE, true);
-
-                        double from = getDoubleAttribute(annotation, ATTR_FROM,
-                                                         Double.NEGATIVE_INFINITY);
-                        double to = getDoubleAttribute(annotation, ATTR_TO,
-                                                       Double.POSITIVE_INFINITY);
-                        invalid = from > to;
-                    }
-                    if (invalid) {
-                        mContext.reportUast(ANNOTATION_USAGE, annotation, mContext.getUastLocation(annotation),
-                                        "Invalid range: the `from` attribute must be less than "
-                                        + "the `to` attribute");
-                    }
-                } else if (SIZE_ANNOTATION.equals(type)) {
-                    // Check that the annotated element's type is an array, or a collection
-                    // (or at least not an int or long; if so, suggest IntRange)
-                    // Make sure the size and the modulo is not negative.
-                    int unset = -42;
-                    long exact = getLongAttribute(annotation, ATTR_VALUE, unset);
-                    long min = getLongAttribute(annotation, ATTR_MIN, Long.MIN_VALUE);
-                    long max = getLongAttribute(annotation, ATTR_MAX, Long.MAX_VALUE);
-                    long multiple = getLongAttribute(annotation, ATTR_MULTIPLE, 1);
-                    if (min > max) {
-                        mContext.report(ANNOTATION_USAGE, annotation.getPsi(), mContext.getLocation(annotation.getPsi()),
-                                        "Invalid size range: the `min` attribute must be less than "
-                                        + "the `max` attribute");
-                    } else if (multiple < 1) {
-                        mContext.report(ANNOTATION_USAGE, annotation.getPsi(), mContext.getLocation(annotation.getPsi()),
-                                        "The size multiple must be at least 1");
-
-                    } else if (exact < 0 && exact != unset || min < 0 && min != Long.MIN_VALUE) {
-                        mContext.report(ANNOTATION_USAGE, annotation.getPsi(), mContext.getLocation(annotation.getPsi()),
-                                        "The size can't be negative");
-                    }
-                } else if (COLOR_INT_ANNOTATION.equals(type) || (PX_ANNOTATION.equals(type))) {
-                    // Check that ColorInt applies to the right type
-                    checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
-                } else if (INT_DEF_ANNOTATION.equals(type)) {
-                    // Make sure IntDef constants are unique
-                    ensureUniqueValues(annotation);
-                } else if (PERMISSION_ANNOTATION.equals(type) ||
-                           PERMISSION_ANNOTATION_READ.equals(type) ||
-                           PERMISSION_ANNOTATION_WRITE.equals(type)) {
-                    // Check that if there are no arguments, this is specified on a parameter,
-                    // and conversely, on methods and fields there is a valid argument.
-                    if (annotation.getUastParent() instanceof UMethod) {
-                        String value = PermissionRequirement.getAnnotationStringValue(annotation, ATTR_VALUE);
-                        String[] anyOf = PermissionRequirement.getAnnotationStringValues(annotation, ATTR_ANY_OF);
-                        String[] allOf = PermissionRequirement.getAnnotationStringValues(annotation, ATTR_ALL_OF);
-
-                        int set = 0;
-                        //noinspection VariableNotUsedInsideIf
-                        if (value != null) {
-                            set++;
-                        }
-                        //noinspection VariableNotUsedInsideIf
-                        if (allOf != null) {
-                            set++;
-                        }
-                        //noinspection VariableNotUsedInsideIf
-                        if (anyOf != null) {
-                            set++;
-                        }
-
-                        if (set == 0) {
-                            mContext.report(ANNOTATION_USAGE, annotation.getPsi(),
-                                            mContext.getLocation(annotation.getPsi()),
-                                            "For methods, permission annotation should specify one "
-                                            + "of `value`, `anyOf` or `allOf`");
-                        } else if (set > 1) {
-                            mContext.report(ANNOTATION_USAGE, annotation.getPsi(),
-                                            mContext.getLocation(annotation.getPsi()),
-                                            "Only specify one of `value`, `anyOf` or `allOf`");
-                        }
-                    }
-
-                } else if (type.endsWith(RES_SUFFIX)) {
-                    // Check that resource type annotations are on ints
-                    checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
-                }
-            } else {
-                // Look for typedefs (and make sure they're specified on the right type)
-                PsiElement resolved = annotation.resolve();
-                if (resolved != null) {
-                    PsiClass cls = (PsiClass) resolved;
-                    if (cls.isAnnotationType() && cls.getModifierList() != null) {
-                        for (PsiAnnotation a : cls.getModifierList().getAnnotations()) {
-                            String name = a.getQualifiedName();
-                            if (INT_DEF_ANNOTATION.equals(name)) {
-                                checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
-                            } else if (STRING_DEF_ANNOTATION.equals(type)) {
-                                checkTargetType(annotation, TYPE_STRING, null, true);
-                            }
-                        }
-                    }
-                }
-            }
-
-            return false;
-        }
-
-        private void checkTargetType(@NonNull UAnnotation node, @NonNull String type1,
-                @Nullable String type2, boolean allowCollection) {
-            UElement parent = node.getUastParent();
-            PsiType type;
-
-            if (parent instanceof UDeclarationsExpression) {
-                List<UDeclaration> elements = ((UDeclarationsExpression) parent).getDeclarations();
-                if (!elements.isEmpty()) {
-                    UDeclaration element = elements.get(0);
-                    if (element instanceof ULocalVariable) {
-                        type = ((ULocalVariable) element).getType();
-                    } else {
-                        return;
-                    }
-                } else {
-                    return;
-                }
-            } else if (parent instanceof UMethod) {
-                UMethod method = (UMethod) parent;
-                type = method.isConstructor()
-                       ? mContext.getEvaluator().getClassType(method.getContainingClass())
-                       : method.getReturnType();
-            } else if (parent instanceof UVariable) {
-                // Field or local variable or parameter
-                type = ((UVariable) parent).getType();
-            } else {
-                return;
-            }
-            if (type == null) {
-                return;
-            }
-
-            if (allowCollection) {
-                if (type instanceof PsiArrayType) {
-                    // For example, int[]
-                    type = type.getDeepComponentType();
-                } else if (type instanceof PsiClassType) {
-                    // For example, List<Integer>
-                    PsiClassType classType = (PsiClassType)type;
-                    if (classType.getParameters().length == 1) {
-                        PsiClass resolved = classType.resolve();
-                        if (resolved != null &&
-                            InheritanceUtil.isInheritor(resolved, false, "java.util.Collection")) {
-                            type = classType.getParameters()[0];
-                        }
-                    }
-                }
-            }
-
-            String typeName = type.getCanonicalText();
-            if (!typeName.equals(type1)
-                && (type2 == null || !typeName.equals(type2))) {
-                // Autoboxing? You can put @DrawableRes on a java.lang.Integer for example
-                if (typeName.equals(getAutoBoxedType(type1))
-                    || type2 != null && typeName.equals(getAutoBoxedType(type2))) {
-                    return;
-                }
-
-                String expectedTypes = type2 == null ? type1 : type1 + " or " + type2;
-                if (typeName.equals(TYPE_STRING)) {
-                    typeName = "String";
-                }
-                String message = String.format(
-                        "This annotation does not apply for type %1$s; expected %2$s",
-                        typeName, expectedTypes);
-                Location location = mContext.getUastLocation(node);
-                mContext.report(ANNOTATION_USAGE, node, location, message);
-            }
-        }
-
-        @Override
-        public boolean visitSwitchExpression(USwitchExpression switchExpression) {
-            UExpression condition = switchExpression.getExpression();
-            if (condition != null && PsiType.INT.equals(condition.getExpressionType())) {
-                UAnnotation annotation = findIntDefAnnotation(condition);
-                if (annotation != null) {
-                    UExpression value =
-                            annotation.findDeclaredAttributeValue(ATTR_VALUE);
-                    if (value == null) {
-                        value = annotation.findDeclaredAttributeValue(null);
-                    }
-
-                    if (UastExpressionUtils.isArrayInitializer(value)) {
-                        List<UExpression> allowedValues =
-                                ((UCallExpression) value).getValueArguments();
-                        switchExpression.accept(new SwitchChecker(switchExpression, allowedValues));
-                    }
-                }
-            }
-            return false;
-        }
-
-        @Nullable
-        private Integer getConstantValue(@NonNull PsiField intDefConstantRef) {
-            Object constant = intDefConstantRef.computeConstantValue();
-            if (constant instanceof Number) {
-                return ((Number)constant).intValue();
-            }
-
-            return null;
-        }
-
-        /**
-         * Searches for the corresponding @IntDef annotation definition associated
-         * with a given node
-         */
-        @Nullable
-        private UAnnotation findIntDefAnnotation(@NonNull UExpression expression) {
-            if (expression instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) expression).resolve();
-
-                if (resolved instanceof PsiModifierListOwner) {
-                    PsiAnnotation[] annotations = mContext.getEvaluator().getAllAnnotations(
-                            (PsiModifierListOwner)resolved);
-                    PsiAnnotation[] relevantAnnotations =
-                            filterRelevantAnnotations(mContext.getEvaluator(), annotations);
-                    UAnnotation annotation = SupportAnnotationDetector.findIntDef(
-                            JavaUAnnotation.wrap(relevantAnnotations));
-                    if (annotation != null) {
-                        return annotation;
-                    }
-                }
-
-                if (resolved instanceof PsiLocalVariable) {
-                    PsiLocalVariable variable = (PsiLocalVariable) resolved;
-                    UExpression lastAssignment = UastLintUtils.findLastAssignment(variable,
-                                                                                  expression, mContext);
-
-                    if(lastAssignment != null) {
-                        return findIntDefAnnotation(lastAssignment);
-                    }
-
-                }
-
-            } else if (expression instanceof UCallExpression) {
-                PsiMethod method = ((UCallExpression) expression).resolve();
-                if (method != null) {
-                    PsiAnnotation[] annotations =
-                            mContext.getEvaluator().getAllAnnotations(method);
-                    PsiAnnotation[] relevantAnnotations =
-                            filterRelevantAnnotations(mContext.getEvaluator(), annotations);
-                    List<UAnnotation> uAnnotations = JavaUAnnotation.wrap(relevantAnnotations);
-                    UAnnotation annotation = SupportAnnotationDetector.findIntDef(uAnnotations);
-                    if (annotation != null) {
-                        return annotation;
-                    }
-                }
-            } else if (expression instanceof UIfExpression) {
-                UIfExpression ifExpression = (UIfExpression) expression;
-                if (ifExpression.getThenExpression() != null) {
-                    UAnnotation result = findIntDefAnnotation(ifExpression.getThenExpression());
-                    if (result != null) {
-                        return result;
-                    }
-                }
-                if (ifExpression.getElseExpression() != null) {
-                    UAnnotation result = findIntDefAnnotation(ifExpression.getElseExpression());
-                    if (result != null) {
-                        return result;
-                    }
-                }
-            } else if (expression instanceof JavaUTypeCastExpression) {
-                return findIntDefAnnotation(((JavaUTypeCastExpression)expression).getOperand());
-
-            } else if (expression instanceof UParenthesizedExpression) {
-                return findIntDefAnnotation(((UParenthesizedExpression) expression).getExpression());
-            }
-
-            return null;
-        }
-
-        private void ensureUniqueValues(@NonNull UAnnotation node) {
-            UExpression value = node.findAttributeValue(ATTR_VALUE);
-            if (value == null) {
-                value = node.findAttributeValue(null);
-            }
-
-            if (!(UastExpressionUtils.isArrayInitializer(value))) {
-                return;
-            }
-
-            PsiArrayInitializerMemberValue array = (PsiArrayInitializerMemberValue) value;
-            PsiAnnotationMemberValue[] initializers = array.getInitializers();
-            Map<Number,Integer> valueToIndex =
-                    Maps.newHashMapWithExpectedSize(initializers.length);
-
-            boolean flag = getAnnotationBooleanValue(node, TYPE_DEF_FLAG_ATTRIBUTE) == Boolean.TRUE;
-            if (flag) {
-                ensureUsingFlagStyle(initializers);
-            }
-
-            ConstantEvaluator constantEvaluator = new ConstantEvaluator(mContext);
-            for (int index = 0; index < initializers.length; index++) {
-                PsiAnnotationMemberValue expression = initializers[index];
-                Object o = constantEvaluator.evaluate(expression);
-                if (o instanceof Number) {
-                    Number number = (Number) o;
-                    if (valueToIndex.containsKey(number)) {
-                        @SuppressWarnings("UnnecessaryLocalVariable")
-                        Number repeatedValue = number;
-
-                        Location location;
-                        String message;
-                        int prevIndex = valueToIndex.get(number);
-                        PsiElement prevConstant = initializers[prevIndex];
-                        message = String.format(
-                                "Constants `%1$s` and `%2$s` specify the same exact "
-                                + "value (%3$s); this is usually a cut & paste or "
-                                + "merge error",
-                                expression.getText(), prevConstant.getText(),
-                                repeatedValue.toString());
-                        location = mContext.getLocation(expression);
-                        Location secondary = mContext.getLocation(prevConstant);
-                        secondary.setMessage("Previous same value");
-                        location.setSecondary(secondary);
-                        UElement scope = getAnnotationScope(node);
-                        mContext.reportUast(UNIQUE, scope, location, message);
-                        break;
-                    }
-                    valueToIndex.put(number, index);
-                }
-            }
-        }
-
-        private void ensureUsingFlagStyle(@NonNull PsiAnnotationMemberValue[] constants) {
-            if (constants.length < 3) {
-                return;
-            }
-
-            for (PsiAnnotationMemberValue constant : constants) {
-                if (constant instanceof PsiReferenceExpression) {
-                    PsiElement resolved = ((PsiReferenceExpression) constant).resolve();
-                    if (resolved instanceof PsiField) {
-                        PsiExpression initializer = ((PsiField) resolved).getInitializer();
-                        if (initializer instanceof PsiLiteral) {
-                            PsiLiteral literal = (PsiLiteral) initializer;
-                            Object o = literal.getValue();
-                            if (!(o instanceof Number)) {
-                                continue;
-                            }
-                            long value = ((Number)o).longValue();
-                            // Allow -1, 0 and 1. You can write 1 as "1 << 0" but IntelliJ for
-                            // example warns that that's a redundant shift.
-                            if (Math.abs(value) <= 1) {
-                                continue;
-                            }
-                            // Only warn if we're setting a specific bit
-                            if (Long.bitCount(value) != 1) {
-                                continue;
-                            }
-                            int shift = Long.numberOfTrailingZeros(value);
-                            if (mWarnedFlags == null) {
-                                mWarnedFlags = Sets.newHashSet();
-                            }
-                            if (!mWarnedFlags.add(resolved)) {
-                                return;
-                            }
-                            String message = String.format(
-                                    "Consider declaring this constant using 1 << %1$d instead",
-                                    shift);
-                            Location location = mContext.getLocation(initializer);
-                            mContext.report(FLAG_STYLE, initializer, location, message);
-                        }
-                    }
-                }
-            }
-        }
-
-        private boolean checkSuppressLint(@NonNull UAnnotation node, @NonNull String id) {
-            IssueRegistry registry = mContext.getDriver().getRegistry();
-            Issue issue = registry.getIssue(id);
-            // Special-case the ApiDetector issue, since it does both source file analysis
-            // only on field references, and class file analysis on the rest, so we allow
-            // annotations outside of methods only on fields
-            if (issue != null && !issue.getImplementation().getScope().contains(Scope.JAVA_FILE)
-                || issue == ApiDetector.UNSUPPORTED) {
-                // This issue doesn't have AST access: annotations are not
-                // available for local variables or parameters
-                UElement scope = getAnnotationScope(node);
-                mContext.report(INSIDE_METHOD, scope, mContext.getUastLocation(node), String.format(
-                        "The `@SuppressLint` annotation cannot be used on a local " +
-                        "variable with the lint check '%1$s': move out to the " +
-                        "surrounding method", id));
-                return false;
-            }
-
-            return true;
-        }
-
-        private class SwitchChecker extends AbstractUastVisitor {
-
-            private final USwitchExpression mSwitchExpression;
-            private final List<UExpression> mAllowedValues;
-            private final List<Object> mFields;
-            private final List<Integer> mSeenValues;
-
-            private boolean mReported = false;
-
-            private SwitchChecker(USwitchExpression switchExpression,
-                    List<UExpression> allowedValues) {
-                mSwitchExpression = switchExpression;
-                mAllowedValues = allowedValues;
-
-                mFields = Lists.newArrayListWithCapacity(allowedValues.size());
-                for (UExpression allowedValue : allowedValues) {
-                    if (allowedValue instanceof ExternalReferenceExpression) {
-                        ExternalReferenceExpression externalRef =
-                                (ExternalReferenceExpression) allowedValue;
-
-                        PsiElement resolved = UastLintUtils.resolve(externalRef, switchExpression);
-
-                        if (resolved instanceof PsiField) {
-                            mFields.add(resolved);
-                        }
-                    } else if (allowedValue instanceof UReferenceExpression) {
-                        PsiElement resolved = ((UReferenceExpression) allowedValue).resolve();
-                        if (resolved != null) {
-                            mFields.add(resolved);
-                        }
-                    } else if (allowedValue instanceof ULiteralExpression) {
-                        mFields.add(allowedValue);
-                    }
-                }
-
-                mSeenValues = Lists.newArrayListWithCapacity(allowedValues.size());
-            }
-
-            @Override
-            public boolean visitSwitchClauseExpression(USwitchClauseExpression node) {
-                if (mReported) {
-                    return true;
-                }
-
-                if (mAllowedValues == null) {
-                    return true;
-                }
-
-                List<UExpression> caseValues = node.getCaseValues();
-                if (caseValues == null) {
-                    return true;
-                }
-
-                for (UExpression caseValue : caseValues) {
-                    if (caseValue instanceof ULiteralExpression) {
-                        // Report warnings if you specify hardcoded constants.
-                        // It's the wrong thing to do.
-                        List<String> list = computeFieldNames(mSwitchExpression,
-                                                              Arrays.asList(mAllowedValues));
-                        // Keep error message in sync with {@link #getMissingCases}
-                        String message = "Don't use a constant here; expected one of: " + Joiner
-                                .on(", ").join(list);
-                        mContext.report(SWITCH_TYPE_DEF, caseValue,
-                                        mContext.getUastLocation(caseValue), message);
-                        // Don't look for other missing typedef constants since you might
-                        // have aliased with value
-                        mReported = true;
-
-                    } else if (caseValue instanceof UReferenceExpression) { // default case can have null expression
-                        PsiElement resolved = ((UReferenceExpression) caseValue).resolve();
-                        if (resolved == null) {
-                            // If there are compilation issues (e.g. user is editing code) we
-                            // can't be certain, so don't flag anything.
-                            return true;
-                        }
-                        if (resolved instanceof PsiField) {
-                            // We can't just do
-                            //    fields.remove(resolved);
-                            // since the fields list contains instances of potentially
-                            // different types with different hash codes (due to the
-                            // external annotations, which are not of the same type as
-                            // for example the ECJ based ones.
-                            //
-                            // The equals method on external field class deliberately handles
-                            // this (but it can't make its hash code match what
-                            // the ECJ fields do, which is tied to the ECJ binding hash code.)
-                            // So instead, manually check for equals. These lists tend to
-                            // be very short anyway.
-                            boolean found = false;
-                            ListIterator<Object> iterator = mFields.listIterator();
-                            while (iterator.hasNext()) {
-                                Object field = iterator.next();
-                                if (field.equals(resolved)) {
-                                    iterator.remove();
-                                    found = true;
-                                    break;
-                                }
-                            }
-                            if (!found) {
-                                // Look for local alias
-                                UExpression initializer = mContext.getUastContext()
-                                        .getInitializerBody(((PsiField) resolved));
-                                if (initializer instanceof UReferenceExpression) {
-                                    resolved = ((UReferenceExpression) initializer).resolve();
-                                    if (resolved instanceof PsiField) {
-                                        iterator = mFields.listIterator();
-                                        while (iterator.hasNext()) {
-                                            Object field = iterator.next();
-                                            if (field.equals(resolved)) {
-                                                iterator.remove();
-                                                found = true;
-                                                break;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-
-                            if (found) {
-                                Integer cv = getConstantValue((PsiField) resolved);
-                                if (cv != null) {
-                                    mSeenValues.add(cv);
-                                }
-                            } else {
-                                List<String> list = computeFieldNames(
-                                        mSwitchExpression, Collections.singletonList(mAllowedValues));
-                                // Keep error message in sync with {@link #getMissingCases}
-                                String message = "Unexpected constant; expected one of: " + Joiner
-                                        .on(", ").join(list);
-                                Location location = mContext.getUastNameLocation(caseValue);
-                                mContext.report(SWITCH_TYPE_DEF, caseValue, location, message);
-                            }
-                        }
-                    }
-                }
-                return true;
-            }
-
-            @Override
-            public void afterVisitSwitchExpression(USwitchExpression node) {
-                reportMissingSwitchCases();
-                super.afterVisitSwitchExpression(node);
-            }
-
-            private void reportMissingSwitchCases() {
-                if (mReported) {
-                    return;
-                }
-
-                if (mAllowedValues == null) {
-                    return;
-                }
-
-                // Any missing switch constants? Before we flag them, look to see if any
-                // of them have the same values: those can be omitted
-                if (!mFields.isEmpty()) {
-                    ListIterator<Object> iterator = mFields.listIterator();
-                    while (iterator.hasNext()) {
-                        Object next = iterator.next();
-                        if (next instanceof PsiField) {
-                            Integer cv = getConstantValue((PsiField)next);
-                            if (mSeenValues.contains(cv)) {
-                                iterator.remove();
-                            }
-                        }
-                    }
-                }
-
-                if (!mFields.isEmpty()) {
-                    List<String> list = computeFieldNames(mSwitchExpression, mFields);
-                    // Keep error message in sync with {@link #getMissingCases}
-                    String message = "Switch statement on an `int` with known associated constant "
-                                     + "missing case " + Joiner.on(", ").join(list);
-                    Location location = mContext.getUastLocation(mSwitchExpression.getSwitchIdentifier());
-                    mContext.report(SWITCH_TYPE_DEF, mSwitchExpression, location, message);
-                }
-            }
-        }
-    }
-
-    private static List<String> computeFieldNames(
-            @NonNull USwitchExpression node, Iterable<?> allowedValues) {
-
-        List<String> list = Lists.newArrayList();
-        for (Object o : allowedValues) {
-            if (o instanceof ExternalReferenceExpression) {
-                ExternalReferenceExpression externalRef = (ExternalReferenceExpression) o;
-                PsiElement resolved = UastLintUtils.resolve(externalRef, node);
-                if (resolved != null) {
-                    o = resolved;
-                }
-            } else if (o instanceof PsiReferenceExpression) {
-                PsiElement resolved = ((PsiReferenceExpression) o).resolve();
-                if (resolved != null) {
-                    o = resolved;
-                }
-            } else if (o instanceof PsiLiteral) {
-                list.add("`" + ((PsiLiteral) o).getValue() + '`');
-                continue;
-            }
-
-            if (o instanceof PsiField) {
-                PsiField field = (PsiField) o;
-                // Only include class name if necessary
-                String name = field.getName();
-                UClass clz = UastUtils.getParentOfType(node, UClass.class, true);
-                if (clz != null) {
-                    PsiClass containingClass = field.getContainingClass();
-                    if (containingClass != null && !containingClass.equals(clz.getPsi())) {
-                        name = containingClass.getName() + '.' + field.getName();
-                    }
-                }
-                list.add('`' + name + '`');
-            }
-        }
-        Collections.sort(list);
-        return list;
-    }
-
-    /**
-     * Returns the node to use as the scope for the given annotation node.
-     * You can't annotate an annotation itself (with {@code @SuppressLint}), but
-     * you should be able to place an annotation next to it, as a sibling, to only
-     * suppress the error on this annotated element, not the whole surrounding class.
-     */
-    @NonNull
-    private static UElement getAnnotationScope(@NonNull UAnnotation node) {
-        UElement scope = UastUtils.getParentOfType(node, UAnnotation.class, true);
-        if (scope == null) {
-            scope = node;
-        }
-        return scope;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/Api.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/Api.java
deleted file mode 100644
index 191b172..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/Api.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-
-import com.android.annotations.NonNull;
-
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Main entry point for API description.
- *
- * To create the {@link Api}, use {@link #parseApi(File)}
- *
- */
-public class Api {
-
-    /**
-     * Parses simplified API file.
-     * @param apiFile the file to read
-     * @return a new ApiInfo
-     */
-    public static Api parseApi(File apiFile) {
-        InputStream inputStream = null;
-        try {
-            inputStream = new FileInputStream(apiFile);
-            SAXParserFactory parserFactory = SAXParserFactory.newInstance();
-            SAXParser parser = parserFactory.newSAXParser();
-            ApiParser apiParser = new ApiParser();
-            parser.parse(inputStream, apiParser);
-            inputStream.close();
-
-            // Also read in API (unless regenerating the map for newer libraries)
-            //noinspection PointlessBooleanExpression,TestOnlyProblems
-            if (!ApiLookup.DEBUG_FORCE_REGENERATE_BINARY) {
-                inputStream = Api.class.getResourceAsStream("api-versions-support-library.xml");
-                if (inputStream != null) {
-                    parser.parse(inputStream, apiParser);
-                }
-            }
-
-            return new Api(apiParser.getClasses(), apiParser.getPackages());
-        } catch (ParserConfigurationException e) {
-            e.printStackTrace();
-        } catch (SAXException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            if (inputStream != null) {
-                try {
-                    inputStream.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private final Map<String, ApiClass> mClasses;
-    private final Map<String, ApiPackage> mPackages;
-
-    private Api(
-            @NonNull Map<String, ApiClass> classes,
-            @NonNull Map<String, ApiPackage> packages) {
-        mClasses = new HashMap<String, ApiClass>(classes);
-        mPackages = new HashMap<String, ApiPackage>(packages);
-    }
-
-    ApiClass getClass(String fqcn) {
-        return mClasses.get(fqcn);
-    }
-
-    Map<String, ApiClass> getClasses() {
-        return Collections.unmodifiableMap(mClasses);
-    }
-
-    Map<String, ApiPackage> getPackages() {
-        return Collections.unmodifiableMap(mPackages);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiClass.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiClass.java
deleted file mode 100644
index 80d1771..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiClass.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.CONSTRUCTOR_NAME;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.utils.Pair;
-import com.google.common.collect.Lists;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Represents a class and its methods/fields.
- *
- * {@link #getSince()} gives the API level it was introduced.
- *
- * {@link #getMethod} returns when the method was introduced.
- * {@link #getField} returns when the field was introduced.
- */
-public class ApiClass implements Comparable<ApiClass> {
-    private final String mName;
-    private final int mSince;
-    private final int mDeprecatedIn;
-
-    private final List<Pair<String, Integer>> mSuperClasses = Lists.newArrayList();
-    private final List<Pair<String, Integer>> mInterfaces = Lists.newArrayList();
-
-    private final Map<String, Integer> mFields = new HashMap<String, Integer>();
-    private final Map<String, Integer> mMethods = new HashMap<String, Integer>();
-    private final Map<String, Integer> mDeprecatedMembersIn = new HashMap<String, Integer>();
-
-    // Persistence data: Used when writing out binary data in ApiLookup
-    List<String> members;
-    int index;               // class number, e.g. entry in index where the pointer can be found
-    int indexOffset;         // offset of the class entry
-    int memberOffsetBegin;   // offset of the first member entry in the class
-    int memberOffsetEnd;     // offset after the last member entry in the class
-    int memberIndexStart;    // entry in index for first member
-    int memberIndexLength;   // number of entries
-
-    ApiClass(String name, int since, int deprecatedIn) {
-        mName = name;
-        mSince = since;
-        mDeprecatedIn = deprecatedIn;
-    }
-
-    /**
-     * Returns the name of the class.
-     * @return the name of the class
-     */
-    String getName() {
-        return mName;
-    }
-
-    /**
-     * Returns when the class was introduced.
-     * @return the api level the class was introduced.
-     */
-    int getSince() {
-        return mSince;
-    }
-
-    /**
-     * Returns the API level a method was deprecated in, or 0 if the method is not deprecated
-     *
-     * @return the API level a method was deprecated in, or 0 if the method is not deprecated
-     */
-    int getDeprecatedIn() {
-        return mDeprecatedIn;
-    }
-
-    /**
-     * Returns when a field was added, or Integer.MAX_VALUE if it doesn't exist.
-     * @param name the name of the field.
-     * @param info the corresponding info
-     */
-    int getField(String name, Api info) {
-        // The field can come from this class or from a super class or an interface
-        // The value can never be lower than this introduction of this class.
-        // When looking at super classes and interfaces, it can never be lower than when the
-        // super class or interface was added as a super class or interface to this class.
-        // Look at all the values and take the lowest.
-        // For instance:
-        // This class A is introduced in 5 with super class B.
-        // In 10, the interface C was added.
-        // Looking for SOME_FIELD we get the following:
-        // Present in A in API 15
-        // Present in B in API 11
-        // Present in C in API 7.
-        // The answer is 10, which is when C became an interface
-        int min = Integer.MAX_VALUE;
-        Integer i = mFields.get(name);
-        if (i != null) {
-            min = i;
-        }
-
-        // now look at the super classes
-        for (Pair<String, Integer> superClassPair : mSuperClasses) {
-            ApiClass superClass = info.getClass(superClassPair.getFirst());
-            if (superClass != null) {
-                i = superClass.getField(name, info);
-                int tmp = superClassPair.getSecond() > i ? superClassPair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        // now look at the interfaces
-        for (Pair<String, Integer> superClassPair : mInterfaces) {
-            ApiClass superClass = info.getClass(superClassPair.getFirst());
-            if (superClass != null) {
-                i = superClass.getField(name, info);
-                int tmp = superClassPair.getSecond() > i ? superClassPair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        return min;
-    }
-
-    /**
-     * Returns when a field was deprecated, or 0 if it's not deprecated
-     *
-     * @param name the name of the field.
-     * @param info the corresponding info
-     */
-    int getMemberDeprecatedIn(String name, Api info) {
-        int deprecatedIn = findMemberDeprecatedIn(name, info);
-        return deprecatedIn < Integer.MAX_VALUE ? deprecatedIn : 0;
-    }
-
-    private int findMemberDeprecatedIn(String name, Api info) {
-        // This follows the same logic as getField/getMethod.
-        // However, it also incorporates deprecation versions from the class.
-        int min = Integer.MAX_VALUE;
-        Integer i = mDeprecatedMembersIn.get(name);
-        if (i != null) {
-            min = i;
-        }
-
-        // now look at the super classes
-        for (Pair<String, Integer> superClassPair : mSuperClasses) {
-            ApiClass superClass = info.getClass(superClassPair.getFirst());
-            if (superClass != null) {
-                i = superClass.findMemberDeprecatedIn(name, info);
-                int tmp = superClassPair.getSecond() > i ? superClassPair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        // now look at the interfaces
-        for (Pair<String, Integer> superClassPair : mInterfaces) {
-            ApiClass superClass = info.getClass(superClassPair.getFirst());
-            if (superClass != null) {
-                i = superClass.findMemberDeprecatedIn(name, info);
-                int tmp = superClassPair.getSecond() > i ? superClassPair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        return min;
-    }
-
-    /**
-     * Returns when a method was added, or Integer.MAX_VALUE if it doesn't exist.
-     * This goes through the super class to find method only present there.
-     * @param methodSignature the method signature
-     */
-    int getMethod(String methodSignature, Api info) {
-        // The method can come from this class or from a super class.
-        // The value can never be lower than this introduction of this class.
-        // When looking at super classes, it can never be lower than when the super class became
-        // a super class of this class.
-        // Look at all the values and take the lowest.
-        // For instance:
-        // This class A is introduced in 5 with super class B.
-        // In 10, the super class changes to C.
-        // Looking for foo() we get the following:
-        // Present in A in API 15
-        // Present in B in API 11
-        // Present in C in API 7.
-        // The answer is 10, which is when C became the super class.
-        int min = Integer.MAX_VALUE;
-        Integer i = mMethods.get(methodSignature);
-        if (i != null) {
-            min = i;
-
-            // Constructors aren't inherited
-            if (methodSignature.startsWith(CONSTRUCTOR_NAME)) {
-                return i;
-            }
-        }
-
-        // now look at the super classes
-        for (Pair<String, Integer> superClassPair : mSuperClasses) {
-            ApiClass superClass = info.getClass(superClassPair.getFirst());
-            if (superClass != null) {
-                i = superClass.getMethod(methodSignature, info);
-                int tmp = superClassPair.getSecond() > i ? superClassPair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        // now look at the interfaces classes
-        for (Pair<String, Integer> interfacePair : mInterfaces) {
-            ApiClass superClass = info.getClass(interfacePair.getFirst());
-            if (superClass != null) {
-                i = superClass.getMethod(methodSignature, info);
-                int tmp = interfacePair.getSecond() > i ? interfacePair.getSecond() : i;
-                if (tmp < min) {
-                    min = tmp;
-                }
-            }
-        }
-
-        return min;
-    }
-
-    void addField(String name, int since, int deprecatedIn) {
-        Integer i = mFields.get(name);
-        assert i == null;
-        mFields.put(name, since);
-        if (deprecatedIn > 0) {
-            mDeprecatedMembersIn.put(name, deprecatedIn);
-        }
-    }
-
-    void addMethod(String name, int since, int deprecatedIn) {
-        // Strip off the method type at the end to ensure that the code which
-        // produces inherited methods doesn't get confused and end up multiple entries.
-        // For example, java/nio/Buffer has the method "array()Ljava/lang/Object;",
-        // and the subclass java/nio/ByteBuffer has the method "array()[B". We want
-        // the lookup on mMethods to associate the ByteBuffer array method to be
-        // considered overriding the Buffer method.
-        int index = name.indexOf(')');
-        if (index != -1) {
-            name = name.substring(0, index + 1);
-        }
-
-        Integer i = mMethods.get(name);
-        assert i == null || i == since : i;
-        mMethods.put(name, since);
-        if (deprecatedIn > 0) {
-            mDeprecatedMembersIn.put(name, deprecatedIn);
-        }
-    }
-
-    void addSuperClass(String superClass, int since) {
-        addToArray(mSuperClasses, superClass, since);
-    }
-
-    void addInterface(String interfaceClass, int since) {
-        addToArray(mInterfaces, interfaceClass, since);
-    }
-
-    static void addToArray(List<Pair<String, Integer>> list, String name, int value) {
-        // check if we already have that name (at a lower level)
-        for (Pair<String, Integer> pair : list) {
-            if (name.equals(pair.getFirst())) {
-                assert false;
-                return;
-            }
-        }
-
-        list.add(Pair.of(name, value));
-
-    }
-
-    @Nullable
-    public String getPackage() {
-        int index = mName.lastIndexOf('/');
-        if (index != -1) {
-            return mName.substring(0, index);
-        }
-
-        return null;
-    }
-
-    @NonNull
-    public String getSimpleName() {
-        int index = mName.lastIndexOf('/');
-        if (index != -1) {
-            return mName.substring(index + 1);
-        }
-
-        return mName;
-    }
-
-    @Override
-    public String toString() {
-        return mName;
-    }
-
-    /**
-     * Returns the set of all methods, including inherited
-     * ones.
-     *
-     * @param info the api to look up super classes from
-     * @return a set containing all the members fields
-     */
-    Set<String> getAllMethods(Api info) {
-        Set<String> members = new HashSet<String>(100);
-        addAllMethods(info, members, true /*includeConstructors*/);
-
-        return members;
-    }
-
-    List<Pair<String, Integer>> getInterfaces() {
-        return mInterfaces;
-    }
-
-    List<Pair<String, Integer>> getSuperClasses() {
-        return mSuperClasses;
-    }
-
-    private void addAllMethods(Api info, Set<String> set, boolean includeConstructors) {
-        if (!includeConstructors) {
-            for (String method : mMethods.keySet()) {
-                if (!method.startsWith(CONSTRUCTOR_NAME)) {
-                    set.add(method);
-                }
-            }
-        } else {
-            for (String method : mMethods.keySet()) {
-                set.add(method);
-            }
-        }
-
-        for (Pair<String, Integer> superClass : mSuperClasses) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            if (clz != null) {
-                clz.addAllMethods(info, set, false);
-            }
-        }
-
-        // Get methods from implemented interfaces as well;
-        for (Pair<String, Integer> superClass : mInterfaces) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            if (clz != null) {
-                clz.addAllMethods(info, set, false);
-            }
-        }
-    }
-
-    /**
-     * Returns the set of all fields, including inherited
-     * ones.
-     *
-     * @param info the api to look up super classes from
-     * @return a set containing all the fields
-     */
-    Set<String> getAllFields(Api info) {
-        Set<String> members = new HashSet<String>(100);
-        addAllFields(info, members);
-
-        return members;
-    }
-
-    private void addAllFields(Api info, Set<String> set) {
-        for (String field : mFields.keySet()) {
-            set.add(field);
-        }
-
-        for (Pair<String, Integer> superClass : mSuperClasses) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            assert clz != null : superClass.getSecond();
-            clz.addAllFields(info, set);
-        }
-
-        // Get methods from implemented interfaces as well;
-        for (Pair<String, Integer> superClass : mInterfaces) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            assert clz != null : superClass.getSecond();
-            clz.addAllFields(info, set);
-        }
-    }
-
-    @Override
-    public int compareTo(@NonNull ApiClass other) {
-        return mName.compareTo(other.mName);
-    }
-
-    /* This code can be used to scan through all the fields and look for fields
-       that have moved to a higher class:
-            Field android/view/MotionEvent#CREATOR has api=1 but parent android/view/InputEvent provides it as 9
-            Field android/provider/ContactsContract$CommonDataKinds$Organization#PHONETIC_NAME has api=5 but parent android/provider/ContactsContract$ContactNameColumns provides it as 11
-            Field android/widget/ListView#CHOICE_MODE_MULTIPLE has api=1 but parent android/widget/AbsListView provides it as 11
-            Field android/widget/ListView#CHOICE_MODE_NONE has api=1 but parent android/widget/AbsListView provides it as 11
-            Field android/widget/ListView#CHOICE_MODE_SINGLE has api=1 but parent android/widget/AbsListView provides it as 11
-            Field android/view/KeyEvent#CREATOR has api=1 but parent android/view/InputEvent provides it as 9
-       This is used for example in the ApiDetector to filter out warnings which result
-       when people follow Eclipse's advice to replace
-            ListView.CHOICE_MODE_MULTIPLE
-       references with
-            AbsListView.CHOICE_MODE_MULTIPLE
-       since the latter has API=11 and the former has API=1; since the constant is unchanged
-       between the two, and the literal is copied into the class, using the AbsListView
-       reference works.
-    public void checkFields(Api info) {
-        fieldLoop:
-        for (String field : mFields.keySet()) {
-            Integer since = getField(field, info);
-            if (since == null || since == Integer.MAX_VALUE) {
-                continue;
-            }
-
-            for (Pair<String, Integer> superClass : mSuperClasses) {
-                ApiClass clz = info.getClass(superClass.getFirst());
-                assert clz != null : superClass.getSecond();
-                if (clz != null) {
-                    Integer superSince = clz.getField(field, info);
-                    if (superSince == Integer.MAX_VALUE) {
-                        continue;
-                    }
-
-                    if (superSince != null && superSince > since) {
-                        String declaredIn = clz.findFieldDeclaration(info, field);
-                        System.out.println("Field " + getName() + "#" + field + " has api="
-                                + since + " but parent " + declaredIn + " provides it as "
-                                + superSince);
-                        continue fieldLoop;
-                    }
-                }
-            }
-
-            // Get methods from implemented interfaces as well;
-            for (Pair<String, Integer> superClass : mInterfaces) {
-                ApiClass clz = info.getClass(superClass.getFirst());
-                assert clz != null : superClass.getSecond();
-                if (clz != null) {
-                    Integer superSince = clz.getField(field, info);
-                    if (superSince == Integer.MAX_VALUE) {
-                        continue;
-                    }
-                    if (superSince != null && superSince > since) {
-                        String declaredIn = clz.findFieldDeclaration(info, field);
-                        System.out.println("Field " + getName() + "#" + field + " has api="
-                                + since + " but parent " + declaredIn + " provides it as "
-                                + superSince);
-                        continue fieldLoop;
-                    }
-                }
-            }
-        }
-    }
-
-    private String findFieldDeclaration(Api info, String name) {
-        if (mFields.containsKey(name)) {
-            return getName();
-        }
-        for (Pair<String, Integer> superClass : mSuperClasses) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            assert clz != null : superClass.getSecond();
-            if (clz != null) {
-                String declaredIn = clz.findFieldDeclaration(info, name);
-                if (declaredIn != null) {
-                    return declaredIn;
-                }
-            }
-        }
-
-        // Get methods from implemented interfaces as well;
-        for (Pair<String, Integer> superClass : mInterfaces) {
-            ApiClass clz = info.getClass(superClass.getFirst());
-            assert clz != null : superClass.getSecond();
-            if (clz != null) {
-                String declaredIn = clz.findFieldDeclaration(info, name);
-                if (declaredIn != null) {
-                    return declaredIn;
-                }
-            }
-        }
-
-        return null;
-    }
-    */
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.java
deleted file mode 100644
index 81531cf..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.java
+++ /dev/null
@@ -1,1992 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.repository.GradleVersion;
-import com.android.repository.Revision;
-import com.android.repository.api.LocalPackage;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.SdkVersionInfo;
-import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.tools.klint.client.api.*;
-import com.android.tools.klint.detector.api.*;
-import com.android.tools.klint.detector.api.Detector.ClassScanner;
-import com.intellij.psi.*;
-import com.intellij.psi.util.MethodSignatureUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import org.jetbrains.android.inspections.klint.IntellijLintUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.android.SdkConstants.*;
-import static com.android.tools.klint.detector.api.ClassContext.getFqcn;
-import static com.android.utils.SdkUtils.getResourceFieldName;
-
-/**
- * Looks for usages of APIs that are not supported in all the versions targeted
- * by this application (according to its minimum API requirement in the manifest).
- */
-public class ApiDetector extends ResourceXmlDetector
-        implements ClassScanner, Detector.UastScanner {
-
-    private static final String ATTR_WIDTH = "width";
-    private static final String ATTR_HEIGHT = "height";
-    private static final String ATTR_SUPPORTS_RTL = "supportsRtl";
-
-    public static final String REQUIRES_API_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "RequiresApi"; //$NON-NLS-1$
-
-    /** Accessing an unsupported API */
-    @SuppressWarnings("unchecked")
-    public static final Issue UNSUPPORTED = Issue.create(
-            "NewApi", //$NON-NLS-1$
-            "Calling new methods on older versions",
-
-            "This check scans through all the Android API calls in the application and " +
-            "warns about any calls that are not available on *all* versions targeted " +
-            "by this application (according to its minimum SDK attribute in the manifest).\n" +
-            "\n" +
-            "If you really want to use this API and don't need to support older devices just " +
-            "set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.\n" +
-            "\n" +
-            "If your code is *deliberately* accessing newer APIs, and you have ensured " +
-            "(e.g. with conditional execution) that this code will only ever be called on a " +
-            "supported platform, then you can annotate your class or method with the " +
-            "`@TargetApi` annotation specifying the local minimum SDK to apply, such as " +
-            "`@TargetApi(11)`, such that this check considers 11 rather than your manifest " +
-            "file's minimum SDK as the required API level.\n" +
-            "\n" +
-            "If you are deliberately setting `android:` attributes in style definitions, " +
-            "make sure you place this in a `values-vNN` folder in order to avoid running " +
-            "into runtime conflicts on certain devices where manufacturers have added " +
-            "custom attributes whose ids conflict with the new ones on later platforms.\n" +
-            "\n" +
-            "Similarly, you can use tools:targetApi=\"11\" in an XML file to indicate that " +
-            "the element will only be inflated in an adequate context.",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            new Implementation(
-                    ApiDetector.class,
-                    EnumSet.of(Scope.JAVA_FILE, Scope.RESOURCE_FILE, Scope.MANIFEST),
-                    Scope.JAVA_FILE_SCOPE,
-                    Scope.RESOURCE_FILE_SCOPE,
-                    Scope.MANIFEST_SCOPE));
-
-    /** Accessing an inlined API on older platforms */
-    public static final Issue INLINED = Issue.create(
-            "InlinedApi", //$NON-NLS-1$
-            "Using inlined constants on older versions",
-
-            "This check scans through all the Android API field references in the application " +
-            "and flags certain constants, such as static final integers and Strings, " +
-            "which were introduced in later versions. These will actually be copied " +
-            "into the class files rather than being referenced, which means that " +
-            "the value is available even when running on older devices. In some " +
-            "cases that's fine, and in other cases it can result in a runtime " +
-            "crash or incorrect behavior. It depends on the context, so consider " +
-            "the code carefully and device whether it's safe and can be suppressed " +
-            "or whether the code needs tbe guarded.\n" +
-            "\n" +
-            "If you really want to use this API and don't need to support older devices just " +
-            "set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files." +
-            "\n" +
-            "If your code is *deliberately* accessing newer APIs, and you have ensured " +
-            "(e.g. with conditional execution) that this code will only ever be called on a " +
-            "supported platform, then you can annotate your class or method with the " +
-            "`@TargetApi` annotation specifying the local minimum SDK to apply, such as " +
-            "`@TargetApi(11)`, such that this check considers 11 rather than your manifest " +
-            "file's minimum SDK as the required API level.\n",
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    ApiDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Method conflicts with new inherited method */
-    public static final Issue OVERRIDE = Issue.create(
-            "Override", //$NON-NLS-1$
-            "Method conflicts with new inherited method",
-
-            "Suppose you are building against Android API 8, and you've subclassed Activity. " +
-            "In your subclass you add a new method called `isDestroyed`(). At some later point, " +
-            "a method of the same name and signature is added to Android. Your method will " +
-            "now override the Android method, and possibly break its contract. Your method " +
-            "is not calling `super.isDestroyed()`, since your compilation target doesn't " +
-            "know about the method.\n" +
-            "\n" +
-            "The above scenario is what this lint detector looks for. The above example is " +
-            "real, since `isDestroyed()` was added in API 17, but it will be true for *any* " +
-            "method you have added to a subclass of an Android class where your build target " +
-            "is lower than the version the method was introduced in.\n" +
-            "\n" +
-            "To fix this, either rename your method, or if you are really trying to augment " +
-            "the builtin method if available, switch to a higher build target where you can " +
-            "deliberately add `@Override` on your overriding method, and call `super` if " +
-            "appropriate etc.\n",
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            new Implementation(
-                    ApiDetector.class,
-                    Scope.CLASS_FILE_SCOPE));
-
-    /** Attribute unused on older versions */
-    public static final Issue UNUSED = Issue.create(
-            "UnusedAttribute", //$NON-NLS-1$
-            "Attribute unused on older versions",
-
-            "This check finds attributes set in XML files that were introduced in a version " +
-            "newer than the oldest version targeted by your application (with the " +
-            "`minSdkVersion` attribute).\n" +
-            "\n" +
-            "This is not an error; the application will simply ignore the attribute. However, " +
-            "if the attribute is important to the appearance of functionality of your " +
-            "application, you should consider finding an alternative way to achieve the " +
-            "same result with only available attributes, and then you can optionally create " +
-            "a copy of the layout in a layout-vNN folder which will be used on API NN or " +
-            "higher where you can take advantage of the newer attribute.\n" +
-            "\n" +
-            "Note: This check does not only apply to attributes. For example, some tags can be " +
-            "unused too, such as the new `<tag>` element in layouts introduced in API 21.",
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    ApiDetector.class,
-                    Scope.RESOURCE_FILE_SCOPE));
-
-    private static final String TAG_RIPPLE = "ripple";
-    private static final String TAG_VECTOR = "vector";
-    private static final String TAG_ANIMATED_VECTOR = "animated-vector";
-    private static final String TAG_ANIMATED_SELECTOR = "animated-selector";
-
-    private static final String SDK_INT = "SDK_INT";
-    private static final String REFLECTIVE_OPERATION_EXCEPTION = "java.lang.ReflectiveOperationException";
-    public static final String ERROR = "error";
-
-    private ApiLookup mApiDatabase;
-    private boolean mWarnedMissingDb;
-    private int mMinApi = -1;
-
-    /** Constructs a new API check */
-    public ApiDetector() {
-    }
-
-    @Override
-    public void beforeCheckProject(@NonNull Context context) {
-        if (mApiDatabase == null) {
-            mApiDatabase = ApiLookup.get(context.getClient());
-            // We can't look up the minimum API required by the project here:
-            // The manifest file hasn't been processed yet in the -before- project hook.
-            // For now it's initialized lazily in getMinSdk(Context), but the
-            // lint infrastructure should be fixed to parse manifest file up front.
-
-            if (mApiDatabase == null && !mWarnedMissingDb) {
-                mWarnedMissingDb = true;
-                context.report(IssueRegistry.LINT_ERROR, Location.create(context.file),
-                               "Can't find API database; API check not performed");
-            } else {
-                // See if you don't have at least version 23.0.1 of platform tools installed
-                AndroidSdkHandler sdk = context.getClient().getSdk();
-                if (sdk == null) {
-                    return;
-                }
-                LocalPackage pkgInfo = sdk.getLocalPackage(SdkConstants.FD_PLATFORM_TOOLS,
-                                                           context.getClient().getRepositoryLogger());
-                if (pkgInfo == null) {
-                    return;
-                }
-                Revision revision = pkgInfo.getVersion();
-
-                // The platform tools must be at at least the same revision
-                // as the compileSdkVersion!
-                // And as a special case, for 23, they must be at 23.0.1
-                // because 23.0.0 accidentally shipped without Android M APIs.
-                int compileSdkVersion = context.getProject().getBuildSdk();
-                if (compileSdkVersion == 23) {
-                    if (revision.getMajor() > 23 || revision.getMajor() == 23
-                                                    && (revision.getMinor() > 0 || revision.getMicro() > 0)) {
-                        return;
-                    }
-                } else if (compileSdkVersion <= revision.getMajor()) {
-                    return;
-                }
-
-                // Pick a location: when incrementally linting in the IDE, tie
-                // it to the current file
-                List<File> currentFiles = context.getProject().getSubset();
-                Location location;
-                if (currentFiles != null && currentFiles.size() == 1) {
-                    File file = currentFiles.get(0);
-                    String contents = context.getClient().readFile(file);
-                    int firstLineEnd = contents.indexOf('\n');
-                    if (firstLineEnd == -1) {
-                        firstLineEnd = contents.length();
-                    }
-                    location = Location.create(file,
-                                               new DefaultPosition(0, 0, 0), new
-                                                       DefaultPosition(0, firstLineEnd, firstLineEnd));
-                } else {
-                    location = Location.create(context.file);
-                }
-                context.report(UNSUPPORTED,
-                               location,
-                               String.format("The SDK platform-tools version (%1$s) is too old "
-                                             + " to check APIs compiled with API %2$d; please update",
-                                             revision.toShortString(),
-                                             compileSdkVersion));
-            }
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return true;
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return ALL;
-    }
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        return ALL;
-    }
-
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        if (mApiDatabase == null) {
-            return;
-        }
-
-        int attributeApiLevel = -1;
-        if (ANDROID_URI.equals(attribute.getNamespaceURI())) {
-            String name = attribute.getLocalName();
-            if (!(name.equals(ATTR_LAYOUT_WIDTH) && !(name.equals(ATTR_LAYOUT_HEIGHT)) &&
-                  !(name.equals(ATTR_ID)))) {
-                String owner = "android/R$attr"; //$NON-NLS-1$
-                attributeApiLevel = mApiDatabase.getFieldVersion(owner, name);
-                int minSdk = getMinSdk(context);
-                if (attributeApiLevel > minSdk && attributeApiLevel > context.getFolderVersion()
-                    && attributeApiLevel > getLocalMinSdk(attribute.getOwnerElement())
-                    && !isBenignUnusedAttribute(name)
-                    && !isAlreadyWarnedDrawableFile(context, attribute, attributeApiLevel)) {
-                    if (RtlDetector.isRtlAttributeName(name) || ATTR_SUPPORTS_RTL.equals(name)) {
-                        // No need to warn for example that
-                        //  "layout_alignParentEnd will only be used in API level 17 and higher"
-                        // since we have a dedicated RTL lint rule dealing with those attributes
-
-                        // However, paddingStart in particular is known to cause crashes
-                        // when used on TextViews (and subclasses of TextViews), on some
-                        // devices, because vendor specific attributes conflict with the
-                        // later-added framework resources, and these are apparently read
-                        // by the text views.
-                        //
-                        // However, as of build tools 23.0.1 aapt works around this by packaging
-                        // the resources differently.
-                        if (name.equals(ATTR_PADDING_START)) {
-                            BuildToolInfo buildToolInfo = context.getProject().getBuildTools();
-                            Revision buildTools = buildToolInfo != null
-                                                  ? buildToolInfo.getRevision() : null;
-                            boolean isOldBuildTools = buildTools != null &&
-                                                      (buildTools.getMajor() < 23 || buildTools.getMajor() == 23
-                                                                                     && buildTools.getMinor() == 0 && buildTools.getMicro() == 0);
-                            if ((buildTools == null || isOldBuildTools) &&
-                                viewMayExtendTextView(attribute.getOwnerElement())) {
-                                Location location = context.getLocation(attribute);
-                                String message = String.format(
-                                        "Attribute `%1$s` referenced here can result in a crash on "
-                                        + "some specific devices older than API %2$d "
-                                        + "(current min is %3$d)",
-                                        attribute.getLocalName(), attributeApiLevel, minSdk);
-                                //noinspection VariableNotUsedInsideIf
-                                if (buildTools != null) {
-                                    message = String.format("Upgrade `buildToolsVersion` from "
-                                                            + "`%1$s` to at least `23.0.1`; if not, ",
-                                                            buildTools.toShortString())
-                                              + Character.toLowerCase(message.charAt(0))
-                                              + message.substring(1);
-                                }
-                                context.report(UNSUPPORTED, attribute, location, message);
-                            }
-                        }
-                    } else {
-                        Location location = context.getLocation(attribute);
-                        String message = String.format(
-                                "Attribute `%1$s` is only used in API level %2$d and higher "
-                                + "(current min is %3$d)",
-                                attribute.getLocalName(), attributeApiLevel, minSdk);
-                        context.report(UNUSED, attribute, location, message);
-                    }
-                }
-            }
-
-            // Special case:
-            // the dividers attribute is present in API 1, but it won't be read on older
-            // versions, so don't flag the common pattern
-            //    android:divider="?android:attr/dividerHorizontal"
-            // since this will work just fine. See issue 67440 for more.
-            if (name.equals("divider")) {
-                return;
-            }
-        }
-
-        String value = attribute.getValue();
-        String owner = null;
-        String name = null;
-        String prefix;
-        if (value.startsWith(ANDROID_PREFIX)) {
-            prefix = ANDROID_PREFIX;
-        } else if (value.startsWith(ANDROID_THEME_PREFIX)) {
-            prefix = ANDROID_THEME_PREFIX;
-            if (context.getResourceFolderType() == ResourceFolderType.DRAWABLE) {
-                int api = 21;
-                int minSdk = getMinSdk(context);
-                if (api > minSdk && api > context.getFolderVersion()
-                    && api > getLocalMinSdk(attribute.getOwnerElement())) {
-                    Location location = context.getLocation(attribute);
-                    String message;
-                    message = String.format(
-                            "Using theme references in XML drawables requires API level %1$d "
-                            + "(current min is %2$d)", api,
-                            minSdk);
-                    context.report(UNSUPPORTED, attribute, location, message);
-                    // Don't flag individual theme attribute requirements here, e.g. once
-                    // we've told you that you need at least v21 to reference themes, we don't
-                    // need to also tell you that ?android:selectableItemBackground requires
-                    // API level 11
-                    return;
-                }
-            }
-        } else if (value.startsWith(PREFIX_ANDROID) && ATTR_NAME.equals(attribute.getName())
-                   && TAG_ITEM.equals(attribute.getOwnerElement().getTagName())
-                   && attribute.getOwnerElement().getParentNode() != null
-                   && TAG_STYLE.equals(attribute.getOwnerElement().getParentNode().getNodeName())) {
-            owner = "android/R$attr"; //$NON-NLS-1$
-            name = value.substring(PREFIX_ANDROID.length());
-            prefix = null;
-        } else if (value.startsWith(PREFIX_ANDROID) && ATTR_PARENT.equals(attribute.getName())
-                   && TAG_STYLE.equals(attribute.getOwnerElement().getTagName())) {
-            owner = "android/R$style"; //$NON-NLS-1$
-            name = getResourceFieldName(value.substring(PREFIX_ANDROID.length()));
-            prefix = null;
-        } else {
-            return;
-        }
-
-        if (owner == null) {
-            // Convert @android:type/foo into android/R$type and "foo"
-            int index = value.indexOf('/', prefix.length());
-            if (index != -1) {
-                owner = "android/R$"    //$NON-NLS-1$
-                        + value.substring(prefix.length(), index);
-                name = getResourceFieldName(value.substring(index + 1));
-            } else if (value.startsWith(ANDROID_THEME_PREFIX)) {
-                owner = "android/R$attr";  //$NON-NLS-1$
-                name = value.substring(ANDROID_THEME_PREFIX.length());
-            } else {
-                return;
-            }
-        }
-        int api = mApiDatabase.getFieldVersion(owner, name);
-        int minSdk = getMinSdk(context);
-        if (api > minSdk && api > context.getFolderVersion()
-            && api > getLocalMinSdk(attribute.getOwnerElement())) {
-            // Don't complain about resource references in the tools namespace,
-            // such as for example "tools:layout="@android:layout/list_content",
-            // used only for designtime previews
-            if (TOOLS_URI.equals(attribute.getNamespaceURI())) {
-                return;
-            }
-
-            //noinspection StatementWithEmptyBody
-            if (attributeApiLevel >= api) {
-                // The attribute will only be *read* on platforms >= attributeApiLevel.
-                // If this isn't lower than the attribute reference's API level, it
-                // won't be a problem
-            } else if (attributeApiLevel > minSdk) {
-                String attributeName = attribute.getLocalName();
-                Location location = context.getLocation(attribute);
-                String message = String.format(
-                        "`%1$s` requires API level %2$d (current min is %3$d), but note "
-                        + "that attribute `%4$s` is only used in API level %5$d "
-                        + "and higher",
-                        name, api, minSdk, attributeName, attributeApiLevel);
-                context.report(UNSUPPORTED, attribute, location, message);
-            } else {
-                Location location = context.getLocation(attribute);
-                String message = String.format(
-                        "`%1$s` requires API level %2$d (current min is %3$d)",
-                        value, api, minSdk);
-                context.report(UNSUPPORTED, attribute, location, message);
-            }
-        }
-    }
-
-    /**
-     * Returns true if the view tag is possibly a text view. It may not be certain,
-     * but will err on the side of caution (for example, any custom view is considered
-     * to be a potential text view.)
-     */
-    private static boolean viewMayExtendTextView(@NonNull Element element) {
-        String tag = element.getTagName();
-        if (tag.equals(VIEW_TAG)) {
-            tag = element.getAttribute(ATTR_CLASS);
-            if (tag == null || tag.isEmpty()) {
-                return false;
-            }
-        }
-
-        //noinspection SimplifiableIfStatement
-        if (tag.indexOf('.') != -1) {
-            // Custom views: not sure. Err on the side of caution.
-            return true;
-
-        }
-
-        return tag.contains("Text")  // TextView, EditText, etc
-               || tag.contains(BUTTON)  // Button, ToggleButton, etc
-               || tag.equals("DigitalClock")
-               || tag.equals("Chronometer")
-               || tag.equals(CHECK_BOX)
-               || tag.equals(SWITCH);
-    }
-
-    /**
-     * Returns true if this attribute is in a drawable document with one of the
-     * root tags that require API 21
-     */
-    private static boolean isAlreadyWarnedDrawableFile(@NonNull XmlContext context,
-            @NonNull Attr attribute, int attributeApiLevel) {
-        // Don't complain if it's in a drawable file where we've already
-        // flagged the root drawable type as being unsupported
-        if (context.getResourceFolderType() == ResourceFolderType.DRAWABLE
-            && attributeApiLevel == 21) {
-            String root = attribute.getOwnerDocument().getDocumentElement().getTagName();
-            if (TAG_RIPPLE.equals(root)
-                || TAG_VECTOR.equals(root)
-                || TAG_ANIMATED_VECTOR.equals(root)
-                || TAG_ANIMATED_SELECTOR.equals(root)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Is the given attribute a "benign" unused attribute, one we probably don't need to
-     * flag to the user as not applicable on all versions? These are typically attributes
-     * which add some nice platform behavior when available, but that are not critical
-     * and developers would not typically need to be aware of to try to implement workarounds
-     * on older platforms.
-     */
-    private static boolean isBenignUnusedAttribute(@NonNull String name) {
-        return ATTR_LABEL_FOR.equals(name)
-               || ATTR_TEXT_IS_SELECTABLE.equals(name)
-               || "textAlignment".equals(name)
-               || ATTR_FULL_BACKUP_CONTENT.equals(name);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        if (mApiDatabase == null) {
-            return;
-        }
-
-        String tag = element.getTagName();
-
-        ResourceFolderType folderType = context.getResourceFolderType();
-        if (folderType != ResourceFolderType.LAYOUT) {
-            if (folderType == ResourceFolderType.DRAWABLE) {
-                checkElement(context, element, TAG_VECTOR, 21, "1.4", UNSUPPORTED);
-                checkElement(context, element, TAG_RIPPLE, 21, null, UNSUPPORTED);
-                checkElement(context, element, TAG_ANIMATED_SELECTOR, 21, null, UNSUPPORTED);
-                checkElement(context, element, TAG_ANIMATED_VECTOR, 21, null, UNSUPPORTED);
-                checkElement(context, element, "drawable", 24, null, UNSUPPORTED);
-                if ("layer-list".equals(tag)) {
-                    checkLevelList(context, element);
-                } else if (tag.contains(".")) {
-                    checkElement(context, element, tag, 24, null, UNSUPPORTED);
-                }
-            }
-            if (element.getParentNode().getNodeType() != Node.ELEMENT_NODE) {
-                // Root node
-                return;
-            }
-            NodeList childNodes = element.getChildNodes();
-            for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-                Node textNode = childNodes.item(i);
-                if (textNode.getNodeType() == Node.TEXT_NODE) {
-                    String text = textNode.getNodeValue();
-                    if (text.contains(ANDROID_PREFIX)) {
-                        text = text.trim();
-                        // Convert @android:type/foo into android/R$type and "foo"
-                        int index = text.indexOf('/', ANDROID_PREFIX.length());
-                        if (index != -1) {
-                            String typeString = text.substring(ANDROID_PREFIX.length(), index);
-                            if (ResourceType.getEnum(typeString) != null) {
-                                String owner = "android/R$" + typeString;
-                                String name = getResourceFieldName(text.substring(index + 1));
-                                int api = mApiDatabase.getFieldVersion(owner, name);
-                                int minSdk = getMinSdk(context);
-                                if (api > minSdk && api > context.getFolderVersion()
-                                    && api > getLocalMinSdk(element)) {
-                                    Location location = context.getLocation(textNode);
-                                    String message = String.format(
-                                            "`%1$s` requires API level %2$d (current min is %3$d)",
-                                            text, api, minSdk);
-                                    context.report(UNSUPPORTED, element, location, message);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        } else {
-            if (VIEW_TAG.equals(tag)) {
-                tag = element.getAttribute(ATTR_CLASS);
-                if (tag == null || tag.isEmpty()) {
-                    return;
-                }
-            } else {
-                // TODO: Complain if <tag> is used at the root level!
-                checkElement(context, element, TAG, 21, null, UNUSED);
-            }
-
-            // Check widgets to make sure they're available in this version of the SDK.
-            if (tag.indexOf('.') != -1) {
-                // Custom views aren't in the index
-                return;
-            }
-            String fqn = "android/widget/" + tag;    //$NON-NLS-1$
-            if (tag.equals("TextureView")) {         //$NON-NLS-1$
-                fqn = "android/view/TextureView";    //$NON-NLS-1$
-            }
-            // TODO: Consider other widgets outside of android.widget.*
-            int api = mApiDatabase.getClassVersion(fqn);
-            int minSdk = getMinSdk(context);
-            if (api > minSdk && api > context.getFolderVersion()
-                && api > getLocalMinSdk(element)) {
-                Location location = context.getLocation(element);
-                String message = String.format(
-                        "View requires API level %1$d (current min is %2$d): `<%3$s>`",
-                        api, minSdk, tag);
-                context.report(UNSUPPORTED, element, location, message);
-            }
-        }
-    }
-
-    /** Checks whether the given element is the given tag, and if so, whether it satisfied
-     * the minimum version that the given tag is supported in */
-    private void checkLevelList(@NonNull XmlContext context, @NonNull Element element) {
-        Node curr = element.getFirstChild();
-        while (curr != null) {
-            if (curr.getNodeType() == Node.ELEMENT_NODE
-                && TAG_ITEM.equals(curr.getNodeName())) {
-                Element e = (Element) curr;
-                if (e.hasAttributeNS(ANDROID_URI, ATTR_WIDTH)
-                    || e.hasAttributeNS(ANDROID_URI, ATTR_HEIGHT)) {
-                    int attributeApiLevel = 23; // Using width and height on layer-list children requires M
-                    int minSdk = getMinSdk(context);
-                    if (attributeApiLevel > minSdk
-                        && attributeApiLevel > context.getFolderVersion()
-                        && attributeApiLevel > getLocalMinSdk(element)) {
-                        for (String attributeName : new String[] { ATTR_WIDTH, ATTR_HEIGHT}) {
-                            Attr attribute = e.getAttributeNodeNS(ANDROID_URI, attributeName);
-                            if (attribute == null) {
-                                continue;
-                            }
-                            Location location = context.getLocation(attribute);
-                            String message = String.format(
-                                    "Attribute `%1$s` is only used in API level %2$d and higher "
-                                    + "(current min is %3$d)",
-                                    attribute.getLocalName(), attributeApiLevel, minSdk);
-                            context.report(UNUSED, attribute, location, message);
-                        }
-                    }
-                }
-            }
-            curr = curr.getNextSibling();
-        }
-    }
-
-    /** Checks whether the given element is the given tag, and if so, whether it satisfied
-     * the minimum version that the given tag is supported in */
-    private void checkElement(@NonNull XmlContext context, @NonNull Element element,
-            @NonNull String tag, int api, @Nullable String gradleVersion, @NonNull Issue issue) {
-        if (tag.equals(element.getTagName())) {
-            int minSdk = getMinSdk(context);
-            if (api > minSdk
-                && api > context.getFolderVersion()
-                && api > getLocalMinSdk(element)
-                && !featureProvidedByGradle(context, gradleVersion)) {
-                Location location = context.getLocation(element);
-
-                // For the <drawable> tag we report it against the class= attribute
-                if ("drawable".equals(tag)) {
-                    Attr attribute = element.getAttributeNode(ATTR_CLASS);
-                    if (attribute == null) {
-                        return;
-                    }
-                    location = context.getLocation(attribute);
-                    tag = ATTR_CLASS;
-                }
-
-                String message;
-                if (issue == UNSUPPORTED) {
-                    message = String.format(
-                            "`<%1$s>` requires API level %2$d (current min is %3$d)", tag, api,
-                            minSdk);
-                    if (gradleVersion != null) {
-                        message += String.format(
-                                " or building with Android Gradle plugin %1$s or higher",
-                                gradleVersion);
-                    } else if (tag.contains(".")) {
-                        message = String.format(
-                                "Custom drawables requires API level %1$d (current min is %2$d)",
-                                api, minSdk);
-                    }
-                } else {
-                    assert issue == UNUSED : issue;
-                    message = String.format(
-                            "`<%1$s>` is only used in API level %2$d and higher "
-                            + "(current min is %3$d)", tag, api, minSdk);
-                }
-                context.report(issue, element, location, message);
-            }
-        }
-    }
-
-    protected int getMinSdk(Context context) {
-        if (mMinApi == -1) {
-            AndroidVersion minSdkVersion = context.getMainProject().getMinSdkVersion();
-            mMinApi = minSdkVersion.getFeatureLevel();
-        }
-
-        return mMinApi;
-    }
-
-    /**
-     * Returns the minimum SDK to use in the given element context, or -1 if no
-     * {@code tools:targetApi} attribute was found.
-     *
-     * @param element the element to look at, including parents
-     * @return the API level to use for this element, or -1
-     */
-    private static int getLocalMinSdk(@NonNull Element element) {
-        //noinspection ConstantConditions
-        while (element != null) {
-            String targetApi = element.getAttributeNS(TOOLS_URI, ATTR_TARGET_API);
-            if (targetApi != null && !targetApi.isEmpty()) {
-                if (Character.isDigit(targetApi.charAt(0))) {
-                    try {
-                        return Integer.parseInt(targetApi);
-                    } catch (NumberFormatException e) {
-                        break;
-                    }
-                } else {
-                    return SdkVersionInfo.getApiByBuildCode(targetApi, true);
-                }
-            }
-
-            Node parent = element.getParentNode();
-            if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
-                element = (Element) parent;
-            } else {
-                break;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Checks if the current project supports features added in {@code minGradleVersion} version of
-     * the Android gradle plugin.
-     *
-     * @param context                Current context.
-     * @param minGradleVersionString Version in which support for a given feature was added, or null
-     *                               if it's not supported at build time.
-     */
-    private static boolean featureProvidedByGradle(@NonNull XmlContext context,
-            @Nullable String minGradleVersionString) {
-        if (minGradleVersionString == null) {
-            return false;
-        }
-
-        GradleVersion gradleModelVersion = context.getProject().getGradleModelVersion();
-        if (gradleModelVersion != null) {
-            GradleVersion minVersion = GradleVersion.tryParse(minGradleVersionString);
-            if (minVersion != null
-                && gradleModelVersion.compareIgnoringQualifiers(minVersion) >= 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        if (mApiDatabase == null) {
-            return new AbstractUastVisitor() {
-                @Override
-                public boolean visitElement(@NotNull UElement element) {
-                    // No-op. Workaround for super currently calling
-                    //   ProgressIndicatorProvider.checkCanceled();
-                    return super.visitElement(element);
-                }
-            };
-        }
-        return new ApiVisitor(context);
-    }
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        List<Class<? extends UElement>> types = new ArrayList<Class<? extends UElement>>(9);
-        types.add(UImportStatement.class);
-        types.add(USimpleNameReferenceExpression.class);
-        types.add(UVariable.class);
-        types.add(UTryExpression.class);
-        types.add(UBinaryExpressionWithType.class);
-        types.add(UBinaryExpression.class);
-        types.add(UCallExpression.class);
-        types.add(UClass.class);
-        types.add(UTypeReferenceExpression.class);
-        types.add(UClassLiteralExpression.class);
-        types.add(UMethod.class);
-        return types;
-    }
-
-    /**
-     * Checks whether the given instruction is a benign usage of a constant defined in
-     * a later version of Android than the application's {@code minSdkVersion}.
-     *
-     * @param node  the instruction to check
-     * @param name  the name of the constant
-     * @param owner the field owner
-     * @return true if the given usage is safe on older versions than the introduction
-     *              level of the constant
-     */
-    private static boolean isBenignConstantUsage(
-            @Nullable UElement node,
-            @NonNull String name,
-            @NonNull String owner
-    ) {
-        if (owner.equals("android/os/Build$VERSION_CODES")) {     //$NON-NLS-1$
-            // These constants are required for compilation, not execution
-            // and valid code checks it even on older platforms
-            return true;
-        }
-        if (owner.equals("android/view/ViewGroup$LayoutParams")   //$NON-NLS-1$
-            && name.equals("MATCH_PARENT")) {                 //$NON-NLS-1$
-            return true;
-        }
-        if (owner.equals("android/widget/AbsListView")            //$NON-NLS-1$
-            && ((name.equals("CHOICE_MODE_NONE")              //$NON-NLS-1$
-                 || name.equals("CHOICE_MODE_MULTIPLE")            //$NON-NLS-1$
-                 || name.equals("CHOICE_MODE_SINGLE")))) {         //$NON-NLS-1$
-            // android.widget.ListView#CHOICE_MODE_MULTIPLE and friends have API=1,
-            // but in API 11 it was moved up to the parent class AbsListView.
-            // Referencing AbsListView#CHOICE_MODE_MULTIPLE technically requires API 11,
-            // but the constant is the same as the older version, so accept this without
-            // warning.
-            return true;
-        }
-
-        // Gravity#START and Gravity#END are okay; these were specifically written to
-        // be backwards compatible (by using the same lower bits for START as LEFT and
-        // for END as RIGHT)
-        if ("android/view/Gravity".equals(owner)                   //$NON-NLS-1$
-            && ("START".equals(name) || "END".equals(name))) { //$NON-NLS-1$ //$NON-NLS-2$
-            return true;
-        }
-
-        if (node == null) {
-            return false;
-        }
-
-        // It's okay to reference the constant as a case constant (since that
-        // code path won't be taken) or in a condition of an if statement
-        UElement curr = node.getUastParent();
-        while (curr != null) {
-            if (curr instanceof USwitchClauseExpression) {
-                List<UExpression> caseValues = ((USwitchClauseExpression) curr).getCaseValues();
-                if (caseValues != null) {
-                    for (UExpression condition : caseValues) {
-                        if (condition != null && UastUtils.isChildOf(node, condition, false)) {
-                            return true;
-                        }
-                    }
-                }
-                return false;
-            } else if (curr instanceof UIfExpression) {
-                UExpression condition = ((UIfExpression) curr).getCondition();
-                return UastUtils.isChildOf(node, condition, false);
-            } else if (curr instanceof UMethod || curr instanceof UClass) {
-                break;
-            }
-            curr = curr.getUastParent();
-        }
-
-        return false;
-    }
-
-    public static int getRequiredVersion(String errorMessage) {
-        Pattern pattern = Pattern.compile("\\s(\\d+)\\s");
-        Matcher matcher = pattern.matcher(errorMessage);
-        if (matcher.find()) {
-            return Integer.parseInt(matcher.group(1));
-        }
-
-        return -1;
-    }
-
-    private final class ApiVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private ApiVisitor(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitTypeReferenceExpression(@NotNull UTypeReferenceExpression node) {
-            checkType(node.getType(), node);
-            return super.visitTypeReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitClassLiteralExpression(@NotNull UClassLiteralExpression node) {
-            checkType(node.getType(), node);
-            return super.visitClassLiteralExpression(node);
-        }
-
-        @Override
-        public boolean visitImportStatement(@NotNull UImportStatement statement) {
-            if (!statement.isOnDemand()) {
-                PsiElement resolved = statement.resolve();
-                if (resolved instanceof PsiField) {
-                    checkField(statement, (PsiField)resolved);
-                }
-            }
-
-            return super.visitImportStatement(statement);
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(@NotNull USimpleNameReferenceExpression node) {
-            PsiElement resolved = node.resolve();
-            if (resolved instanceof PsiField) {
-                checkField(node, (PsiField)resolved);
-            }
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitBinaryExpressionWithType(@NotNull UBinaryExpressionWithType node) {
-            visitTypeCastExpression(node);
-            return super.visitBinaryExpressionWithType(node);
-        }
-
-        private void visitTypeCastExpression(UBinaryExpressionWithType expression) {
-            UExpression operand = expression.getOperand();
-
-            PsiType operandType = operand.getExpressionType();
-            PsiType castType = expression.getType();
-
-            if (castType.equals(operandType)) {
-                return;
-            }
-            if (!(operandType instanceof PsiClassType)) {
-                return;
-            }
-            if (!(castType instanceof PsiClassType)) {
-                return;
-            }
-            PsiClassType classType = (PsiClassType)operandType;
-            PsiClassType interfaceType = (PsiClassType)castType;
-            checkCast(expression, classType, interfaceType);
-        }
-
-        private void checkCast(@NonNull UElement node, @NonNull PsiClassType classType,
-                @NonNull PsiClassType interfaceType) {
-            if (classType.equals(interfaceType)) {
-                return;
-            }
-            JavaEvaluator evaluator = mContext.getEvaluator();
-            String classTypeInternal = evaluator.getInternalName(classType);
-            String interfaceTypeInternal = evaluator.getInternalName(interfaceType);
-            if ("java/lang/Object".equals(interfaceTypeInternal)) {
-                return;
-            }
-
-            int api = mApiDatabase.getValidCastVersion(classTypeInternal, interfaceTypeInternal);
-            if (api == -1) {
-                return;
-            }
-
-            int minSdk = getMinSdk(mContext);
-            if (api <= minSdk) {
-                return;
-            }
-
-            if (isSuppressed(api, node, minSdk, mContext, UNSUPPORTED)) {
-                return;
-            }
-
-            Location location = mContext.getUastLocation(node);
-            String message = String.format("Cast from %1$s to %2$s requires API level %3$d (current min is %4$d)",
-                                           UastLintUtils.getClassName(classType),
-                                           UastLintUtils.getClassName(interfaceType), api, minSdk);
-            mContext.report(UNSUPPORTED, location, message);
-        }
-
-        @Override
-        public boolean visitMethod(@NotNull UMethod method) {
-            // API check for default methods
-            if (method.getModifierList().hasExplicitModifier(PsiModifier.DEFAULT)) {
-                int api = 24; // minSdk for default methods
-                int minSdk = getMinSdk(mContext);
-
-                if (!isSuppressed(api, method, minSdk, mContext, UNSUPPORTED)) {
-                    Location location = mContext.getLocation(method);
-                    String message = String.format("Default method requires API level %1$d "
-                                                   + "(current min is %2$d)", api, minSdk);
-                    mContext.reportUast(UNSUPPORTED, method, location, message);
-                }
-            }
-
-            return super.visitMethod(method);
-        }
-
-        @Override
-        public boolean visitClass(@NotNull UClass aClass) {
-            // Check for repeatable annotations
-            if (aClass.isAnnotationType()) {
-                PsiModifierList modifierList = aClass.getModifierList();
-                if (modifierList != null) {
-                    for (PsiAnnotation annotation : modifierList.getAnnotations()) {
-                        String name = annotation.getQualifiedName();
-                        if ("java.lang.annotation.Repeatable".equals(name)) {
-                            int api = 24; // minSdk for repeatable annotations
-                            int minSdk = getMinSdk(mContext);
-                            if (!isSuppressed(api, aClass, minSdk, mContext, UNSUPPORTED)) {
-                                Location location = mContext.getLocation(annotation);
-                                String message = String.format("Repeatable annotation requires "
-                                                               + "API level %1$d (current min is %2$d)", api, minSdk);
-                                mContext.report(UNSUPPORTED, annotation, location, message);
-                            }
-                        } else if ("java.lang.annotation.Target".equals(name)) {
-                            PsiNameValuePair[] attributes = annotation.getParameterList()
-                                    .getAttributes();
-                            for (PsiNameValuePair pair : attributes) {
-                                PsiAnnotationMemberValue value = pair.getValue();
-                                if (value instanceof PsiArrayInitializerMemberValue) {
-                                    PsiArrayInitializerMemberValue array
-                                            = (PsiArrayInitializerMemberValue) value;
-                                    for (PsiAnnotationMemberValue t : array.getInitializers()) {
-                                        checkAnnotationTarget(t, modifierList);
-                                    }
-                                } else if (value != null) {
-                                    checkAnnotationTarget(value, modifierList);
-                                }
-                            }
-                        }
-                    }
-                }
-            } else {
-                for (UTypeReferenceExpression t : aClass.getUastSuperTypes()) {
-                    checkType(t.getType(), t);
-                }
-            }
-
-            return super.visitClass(aClass);
-        }
-
-        private void checkAnnotationTarget(@NonNull PsiAnnotationMemberValue element,
-                PsiModifierList modifierList) {
-            if (element instanceof UReferenceExpression) {
-                UReferenceExpression ref = (UReferenceExpression) element;
-                String referenceName = UastLintUtils.getReferenceName(ref);
-                if ("TYPE_PARAMETER".equals(referenceName)
-                    || "TYPE_USE".equals(referenceName)) {
-                    PsiAnnotation retention = modifierList
-                            .findAnnotation("java.lang.annotation.Retention");
-                    if (retention == null ||
-                        retention.getText().contains("RUNTIME")) {
-                        Location location = mContext.getLocation(element);
-                        String message = String.format("Type annotations are not "
-                                                       + "supported in Android: %1$s", referenceName);
-                        mContext.report(UNSUPPORTED, element, location, message);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public boolean visitCallExpression(@NotNull UCallExpression expression) {
-            checkMethodCallExpression(expression);
-            return super.visitCallExpression(expression);
-        }
-
-        private void checkMethodCallExpression(@NotNull UCallExpression expression) {
-            PsiMethod method = expression.resolve();
-            if (method != null) {
-                PsiClass containingClass = method.getContainingClass();
-                if (containingClass == null) {
-                    return;
-                }
-
-                PsiParameterList parameterList = method.getParameterList();
-                if (parameterList.getParametersCount() > 0) {
-                    PsiParameter[] parameters = parameterList.getParameters();
-
-                    List<UExpression> arguments = expression.getValueArguments();
-                    for (int i = 0; i < parameters.length; i++) {
-                        PsiType parameterType = parameters[i].getType();
-                        if (parameterType instanceof PsiClassType) {
-                            if (i >= arguments.size()) {
-                                // We can end up with more arguments than parameters when
-                                // there is a varargs call.
-                                break;
-                            }
-                            UExpression argument = arguments.get(i);
-                            PsiType argumentType = argument.getExpressionType();
-                            if (argumentType == null || parameterType.equals(argumentType) || !(argumentType instanceof PsiClassType)) {
-                                continue;
-                            }
-                            checkCast(argument, (PsiClassType)argumentType, (PsiClassType)parameterType);
-                        }
-                    }
-                }
-
-                JavaEvaluator evaluator = mContext.getEvaluator();
-                String fqcn = containingClass.getQualifiedName();
-                String owner = evaluator.getInternalName(containingClass);
-                if (owner == null) {
-                    return; // Couldn't resolve type
-                }
-
-                String name = IntellijLintUtils.getInternalMethodName(method);
-                String desc = IntellijLintUtils.getInternalDescription(method, false, false);
-                if (desc == null) {
-                    // Couldn't compute description of method for some reason; probably
-                    // failure to resolve parameter types
-                    return;
-                }
-
-                boolean hasApiAnnotation = false;
-                int api = mApiDatabase.getCallVersion(owner, name, desc);
-                if (api == -1) {
-                    api = getTargetApi(method.getModifierList());
-                    if (api == -1 && method.isConstructor()) {
-                        api = getTargetApi(method.getContainingClass().getModifierList());
-                    }
-
-                    if (api == -1) {
-                        return;
-                    } else {
-                        hasApiAnnotation = true;
-                    }
-                }
-
-                int minSdk = getMinSdk(mContext);
-                if (api <= minSdk) {
-                    return;
-                }
-
-                // The lint API database contains two optimizations:
-                // First, all members that were available in API 1 are omitted from the database, since that saves
-                // about half of the size of the database, and for API check purposes, we don't need to distinguish
-                // between "doesn't exist" and "available in all versions".
-                // Second, all inherited members were inlined into each class, so that it doesn't have to do a
-                // repeated search up the inheritance chain.
-                //
-                // Unfortunately, in this custom PSI detector, we look up the real resolved method, which can sometimes
-                // have a different minimum API.
-                //
-                // For example, SQLiteDatabase had a close() method from API 1. Therefore, calling SQLiteDatabase is supported
-                // in all versions. However, it extends SQLiteClosable, which in API 16 added "implements Closable". In
-                // this detector, if we have the following code:
-                //     void test(SQLiteDatabase db) { db.close }
-                // here the call expression will be the close method on type SQLiteClosable. And that will result in an API
-                // requirement of API 16, since the close method it now resolves to is in API 16.
-                //
-                // To work around this, we can now look up the type of the call expression ("db" in the above, but it could
-                // have been more complicated), and if that's a different type than the type of the method, we look up
-                // *that* method from lint's database instead. Furthermore, it's possible for that method to return "-1"
-                // and we can't tell if that means "doesn't exist" or "present in API 1", we then check the package prefix
-                // to see whether we know it's an API method whose members should all have been inlined.
-                if (!hasApiAnnotation && UastExpressionUtils.isMethodCall(expression)) {
-                    UExpression qualifier = expression.getReceiver();
-                    if (qualifier != null && !(qualifier instanceof UThisExpression) && !(qualifier instanceof USuperExpression)) {
-                        PsiType type = qualifier.getExpressionType();
-                        if (type != null && type instanceof PsiClassType) {
-                            String expressionOwner = evaluator.getInternalName((PsiClassType)type);
-                            if (expressionOwner != null && !expressionOwner.equals(owner)) {
-                                int specificApi = mApiDatabase.getCallVersion(expressionOwner, name, desc);
-                                if (specificApi == -1) {
-                                    if (ApiLookup.isRelevantOwner(expressionOwner)) {
-                                        return;
-                                    }
-                                } else if (specificApi <= minSdk) {
-                                    return;
-                                } else {
-                                    // For example, for Bundle#getString(String,String) the API level is 12, whereas for
-                                    // BaseBundle#getString(String,String) the API level is 21. If the code specified a Bundle instead of
-                                    // a BaseBundle, reported the Bundle level in the error message instead.
-                                    if (specificApi < api) {
-                                        api = specificApi;
-                                        fqcn = expressionOwner.replace('/', '.');
-                                    }
-                                    api = Math.min(specificApi, api);
-                                }
-                            }
-                        }
-                    } else {
-                        // Unqualified call; need to search in our super hierarchy
-                        PsiClass cls = null;
-                        PsiType receiverType = expression.getReceiverType();
-                        if (receiverType instanceof PsiClassType) {
-                            cls = ((PsiClassType) receiverType).resolve();
-                        }
-
-                        while (cls != null) {
-                            if (cls instanceof PsiAnonymousClass) {
-                                // If it's an unqualified call in an anonymous class, we need to rely on the
-                                // resolve method to find out whether the method is picked up from the anonymous
-                                // class chain or any outer classes
-                                boolean found = false;
-                                PsiClassType anonymousBaseType = ((PsiAnonymousClass)cls).getBaseClassType();
-                                PsiClass anonymousBase = anonymousBaseType.resolve();
-                                if (anonymousBase != null && anonymousBase.isInheritor(containingClass, true)) {
-                                    cls = anonymousBase;
-                                    found = true;
-                                } else {
-                                    PsiClass surroundingBaseType = PsiTreeUtil.getParentOfType(cls, PsiClass.class, true);
-                                    if (surroundingBaseType != null && surroundingBaseType.isInheritor(containingClass, true)) {
-                                        cls = surroundingBaseType;
-                                        found = true;
-                                    }
-                                }
-                                if (!found) {
-                                    break;
-                                }
-                            }
-                            String expressionOwner = evaluator.getInternalName(cls);
-                            if (expressionOwner == null) {
-                                break;
-                            }
-                            int specificApi = mApiDatabase.getCallVersion(expressionOwner, name, desc);
-                            if (specificApi == -1) {
-                                if (ApiLookup.isRelevantOwner(expressionOwner)) {
-                                    return;
-                                }
-                            } else if (specificApi <= minSdk) {
-                                return;
-                            } else {
-                                if (specificApi < api) {
-                                    api = specificApi;
-                                    fqcn = expressionOwner.replace('/', '.');
-                                }
-                                api = Math.min(specificApi, api);
-                                break;
-                            }
-                            cls = cls.getSuperClass();
-                        }
-                    }
-                }
-
-                if (isSuppressed(api, expression, minSdk, mContext, UNSUPPORTED)) {
-                    return;
-                }
-
-                // If you're simply calling super.X from method X, even if method X is in a higher API level than the minSdk, we're
-                // generally safe; that method should only be called by the framework on the right API levels. (There is a danger of
-                // somebody calling that method locally in other contexts, but this is hopefully unlikely.)
-                if (UastExpressionUtils.isMethodCall(expression)) {
-                    if (expression.getReceiver() instanceof USuperExpression) {
-                        PsiMethod containingMethod = UastUtils.getContainingMethod(expression);
-                        if (containingMethod != null && name.equals(containingMethod.getName())
-                            && MethodSignatureUtil.areSignaturesEqual(method, containingMethod)
-                            // We specifically exclude constructors from this check, because we do want to flag constructors requiring the
-                            // new API level; it's highly likely that the constructor is called by local code so you should specifically
-                            // investigate this as a developer
-                            && !method.isConstructor()) {
-                            return;
-                        }
-                    }
-                }
-
-                UElement locationNode = expression.getMethodIdentifier();
-                if (locationNode == null) {
-                    locationNode = expression;
-                }
-                Location location = mContext.getUastLocation(locationNode);
-                String message = String.format("Call requires API level %1$d (current min is %2$d): %3$s", api, minSdk,
-                                               fqcn + '#' + method.getName());
-
-                mContext.report(UNSUPPORTED, location, message);
-            }
-        }
-
-        @Override
-        public boolean visitLocalVariable(ULocalVariable variable) {
-            UExpression initializer = variable.getUastInitializer();
-            if (initializer == null) {
-                return true;
-            }
-
-            PsiType initializerType = initializer.getExpressionType();
-            if (!(initializerType instanceof PsiClassType)) {
-                return true;
-            }
-
-            PsiType interfaceType = variable.getType();
-            if (initializerType.equals(interfaceType)) {
-                return true;
-            }
-
-            if (!(interfaceType instanceof PsiClassType)) {
-                return true;
-            }
-
-            checkCast(initializer, (PsiClassType)initializerType, (PsiClassType)interfaceType);
-            return true;
-        }
-
-        @Override
-        public boolean visitBinaryExpression(@NotNull UBinaryExpression node) {
-            if (UastExpressionUtils.isAssignment(node)) {
-                visitAssignmentExpression(node);
-            }
-
-            return super.visitBinaryExpression(node);
-        }
-
-        private void visitAssignmentExpression(UBinaryExpression expression) {
-            UExpression rExpression = expression.getRightOperand();
-            PsiType rhsType = rExpression.getExpressionType();
-            if (!(rhsType instanceof PsiClassType)) {
-                return;
-            }
-
-            PsiType interfaceType = expression.getLeftOperand().getExpressionType();
-            if (rhsType.equals(interfaceType)) {
-                return;
-            }
-
-            if (!(interfaceType instanceof PsiClassType)) {
-                return;
-            }
-
-            checkCast(rExpression, (PsiClassType)rhsType, (PsiClassType)interfaceType);
-        }
-
-        @Override
-        public boolean visitTryExpression(@NotNull UTryExpression statement) {
-            if (statement.getHasResources()) {
-                int api = 19; // minSdk for try with resources
-                int minSdk = getMinSdk(mContext);
-
-                if (api > minSdk && api > getTargetApi(statement)) {
-                    Location location = mContext.getUastLocation(statement);
-                    String message = String.format("Try-with-resources requires "
-                                                   + "API level %1$d (current min is %2$d)", api, minSdk);
-                    LintDriver driver = mContext.getDriver();
-                    if (!driver.isSuppressed(mContext, UNSUPPORTED, statement)) {
-                        mContext.report(UNSUPPORTED, statement, location, message);
-                    }
-                }
-            }
-
-            for (UCatchClause catchClause : statement.getCatchClauses()) {
-
-                // Special case reflective operation exception which can be implicitly used
-                // with multi-catches: see issue 153406
-                int minSdk = getMinSdk(mContext);
-                if(minSdk < 19 && isMultiCatchReflectiveOperationException(catchClause)) {
-                    String message = String.format("Multi-catch with these reflection exceptions requires API level 19 (current min is %d) " +
-                                                   "because they get compiled to the common but new super type `ReflectiveOperationException`. " +
-                                                   "As a workaround either create individual catch statements, or catch `Exception`.",
-                                                   minSdk);
-
-                    mContext.report(UNSUPPORTED, getCatchParametersLocation(mContext, catchClause), message);
-                    continue;
-                }
-
-                for (UTypeReferenceExpression typeReference : catchClause.getTypeReferences()) {
-                    checkCatchTypeElement(statement, typeReference, typeReference.getType());
-                }
-            }
-
-            return super.visitTryExpression(statement);
-        }
-
-        private void checkCatchTypeElement(@NonNull UTryExpression statement,
-                @NonNull UTypeReferenceExpression typeReference,
-                @Nullable PsiType type) {
-            PsiClass resolved = null;
-            if (type instanceof PsiClassType) {
-                resolved = ((PsiClassType) type).resolve();
-            }
-            if (resolved != null) {
-                String signature = mContext.getEvaluator().getInternalName(resolved);
-                int api = mApiDatabase.getClassVersion(signature);
-                if (api == -1) {
-                    return;
-                }
-                int minSdk = getMinSdk(mContext);
-                if (api <= minSdk) {
-                    return;
-                }
-                int target = getTargetApi(statement);
-                if (target != -1 && api <= target) {
-                    return;
-                }
-
-                Location location = mContext.getUastLocation(typeReference);
-                String fqcn = resolved.getQualifiedName();
-                String message = String.format("Class requires API level %1$d (current min is %2$d): %3$s",
-                                               api, minSdk, fqcn);
-                mContext.report(UNSUPPORTED, location, message);
-            }
-        }
-
-        private void checkType(PsiType type, UElement element) {
-            if (!(type instanceof PsiClassType)) {
-                return;
-            }
-
-            PsiClass resolved = ((PsiClassType) type).resolve();
-            if (resolved == null) {
-                return;
-            }
-
-            String signature = mContext.getEvaluator().getInternalName(resolved);
-            int api = mApiDatabase.getClassVersion(signature);
-            if (api == -1) {
-                return;
-            }
-
-            int minSdk = getMinSdk(mContext);
-            if (api <= minSdk) {
-                return;
-            }
-
-            if (isSuppressed(api, element, minSdk, mContext, UNSUPPORTED)) {
-                return;
-            }
-
-            Location location = mContext.getUastLocation(element);
-            String fqcn = resolved.getQualifiedName();
-            String message = String.format("Class requires API level %1$d (current min is %2$d): %3$s",
-                                           api, minSdk, fqcn);
-            mContext.report(UNSUPPORTED, location, message);
-        }
-
-        /**
-         * Checks a Java source field reference. Returns true if the field is known
-         * regardless of whether it's an invalid field or not
-         */
-        private boolean checkField(@NonNull UElement node, @NonNull PsiField field) {
-            PsiType type = field.getType();
-            Issue issue;
-            if ((type instanceof PsiPrimitiveType) || LintUtils.isString(type)) {
-                issue = INLINED;
-            } else {
-                issue = UNSUPPORTED;
-            }
-
-            String name = field.getName();
-            PsiClass containingClass = field.getContainingClass();
-            if (containingClass == null || name == null) {
-                return false;
-            }
-            String owner = mContext.getEvaluator().getInternalName(containingClass);
-            int api = mApiDatabase.getFieldVersion(owner, name);
-            if (api != -1) {
-                int minSdk = getMinSdk(mContext);
-                if (api > minSdk
-                    && api > getTargetApi(node)) {
-                    if (isBenignConstantUsage(node, name, owner)) {
-                        return true;
-                    }
-
-                    String fqcn = getFqcn(owner) + '#' + name;
-
-                    // For import statements, place the underlines only under the
-                    // reference, not the import and static keywords
-                    if (node instanceof UImportStatement) {
-                        UElement reference = ((UImportStatement) node).getImportReference();
-                        if (reference != null) {
-                            node = reference;
-                        }
-                    }
-
-                    LintDriver driver = mContext.getDriver();
-                    if (driver.isSuppressed(mContext, INLINED, node)) {
-                        return true;
-                    }
-
-                    // backwards compatibility: lint used to use this issue type so respect
-                    // older suppress annotations
-                    if (driver.isSuppressed(mContext, UNSUPPORTED, node)) {
-                        return true;
-                    }
-                    if (isWithinVersionCheckConditional(node, api, mContext)) {
-                        return true;
-                    }
-                    if (isPrecededByVersionCheckExit(node, api, mContext)) {
-                        return true;
-                    }
-
-                    String message = String.format(
-                            "Field requires API level %1$d (current min is %2$d): `%3$s`",
-                            api, minSdk, fqcn);
-
-                    Location location = mContext.getUastLocation(node);
-                    mContext.report(issue, node, location, message);
-                }
-
-                return true;
-            }
-
-            return false;
-        }
-    }
-
-    private static boolean isSuppressed(int api, UElement element, int minSdk, JavaContext context, Issue issue) {
-        if (api <= minSdk) {
-            return true;
-        }
-
-        int target = getTargetApi(element);
-        if (target != -1) {
-            if (api <= target) {
-                return true;
-            }
-        }
-
-        LintDriver driver = context.getDriver();
-        if(driver.isSuppressed(context, issue, element)) {
-            return true;
-        }
-
-        if (isWithinVersionCheckConditional(element, api, context)) {
-            return true;
-        }
-        if (isPrecededByVersionCheckExit(element, api, context)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private static int getTargetApi(@Nullable UElement scope) {
-        while (scope != null) {
-            if (scope instanceof PsiModifierListOwner) {
-                PsiModifierList modifierList = ((PsiModifierListOwner) scope).getModifierList();
-                int targetApi = getTargetApi(modifierList);
-                if (targetApi != -1) {
-                    return targetApi;
-                }
-            }
-            scope = scope.getUastParent();
-            if (scope instanceof PsiFile) {
-                break;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the API level for the given AST node if specified with
-     * an {@code @TargetApi} annotation.
-     *
-     * @param modifierList the modifier list to check
-     * @return the target API level, or -1 if not specified
-     */
-    public static int getTargetApi(@Nullable PsiModifierList modifierList) {
-        if (modifierList == null) {
-            return -1;
-        }
-
-        for (PsiAnnotation annotation : modifierList.getAnnotations()) {
-            String fqcn = annotation.getQualifiedName();
-            if (fqcn != null &&
-                (fqcn.equals(FQCN_TARGET_API)
-                 || fqcn.equals(REQUIRES_API_ANNOTATION)
-                 || fqcn.equals(TARGET_API))) { // when missing imports
-                PsiAnnotationParameterList parameterList = annotation.getParameterList();
-                for (PsiNameValuePair pair : parameterList.getAttributes()) {
-                    PsiAnnotationMemberValue v = pair.getValue();
-                    if (v instanceof PsiLiteral) {
-                        PsiLiteral literal = (PsiLiteral)v;
-                        Object value = literal.getValue();
-                        if (value instanceof Integer) {
-                            return (Integer) value;
-                        } else if (value instanceof String) {
-                            return codeNameToApi((String) value);
-                        }
-                    } else if (v instanceof PsiArrayInitializerMemberValue) {
-                        PsiArrayInitializerMemberValue mv = (PsiArrayInitializerMemberValue)v;
-                        for (PsiAnnotationMemberValue mmv : mv.getInitializers()) {
-                            if (mmv instanceof PsiLiteral) {
-                                PsiLiteral literal = (PsiLiteral)mmv;
-                                Object value = literal.getValue();
-                                if (value instanceof Integer) {
-                                    return (Integer) value;
-                                } else if (value instanceof String) {
-                                    return codeNameToApi((String) value);
-                                }
-                            }
-                        }
-                    } else if (v instanceof PsiExpression) {
-                        // PsiExpression nodes are not present in light classes, so
-                        // we can use Java PSI api to get the qualified name
-                        if (v instanceof PsiReferenceExpression) {
-                            String name = ((PsiReferenceExpression)v).getQualifiedName();
-                            return codeNameToApi(name);
-                        } else {
-                            return codeNameToApi(v.getText());
-                        }
-                    }
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    private static int codeNameToApi(@NonNull String text) {
-        int dotIndex = text.lastIndexOf('.');
-        if (dotIndex != -1) {
-            text = text.substring(dotIndex + 1);
-        }
-
-        return SdkVersionInfo.getApiByBuildCode(text, true);
-    }
-
-    private static class VersionCheckWithExitFinder extends AbstractUastVisitor {
-
-        private final UExpression mExpression;
-        private final UElement mEndElement;
-        private final int mApi;
-        private final JavaContext mContext;
-
-        private boolean mFound = false;
-        private boolean mDone = false;
-
-        public VersionCheckWithExitFinder(UExpression expression, UElement endElement,
-                int api, JavaContext context) {
-            mExpression = expression;
-
-            mEndElement = endElement;
-            mApi = api;
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitElement(@NotNull UElement node) {
-            if (mDone) {
-                return true;
-            }
-
-            if (node.equals(mEndElement)) {
-                mDone = true;
-            }
-
-            return mDone || !mExpression.equals(node);
-        }
-
-        @Override
-        public boolean visitIfExpression(@NotNull UIfExpression ifStatement) {
-
-            if (mDone) {
-                return true;
-            }
-
-            UExpression thenBranch = ifStatement.getThenExpression();
-            UExpression elseBranch = ifStatement.getElseExpression();
-
-            if (thenBranch != null) {
-                Boolean level = isVersionCheckConditional(mApi, thenBranch, ifStatement, mContext);
-                //noinspection VariableNotUsedInsideIf
-                if (level != null) {
-                    // See if the body does an immediate return
-                    if (isUnconditionalReturn(thenBranch)) {
-                        mFound = true;
-                        mDone = true;
-                    }
-                }
-            }
-
-            if (elseBranch != null) {
-                Boolean level = isVersionCheckConditional(mApi, elseBranch, ifStatement, mContext);
-                //noinspection VariableNotUsedInsideIf
-                if (level != null) {
-                    if (isUnconditionalReturn(elseBranch)) {
-                        mFound = true;
-                        mDone = true;
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        public boolean found() {
-            return mFound;
-        }
-    }
-
-    private static boolean isPrecededByVersionCheckExit(
-            UElement element,
-            int api,
-            JavaContext context
-    ) {
-        //noinspection unchecked
-        UExpression currentExpression = UastUtils.getParentOfType(element, UExpression.class,
-                                                                  true, UMethod.class, UClass.class);
-
-        while(currentExpression != null) {
-            VersionCheckWithExitFinder visitor = new VersionCheckWithExitFinder(
-                    currentExpression, element, api, context);
-            currentExpression.accept(visitor);
-
-            if (visitor.found()) {
-                return true;
-            }
-
-            element = currentExpression;
-            //noinspection unchecked
-            currentExpression = UastUtils.getParentOfType(currentExpression, UExpression.class,
-                                                          true, UMethod.class, UClass.class);
-        }
-
-        return false;
-    }
-
-    private static boolean isUnconditionalReturn(UExpression expression) {
-        if (expression instanceof UBlockExpression) {
-            List<UExpression> expressions = ((UBlockExpression) expression).getExpressions();
-            return !expressions.isEmpty() && (isUnconditionalReturn(expressions.get(expressions.size() - 1)));
-        }
-
-        return expression instanceof UReturnExpression ||
-               expression instanceof UThrowExpression ||
-               (expression instanceof UCallExpression &&
-                ERROR.equals(((UCallExpression)expression).getMethodName()));
-    }
-
-    private static boolean isWithinVersionCheckConditional(
-            UElement element,
-            int api,
-            JavaContext context
-    ) {
-        UElement current = element.getUastParent();
-        UElement prev = element;
-        while (current != null) {
-            if (current instanceof UIfExpression) {
-                UIfExpression ifStatement = (UIfExpression) current;
-                Boolean isConditional = isVersionCheckConditional(api, prev, ifStatement, context);
-                if (isConditional != null) {
-                    return isConditional;
-                }
-            } else if (current instanceof UBinaryExpression) {
-                if (isAndedWithConditional(current, api, prev) || isOredWithConditional(current, api, prev)) {
-                    return true;
-                }
-            } else if (current instanceof UMethod || current instanceof UFile) {
-                return false;
-            }
-            prev = current;
-            current = current.getUastParent();
-        }
-
-        return false;
-    }
-
-    @Nullable
-    private static Boolean isVersionCheckConditional(
-            int api,
-            UElement prev,
-            UIfExpression ifStatement,
-            @NonNull JavaContext context) {
-        UExpression condition = ifStatement.getCondition();
-        if (condition != prev && condition instanceof UBinaryExpression) {
-            Boolean isConditional = isVersionCheckConditional(api, prev, ifStatement, (UBinaryExpression) condition);
-            if (isConditional != null) {
-                return isConditional;
-            }
-        } else if (condition instanceof UCallExpression) {
-            UCallExpression call = (UCallExpression) condition;
-            PsiMethod method = call.resolve();
-            if (method != null && !method.hasModifierProperty(PsiModifier.ABSTRACT)) {
-                UExpression body = context.getUastContext().getMethodBody(method);
-                List<UExpression> expressions;
-                if (body instanceof UBlockExpression) {
-                    expressions = ((UBlockExpression) body).getExpressions();
-                } else {
-                    expressions = Collections.singletonList(body);
-                }
-
-                if (expressions.size() == 1) {
-                    UExpression statement = expressions.get(0);
-                    if (statement instanceof UReturnExpression) {
-                        UReturnExpression returnStatement = (UReturnExpression) statement;
-                        UExpression returnValue = returnStatement.getReturnExpression();
-                        if (returnValue instanceof UBinaryExpression) {
-                            Boolean isConditional = isVersionCheckConditional(api, null, null,
-                                                                              (UBinaryExpression) returnValue);
-                            if (isConditional != null) {
-                                return isConditional;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    @Nullable
-    private static Boolean isVersionCheckConditional(
-            int api,
-            @Nullable UElement prev,
-            @Nullable UIfExpression ifStatement,
-            @NonNull UBinaryExpression binary) {
-        UastBinaryOperator tokenType = binary.getOperator();
-        if (tokenType == UastBinaryOperator.GREATER || tokenType == UastBinaryOperator.GREATER_OR_EQUALS ||
-            tokenType == UastBinaryOperator.LESS_OR_EQUALS || tokenType == UastBinaryOperator.LESS ||
-            tokenType == UastBinaryOperator.EQUALS || tokenType == UastBinaryOperator.IDENTITY_EQUALS) {
-            UExpression left = binary.getLeftOperand();
-            if (left instanceof UReferenceExpression) {
-                UReferenceExpression ref = (UReferenceExpression)left;
-                if (SDK_INT.equals(ref.getResolvedName())) {
-                    UExpression right = binary.getRightOperand();
-                    int level = -1;
-                    if (right instanceof UReferenceExpression) {
-                        UReferenceExpression ref2 = (UReferenceExpression)right;
-                        String codeName = ref2.getResolvedName();
-                        if (codeName == null) {
-                            return false;
-                        }
-                        level = SdkVersionInfo.getApiByBuildCode(codeName, true);
-                    } else if (right instanceof ULiteralExpression) {
-                        ULiteralExpression lit = (ULiteralExpression)right;
-                        Object value = lit.getValue();
-                        if (value instanceof Integer) {
-                            level = (Integer) value;
-                        }
-                    }
-                    if (level != -1) {
-                        boolean fromThen = ifStatement == null || prev == ifStatement.getThenExpression();
-                        boolean fromElse = ifStatement != null && prev == ifStatement.getElseExpression();
-                        assert fromThen == !fromElse;
-                        if (tokenType == UastBinaryOperator.GREATER_OR_EQUALS) {
-                            // if (SDK_INT >= ICE_CREAM_SANDWICH) { <call> } else { ... }
-                            return level >= api && fromThen;
-                        }
-                        else if (tokenType == UastBinaryOperator.GREATER) {
-                            // if (SDK_INT > ICE_CREAM_SANDWICH) { <call> } else { ... }
-                            return level >= api - 1 && fromThen;
-                        }
-                        else if (tokenType == UastBinaryOperator.LESS_OR_EQUALS) {
-                            // if (SDK_INT <= ICE_CREAM_SANDWICH) { ... } else { <call> }
-                            return level >= api - 1 && fromElse;
-                        }
-                        else if (tokenType == UastBinaryOperator.LESS) {
-                            // if (SDK_INT < ICE_CREAM_SANDWICH) { ... } else { <call> }
-                            return level >= api && fromElse;
-                        }
-                        else if (tokenType == UastBinaryOperator.EQUALS
-                                 || tokenType == UastBinaryOperator.IDENTITY_EQUALS) {
-                            // if (SDK_INT == ICE_CREAM_SANDWICH) { <call> } else {  }
-                            return level >= api && fromThen;
-                        } else {
-                            assert false : tokenType;
-                        }
-                    }
-                }
-            }
-        } else if (tokenType == UastBinaryOperator.LOGICAL_AND
-                   && (ifStatement != null && prev == ifStatement.getThenExpression())) {
-            if (isAndedWithConditional(ifStatement.getCondition(), api, prev)) {
-                return true;
-            }
-        }
-        return null;
-    }
-
-    private static Location getCatchParametersLocation(JavaContext context, UCatchClause catchClause) {
-        List<UTypeReferenceExpression> types = catchClause.getTypeReferences();
-        if (types.isEmpty()) {
-            return Location.NONE;
-        }
-
-        Location first = context.getUastLocation(types.get(0));
-        if (types.size() < 2) {
-            return first;
-        }
-
-        Location last = context.getUastLocation(types.get(types.size() - 1));
-        File file = first.getFile();
-        Position start = first.getStart();
-        Position end = last.getEnd();
-
-        if (start == null) {
-            return Location.create(file);
-        }
-
-        return Location.create(file, start, end);
-    }
-
-    private static boolean isMultiCatchReflectiveOperationException(UCatchClause catchClause) {
-        List<PsiType> types = catchClause.getTypes();
-        if (types.size() < 2) {
-            return false;
-        }
-
-        for (PsiType t : types) {
-            if(!isSubclassOfReflectiveOperationException(t)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private static boolean isAndedWithConditional(UElement element, int api, @Nullable UElement target) {
-        if (element instanceof UBinaryExpression) {
-            UBinaryExpression inner = (UBinaryExpression) element;
-            if (inner.getOperator() == UastBinaryOperator.LOGICAL_AND) {
-                return isAndedWithConditional(inner.getLeftOperand(), api, target) ||
-                       inner.getRightOperand() != target && isAndedWithConditional(inner.getRightOperand(), api, target);
-            } else if (inner.getLeftOperand() instanceof UReferenceExpression &&
-                        SDK_INT.equals(((UReferenceExpression)inner.getLeftOperand()).getResolvedName())) {
-                UastOperator tokenType = inner.getOperator();
-                UExpression right = inner.getRightOperand();
-                int level = getApiLevel(right);
-                if (level != -1) {
-                    if (tokenType == UastBinaryOperator.GREATER_OR_EQUALS) {
-                        // if (SDK_INT >= ICE_CREAM_SANDWICH && <call>
-                        return level >= api;
-                    }
-                    else if (tokenType == UastBinaryOperator.GREATER) {
-                        // if (SDK_INT > ICE_CREAM_SANDWICH) && <call>
-                        return level >= api - 1;
-                    }
-                    else if (tokenType == UastBinaryOperator.EQUALS
-                             || tokenType == UastBinaryOperator.IDENTITY_EQUALS) {
-                        // if (SDK_INT == ICE_CREAM_SANDWICH) && <call>
-                        return level >= api;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isOredWithConditional(UElement element, int api, @Nullable UElement target) {
-        if (element instanceof UBinaryExpression) {
-            UBinaryExpression inner = (UBinaryExpression) element;
-            if (inner.getOperator() == UastBinaryOperator.LOGICAL_OR) {
-                return isOredWithConditional(inner.getLeftOperand(), api, target) ||
-                       inner.getRightOperand() != target && isOredWithConditional(inner.getRightOperand(), api, target);
-            } else if (inner.getLeftOperand() instanceof UReferenceExpression &&
-                       SDK_INT.equals(((UReferenceExpression)inner.getLeftOperand()).getResolvedName())) {
-                UastOperator tokenType = inner.getOperator();
-                UExpression right = inner.getRightOperand();
-                int level = getApiLevel(right);
-                if (level != -1) {
-                    if (tokenType == UastBinaryOperator.LESS_OR_EQUALS) {
-                        // if (SDK_INT <= ICE_CREAM_SANDWICH || <call>
-                        return level >= api - 1;
-                    }
-                    else if (tokenType == UastBinaryOperator.LESS) {
-                        // if (SDK_INT < ICE_CREAM_SANDWICH) || <call>
-                        return level >= api;
-                    }
-                    else if (tokenType == UastBinaryOperator.NOT_EQUALS) {
-                        // if (SDK_INT < ICE_CREAM_SANDWICH) || <call>
-                        return level == api;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static int getApiLevel(UElement apiLevelElement) {
-        if (apiLevelElement instanceof UReferenceExpression) {
-            UReferenceExpression ref2 = (UReferenceExpression)apiLevelElement;
-            String codeName = ref2.getResolvedName();
-            if (codeName == null) {
-                return -1;
-            }
-            return SdkVersionInfo.getApiByBuildCode(codeName, true);
-        } else if (apiLevelElement instanceof ULiteralExpression) {
-            ULiteralExpression lit = (ULiteralExpression)apiLevelElement;
-            Object value = lit.getValue();
-            if (value instanceof Integer) {
-                return  ((Integer)value).intValue();
-            }
-        }
-        return -1;
-    }
-
-    private static boolean isSubclassOfReflectiveOperationException(PsiType type) {
-        for (PsiType t : type.getSuperTypes()) {
-            if (REFLECTIVE_OPERATION_EXCEPTION.equals(t.getCanonicalText())) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java
deleted file mode 100644
index 619cf4f..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java
+++ /dev/null
@@ -1,1352 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.tools.klint.detector.api.LintUtils.assertionsEnabled;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.repository.api.LocalPackage;
-import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.tools.klint.client.api.LintClient;
-//import com.android.tools.klint.client.api.SdkWrapper;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.utils.Pair;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import com.google.common.io.ByteSink;
-import com.google.common.io.Files;
-import com.google.common.primitives.UnsignedBytes;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Database for API checking: Allows quick lookup of a given class, method or field
- * to see which API level it was introduced in.
- * <p>
- * This class is optimized for quick bytecode lookup used in conjunction with the
- * ASM library: It has lookup methods that take internal JVM signatures, and for a method
- * call for example it processes the owner, name and description parameters separately
- * the way they are provided from ASM.
- * <p>
- * The {@link Api} class provides access to the full Android API along with version
- * information, initialized from an XML file. This lookup class adds a binary cache around
- * the API to make initialization faster and to require fewer objects. It creates
- * a binary cache data structure, which fits in a single byte array, which means that
- * to open the database you can just read in the byte array and go. On one particular
- * machine, this takes about 30-50 ms versus 600-800ms for the full parse. It also
- * helps memory by placing everything in a compact byte array instead of needing separate
- * strings (2 bytes per character in a char[] for the 25k method entries, 11k field entries
- * and 6k class entries) - and it also avoids the same number of Map.Entry objects.
- * When creating the memory data structure it performs a few other steps to help memory:
- * <ul>
- * <li> It stores the strings as single bytes, since all the JVM signatures are in ASCII
- * <li> It strips out the method return types (which takes the binary size down from
- *      about 4.7M to 4.0M)
- * <li> It strips out all APIs that have since=1, since the lookup only needs to find
- *      classes, methods and fields that have an API level *higher* than 1. This drops
- *      the memory use down from 4.0M to 1.7M.
- * </ul>
- */
-public class ApiLookup {
-    /** Relative path to the api-versions.xml database file within the Lint installation */
-    private static final String XML_FILE_PATH = "platform-tools/api/api-versions.xml"; //$NON-NLS-1$
-    private static final String FILE_HEADER = "API database used by Android lint\000";
-    private static final int BINARY_FORMAT_VERSION = 8;
-    private static final boolean DEBUG_SEARCH = false;
-    private static final boolean WRITE_STATS = false;
-
-    private static final int CLASS_HEADER_MEMBER_OFFSETS = 1;
-    private static final int CLASS_HEADER_API = 2;
-    private static final int CLASS_HEADER_DEPRECATED = 3;
-    private static final int CLASS_HEADER_INTERFACES = 4;
-    private static final int HAS_DEPRECATION_BYTE_FLAG = 1 << 7;
-    private static final int API_MASK = ~HAS_DEPRECATION_BYTE_FLAG;
-
-    @VisibleForTesting
-    static final boolean DEBUG_FORCE_REGENERATE_BINARY = false;
-
-    private final Api mInfo;
-    private byte[] mData;
-    private int[] mIndices;
-
-    private static WeakReference<ApiLookup> sInstance = new WeakReference<ApiLookup>(null);
-
-    private int mPackageCount;
-
-    /**
-     * Returns an instance of the API database
-     *
-     * @param client the client to associate with this database - used only for
-     *            logging. The database object may be shared among repeated invocations,
-     *            and in that case client used will be the one originally passed in.
-     *            In other words, this parameter may be ignored if the client created
-     *            is not new.
-     * @return a (possibly shared) instance of the API database, or null
-     *         if its data can't be found
-     */
-    @Nullable
-    public static ApiLookup get(@NonNull LintClient client) {
-        synchronized (ApiLookup.class) {
-            ApiLookup db = sInstance.get();
-            if (db == null) {
-                File file = client.findResource(XML_FILE_PATH);
-                if (file == null) {
-                    // AOSP build environment?
-                    String build = System.getenv("ANDROID_BUILD_TOP");   //$NON-NLS-1$
-                    if (build != null) {
-                        file = new File(build, "development/sdk/api-versions.xml" //$NON-NLS-1$
-                                .replace('/', File.separatorChar));
-                    }
-                }
-
-                if (file == null || !file.exists()) {
-                    return null;
-                } else {
-                    db = get(client, file);
-                }
-                sInstance = new WeakReference<ApiLookup>(db);
-            }
-
-            return db;
-        }
-    }
-
-    @VisibleForTesting
-    @Nullable
-    static String getPlatformVersion(@NonNull LintClient client) {
-        AndroidSdkHandler sdk = client.getSdk();
-        if (sdk != null) {
-            LocalPackage pkgInfo = sdk
-                    .getLocalPackage(SdkConstants.FD_PLATFORM_TOOLS, client.getRepositoryLogger());
-            if (pkgInfo != null) {
-                return pkgInfo.getVersion().toShortString();
-            }
-        }
-        return null;
-    }
-
-    @VisibleForTesting
-    @NonNull
-    static String getCacheFileName(@NonNull String xmlFileName, @Nullable String platformVersion) {
-        if (LintUtils.endsWith(xmlFileName, DOT_XML)) {
-            xmlFileName = xmlFileName.substring(0, xmlFileName.length() - DOT_XML.length());
-        }
-
-        StringBuilder sb = new StringBuilder(100);
-        sb.append(xmlFileName);
-
-        // Incorporate version number in the filename to avoid upgrade filename
-        // conflicts on Windows (such as issue #26663)
-        sb.append('-').append(BINARY_FORMAT_VERSION);
-
-        if (platformVersion != null) {
-            sb.append('-').append(platformVersion);
-        }
-
-        sb.append(".bin"); //$NON-NLS-1$
-        return sb.toString();
-    }
-
-    /**
-     * Returns an instance of the API database
-     *
-     * @param client the client to associate with this database - used only for
-     *            logging
-     * @param xmlFile the XML file containing configuration data to use for this
-     *            database
-     * @return a (possibly shared) instance of the API database, or null
-     *         if its data can't be found
-     */
-    private static ApiLookup get(LintClient client, File xmlFile) {
-        if (!xmlFile.exists()) {
-            client.log(null, "The API database file %1$s does not exist", xmlFile);
-            return null;
-        }
-
-        File cacheDir = client.getCacheDir(true/*create*/);
-        if (cacheDir == null) {
-            cacheDir = xmlFile.getParentFile();
-        }
-
-        String platformVersion = getPlatformVersion(client);
-        File binaryData = new File(cacheDir, getCacheFileName(xmlFile.getName(), platformVersion));
-
-        if (DEBUG_FORCE_REGENERATE_BINARY) {
-            System.err.println("\nTemporarily regenerating binary data unconditionally \nfrom "
-                    + xmlFile + "\nto " + binaryData);
-            if (!createCache(client, xmlFile, binaryData)) {
-                return null;
-            }
-        } else if (!binaryData.exists() || binaryData.lastModified() < xmlFile.lastModified()
-               || binaryData.length() == 0) {
-            if (!createCache(client, xmlFile, binaryData)) {
-                return null;
-            }
-        }
-
-        if (!binaryData.exists()) {
-            client.log(null, "The API database file %1$s does not exist", binaryData);
-            return null;
-        }
-
-        return new ApiLookup(client, xmlFile, binaryData, null);
-    }
-
-    private static boolean createCache(LintClient client, File xmlFile, File binaryData) {
-        long begin = 0;
-        if (WRITE_STATS) {
-            begin = System.currentTimeMillis();
-        }
-
-        Api info = Api.parseApi(xmlFile);
-
-        if (WRITE_STATS) {
-            long end = System.currentTimeMillis();
-            System.out.println("Reading XML data structures took " + (end - begin) + " ms)");
-        }
-
-        if (info != null) {
-            try {
-                writeDatabase(binaryData, info);
-                return true;
-            } catch (IOException ioe) {
-                client.log(ioe, "Can't write API cache file");
-            }
-        }
-
-        return false;
-    }
-
-    /** Use one of the {@link #get} factory methods instead */
-    private ApiLookup(
-            @NonNull LintClient client,
-            @NonNull File xmlFile,
-            @Nullable File binaryFile,
-            @Nullable Api info) {
-        mInfo = info;
-
-        if (binaryFile != null) {
-            readData(client, xmlFile, binaryFile);
-        }
-    }
-
-    /**
-     * Database format:
-     * <pre>
-     * (Note: all numbers are big endian; the format uses 1, 2, 3 and 4 byte integers.)
-     *
-     *
-     * 1. A file header, which is the exact contents of {@link #FILE_HEADER} encoded
-     *     as ASCII characters. The purpose of the header is to identify what the file
-     *     is for, for anyone attempting to open the file.
-     * 2. A file version number. If the binary file does not match the reader's expected
-     *     version, it can ignore it (and regenerate the cache from XML).
-     *
-     * 3. The index table. When the data file is read, this is used to initialize the
-     *    {@link #mIndices} array. The index table is built up like this:
-     *    a. The number of index entries (e.g. number of elements in the {@link #mIndices} array)
-     *        [1 4-byte int]
-     *    b. The number of java/javax packages [1 4 byte int]
-     *    c. Offsets to the package entries, one for each package, and each offset is 4 bytes.
-     *    d. Offsets to the class entries, one for each class, and each offset is 4 bytes.
-     *    e. Offsets to the member entries, one for each member, and each offset is 4 bytes.
-     *
-     * 4. The member entries -- one for each member. A given class entry will point to the
-     *    first and last members in the index table above, and the offset of a given member
-     *    is pointing to the offset of these entries.
-     *    a. The name and description (except for the return value) of the member, in JVM format
-     *       (e.g. for toLowerCase(char) we'd have "toLowerCase(C)". This is converted into
-     *       UTF_8 representation as bytes [n bytes, the length of the byte representation of
-     *       the description).
-     *    b. A terminating 0 byte [1 byte].
-     *    c. The API level the member was introduced in [1 byte], BUT with the
-     *       top bit ({@link #HAS_DEPRECATION_BYTE_FLAG}) set if the member is deprecated.
-     *    d. IF the member is deprecated, the API level the member was deprecated in [1 byte].
-     *       Note that this byte does not appear if the bit indicated in (c) is not set.
-     *
-     * 5. The class entries -- one for each class.
-     *    a. The index within this class entry where the metadata (other than the name)
-     *       can be found. [1 byte]. This means that if you know a class by its number,
-     *       you can quickly jump to its metadata without scanning through the string to
-     *       find the end of it, by just adding this byte to the current offset and
-     *       then you're at the data described below for (d).
-     *    b. The name of the class (just the base name, not the package), as encoded as a
-     *       UTF-8 string. [n bytes]
-     *    c. A terminating 0 [1 byte].
-     *    d. The index in the index table (3) of the first member in the class [a 3 byte integer.]
-     *    e. The number of members in the class [a 2 byte integer].
-     *    f. The API level the class was introduced in [1 byte], BUT with the
-     *       top bit ({@link #HAS_DEPRECATION_BYTE_FLAG}) set if the class is deprecated.
-     *    g. IF the class is deprecated, the API level the class was deprecated in [1 byte].
-     *       Note that this byte does not appear if the bit indicated in (f) is not set.
-     *    h. The number of new super classes and interfaces [1 byte]. This counts only
-     *       super classes and interfaces added after the original API level of the class.
-     *    i. For each super class or interface counted in h,
-     *       I. The index of the class [a 3 byte integer]
-     *       II. The API level the class/interface was added [1 byte]
-     *
-     * 6. The package entries -- one for each package.
-     *    a. The name of the package as encoded as a UTF-8 string. [n bytes]
-     *    b. A terminating 0 [1 byte].
-     *    c. The index in the index table (3) of the first class in the package [a 3 byte integer.]
-     *    d. The number of classes in the package [a 2 byte integer].
-     * </pre>
-     */
-    private void readData(@NonNull LintClient client, @NonNull File xmlFile,
-            @NonNull File binaryFile) {
-        if (!binaryFile.exists()) {
-            client.log(null, "%1$s does not exist", binaryFile);
-            return;
-        }
-        long start = System.currentTimeMillis();
-        try {
-            byte[] b = Files.toByteArray(binaryFile);
-
-            // First skip the header
-            int offset = 0;
-            byte[] expectedHeader = FILE_HEADER.getBytes(Charsets.US_ASCII);
-            for (byte anExpectedHeader : expectedHeader) {
-                if (anExpectedHeader != b[offset++]) {
-                    client.log(null, "Incorrect file header: not an API database cache " +
-                            "file, or a corrupt cache file");
-                    return;
-                }
-            }
-
-            // Read in the format number
-            if (b[offset++] != BINARY_FORMAT_VERSION) {
-                // Force regeneration of new binary data with up to date format
-                if (createCache(client, xmlFile, binaryFile)) {
-                    readData(client, xmlFile, binaryFile); // Recurse
-                }
-
-                return;
-            }
-
-            int indexCount = get4ByteInt(b, offset);
-            offset += 4;
-            mPackageCount = get4ByteInt(b, offset);
-            offset += 4;
-
-            mIndices = new int[indexCount];
-            for (int i = 0; i < indexCount; i++) {
-                // TODO: Pack the offsets: They increase by a small amount for each entry, so
-                // no need to spend 4 bytes on each. These will need to be processed when read
-                // back in anyway, so consider storing the offset -deltas- as single bytes and
-                // adding them up cumulatively in readData().
-                mIndices[i] = get4ByteInt(b, offset);
-                offset += 4;
-            }
-            mData = b;
-            // TODO: We only need to keep the data portion here since we've initialized
-            // the offset array separately.
-            // TODO: Investigate (profile) accessing the byte buffer directly instead of
-            // accessing a byte array.
-        } catch (Throwable e) {
-            client.log(null, "Failure reading binary cache file %1$s", binaryFile.getPath());
-            client.log(null, "Please delete the file and restart the IDE/lint: %1$s",
-                    binaryFile.getPath());
-            client.log(e, null);
-        }
-        if (WRITE_STATS) {
-            long end = System.currentTimeMillis();
-            System.out.println("\nRead API database in " + (end - start)
-                    + " milliseconds.");
-            System.out.println("Size of data table: " + mData.length + " bytes ("
-                    + Integer.toString(mData.length / 1024) + "k)\n");
-        }
-    }
-
-    /** See the {@link #readData(LintClient,File,File)} for documentation on the data format. */
-    private static void writeDatabase(File file, Api info) throws IOException {
-        Map<String, ApiClass> classMap = info.getClasses();
-
-        List<ApiPackage> packages = Lists.newArrayList(info.getPackages().values());
-        Collections.sort(packages);
-
-        // Compute members of each class that must be included in the database; we can
-        // skip those that have the same since-level as the containing class. And we
-        // also need to keep those entries that are marked deprecated.
-        int estimatedSize = 0;
-        for (ApiPackage pkg : packages) {
-            estimatedSize += 4; // offset entry
-            estimatedSize += pkg.getName().length() + 20; // package entry
-
-            if (assertionsEnabled() && !isRelevantOwner(pkg.getName() + "/") &&
-                    !pkg.getName().startsWith("android/support")) {
-                System.out.println("Warning: isRelevantOwner fails for " + pkg.getName() + "/");
-            }
-
-            for (ApiClass apiClass : pkg.getClasses()) {
-                estimatedSize += 4; // offset entry
-                estimatedSize += apiClass.getName().length() + 20; // class entry
-
-                Set<String> allMethods = apiClass.getAllMethods(info);
-                Set<String> allFields = apiClass.getAllFields(info);
-                // Strip out all members that have been supported since version 1.
-                // This makes the database *much* leaner (down from about 4M to about
-                // 1.7M), and this just fills the table with entries that ultimately
-                // don't help the API checker since it just needs to know if something
-                // requires a version *higher* than the minimum. If in the future the
-                // database needs to answer queries about whether a method is public
-                // or not, then we'd need to put this data back in.
-                int clsSince = apiClass.getSince();
-                List<String> members = new ArrayList<String>(allMethods.size() + allFields.size());
-                for (String member : allMethods) {
-                    if (apiClass.getMethod(member, info) != clsSince
-                            || apiClass.getMemberDeprecatedIn(member, info) > 0) {
-                        members.add(member);
-                    }
-                }
-                for (String member : allFields) {
-                    if (apiClass.getField(member, info) != clsSince
-                            || apiClass.getMemberDeprecatedIn(member, info) > 0) {
-                        members.add(member);
-                    }
-                }
-
-                estimatedSize += 2 + 4 * (apiClass.getInterfaces().size());
-                if (apiClass.getSuperClasses().size() > 1) {
-                    estimatedSize += 2 + 4 * (apiClass.getSuperClasses().size());
-                }
-
-                // Only include classes that have one or more members requiring version 2 or higher:
-                Collections.sort(members);
-                apiClass.members = members;
-                for (String member : members) {
-                    estimatedSize += member.length();
-                    estimatedSize += 16;
-                }
-            }
-
-            // Ensure the classes are sorted
-            Collections.sort(pkg.getClasses());
-        }
-
-        // Write header
-        ByteBuffer buffer = ByteBuffer.allocate(estimatedSize);
-        buffer.order(ByteOrder.BIG_ENDIAN);
-        buffer.put(FILE_HEADER.getBytes(Charsets.US_ASCII));
-        buffer.put((byte) BINARY_FORMAT_VERSION);
-
-        int indexCountOffset = buffer.position();
-        int indexCount = 0;
-
-        buffer.putInt(0); // placeholder
-
-        // Write the number of packages in the package index
-        buffer.putInt(packages.size());
-
-        // Write package index
-        int newIndex = buffer.position();
-        for (ApiPackage pkg : packages) {
-            pkg.indexOffset = newIndex;
-            newIndex += 4;
-            indexCount++;
-        }
-
-        // Write class index
-        for (ApiPackage pkg : packages) {
-            for (ApiClass cls : pkg.getClasses()) {
-                cls.indexOffset = newIndex;
-                cls.index = indexCount;
-                newIndex += 4;
-                indexCount++;
-            }
-        }
-
-        // Write member indices
-        for (ApiPackage pkg : packages) {
-            for (ApiClass cls : pkg.getClasses()) {
-                if (cls.members != null && !cls.members.isEmpty()) {
-                    cls.memberOffsetBegin = newIndex;
-                    cls.memberIndexStart = indexCount;
-                    for (String ignored : cls.members) {
-                        newIndex += 4;
-                        indexCount++;
-                    }
-                    cls.memberOffsetEnd = newIndex;
-                    cls.memberIndexLength = indexCount - cls.memberIndexStart;
-                } else {
-                    cls.memberOffsetBegin = -1;
-                    cls.memberOffsetEnd = -1;
-                    cls.memberIndexStart = -1;
-                    cls.memberIndexLength = 0;
-                }
-            }
-        }
-
-        // Fill in the earlier index count
-        buffer.position(indexCountOffset);
-        buffer.putInt(indexCount);
-        buffer.position(newIndex);
-
-        // Write member entries
-        for (ApiPackage pkg : packages) {
-            for (ApiClass apiClass : pkg.getClasses()) {
-                String clz = apiClass.getName();
-                int index = apiClass.memberOffsetBegin;
-                for (String member : apiClass.members) {
-                    // Update member offset to point to this entry
-                    int start = buffer.position();
-                    buffer.position(index);
-                    buffer.putInt(start);
-                    index = buffer.position();
-                    buffer.position(start);
-
-                    int since;
-                    if (member.indexOf('(') != -1) {
-                        since = apiClass.getMethod(member, info);
-                    } else {
-                        since = apiClass.getField(member, info);
-                    }
-                    if (since == Integer.MAX_VALUE) {
-                        assert false : clz + ':' + member;
-                        since = 1;
-                    }
-
-                    int deprecatedIn = apiClass.getMemberDeprecatedIn(member, info);
-                    if (deprecatedIn != 0) {
-                        assert deprecatedIn != -1 : deprecatedIn + " for " + member;
-                    }
-
-                    byte[] signature = member.getBytes(Charsets.UTF_8);
-                    for (byte b : signature) {
-                        // Make sure all signatures are really just simple ASCII
-                        assert b == (b & 0x7f) : member;
-                        buffer.put(b);
-                        // Skip types on methods
-                        if (b == (byte) ')') {
-                            break;
-                        }
-                    }
-                    buffer.put((byte) 0);
-                    int api = since;
-                    assert api == UnsignedBytes.toInt((byte) api);
-                    assert api >= 1 && api < 0xFF; // max that fits in a byte
-
-                    boolean isDeprecated = deprecatedIn > 0;
-                    if (isDeprecated) {
-                        api |= HAS_DEPRECATION_BYTE_FLAG;
-                    }
-
-                    buffer.put((byte) api);
-
-                    if (isDeprecated) {
-                        assert deprecatedIn == UnsignedBytes.toInt((byte) deprecatedIn);
-                        buffer.put((byte) deprecatedIn);
-                    }
-                }
-                assert index == apiClass.memberOffsetEnd : apiClass.memberOffsetEnd;
-            }
-        }
-
-        // Write class entries. These are written together, rather than
-        // being spread out among the member entries, in order to have
-        // reference locality (search that a binary search through the classes
-        // are likely to look at entries near each other.)
-        for (ApiPackage pkg : packages) {
-            List<ApiClass> classes = pkg.getClasses();
-            for (ApiClass cls : classes) {
-                int index = buffer.position();
-                buffer.position(cls.indexOffset);
-                buffer.putInt(index);
-                buffer.position(index);
-                String name = cls.getSimpleName();
-
-                byte[] nameBytes = name.getBytes(Charsets.UTF_8);
-                assert nameBytes.length < 254 : name;
-                buffer.put((byte)(nameBytes.length + 2)); // 2: terminating 0, and this byte itself
-                buffer.put(nameBytes);
-                buffer.put((byte) 0);
-
-                // 3 bytes for beginning, 2 bytes for *length*
-                put3ByteInt(buffer, cls.memberIndexStart);
-                put2ByteInt(buffer, cls.memberIndexLength);
-
-                ApiClass apiClass = classMap.get(cls.getName());
-                assert apiClass != null : cls.getName();
-                int since = apiClass.getSince();
-                assert since == UnsignedBytes.toInt((byte) since) : since; // make sure it fits
-                int deprecatedIn = apiClass.getDeprecatedIn();
-                boolean isDeprecated = deprecatedIn > 0;
-                // The first byte is deprecated in
-                if (isDeprecated) {
-                    since |= HAS_DEPRECATION_BYTE_FLAG;
-                    assert since == UnsignedBytes.toInt((byte) since) : since; // make sure it fits
-                }
-                buffer.put((byte) since);
-                if (isDeprecated) {
-                    assert deprecatedIn == UnsignedBytes.toInt((byte) deprecatedIn) : deprecatedIn;
-                    buffer.put((byte) deprecatedIn);
-                }
-
-                List<Pair<String, Integer>> interfaces = apiClass.getInterfaces();
-                int count = 0;
-                if (interfaces != null && !interfaces.isEmpty()) {
-                    for (Pair<String, Integer> pair : interfaces) {
-                        int api = pair.getSecond();
-                        if (api > apiClass.getSince()) {
-                            count++;
-                        }
-                    }
-                }
-                List<Pair<String, Integer>> supers = apiClass.getSuperClasses();
-                if (supers != null && !supers.isEmpty()) {
-                    for (Pair<String, Integer> pair : supers) {
-                        int api = pair.getSecond();
-                        if (api > apiClass.getSince()) {
-                            count++;
-                        }
-                    }
-                }
-                buffer.put((byte)count);
-                if (count > 0) {
-                    if (supers != null) {
-                        for (Pair<String, Integer> pair : supers) {
-                            int api = pair.getSecond();
-                            if (api > apiClass.getSince()) {
-                                ApiClass superClass = classMap.get(pair.getFirst());
-                                assert superClass != null : cls;
-                                put3ByteInt(buffer, superClass.index);
-                                buffer.put((byte) api);
-                            }
-                        }
-                    }
-                    if (interfaces != null) {
-                        for (Pair<String, Integer> pair : interfaces) {
-                            int api = pair.getSecond();
-                            if (api > apiClass.getSince()) {
-                                ApiClass interfaceClass = classMap.get(pair.getFirst());
-                                assert interfaceClass != null : cls;
-                                put3ByteInt(buffer, interfaceClass.index);
-                                buffer.put((byte) api);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        for (ApiPackage pkg : packages) {
-            int index = buffer.position();
-            buffer.position(pkg.indexOffset);
-            buffer.putInt(index);
-            buffer.position(index);
-
-            byte[] bytes = pkg.getName().getBytes(Charsets.UTF_8);
-            buffer.put(bytes);
-            buffer.put((byte)0);
-
-            List<ApiClass> classes = pkg.getClasses();
-            if (classes.isEmpty()) {
-                put3ByteInt(buffer, 0);
-                put2ByteInt(buffer, 0);
-            } else {
-                // 3 bytes for beginning, 2 bytes for *length*
-                int firstClassIndex = classes.get(0).index;
-                int classCount = classes.get(classes.size() - 1).index - firstClassIndex + 1;
-                put3ByteInt(buffer, firstClassIndex);
-                put2ByteInt(buffer, classCount);
-            }
-        }
-
-        int size = buffer.position();
-        assert size <= buffer.limit();
-        buffer.mark();
-
-        if (WRITE_STATS) {
-            System.out.print("Actual binary size: " + size + " bytes");
-            System.out.println(String.format(" (%.1fM)", size/(1024*1024.f)));
-        }
-
-        // Now dump this out as a file
-        // There's probably an API to do this more efficiently; TODO: Look into this.
-        byte[] b = new byte[size];
-        buffer.rewind();
-        buffer.get(b);
-        if (file.exists()) {
-            boolean deleted = file.delete();
-            assert deleted : file;
-        }
-        ByteSink sink = Files.asByteSink(file);
-        sink.write(b);
-    }
-
-    // For debugging only
-    private String dumpEntry(int offset) {
-        if (DEBUG_SEARCH) {
-            StringBuilder sb = new StringBuilder(200);
-            for (int i = offset; i < mData.length; i++) {
-                if (mData[i] == 0) {
-                    break;
-                }
-                char c = (char) UnsignedBytes.toInt(mData[i]);
-                sb.append(c);
-            }
-
-            return sb.toString();
-        } else {
-            return "<disabled>"; //$NON-NLS-1$
-        }
-    }
-
-    private static int compare(byte[] data, int offset, byte terminator, String s, int sOffset,
-            int max) {
-        int i = offset;
-        int j = sOffset;
-        for (; j < max; i++, j++) {
-            byte b = data[i];
-            char c = s.charAt(j);
-            // TODO: Check somewhere that the strings are purely in the ASCII range; if not
-            // they're not a match in the database
-            byte cb = (byte) c;
-            int delta = b - cb;
-            if (delta != 0) {
-                return delta;
-            }
-        }
-
-        return data[i] - terminator;
-    }
-
-    /**
-     * Returns the API version required by the given class reference,
-     * or -1 if this is not a known API class. Note that it may return -1
-     * for classes introduced in version 1; internally the database only
-     * stores version data for version 2 and up.
-     *
-     * @param className the internal name of the class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @return the minimum API version the method is supported for, or -1 if
-     *         it's unknown <b>or version 1</b>.
-     */
-    public int getClassVersion(@NonNull String className) {
-        //noinspection VariableNotUsedInsideIf
-        if (mData != null) {
-            return getClassVersion(findClass(className));
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(className);
-            if (clz != null) {
-                int since = clz.getSince();
-                if (since == Integer.MAX_VALUE) {
-                    since = -1;
-                }
-                return since;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns true if the given owner class is known in the API database.
-     *
-     * @param className the internal name of the class, e.g. its fully qualified name (as returned
-     *                  by Class.getName(), but with '.' replaced by '/' (and '$' for inner
-     *                  classes)
-     * @return true if this is a class found in the API database
-     */
-    public boolean isKnownClass(@NonNull String className) {
-        return findClass(className) != -1;
-    }
-
-    private int getClassVersion(int classNumber) {
-        if (classNumber != -1) {
-            int offset = seekClassData(classNumber, CLASS_HEADER_API);
-            int api = UnsignedBytes.toInt(mData[offset]) & API_MASK;
-            return api > 1 ? api : -1;
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the API version required to perform the given cast, or -1 if this is valid for all
-     * versions of the class (or, if these are not known classes or if the cast is not valid at
-     * all.) <p> Note also that this method should only be called for interfaces that are actually
-     * implemented by this class or extending the given super class (check elsewhere); it doesn't
-     * distinguish between interfaces implemented in the initial version of the class and interfaces
-     * not implemented at all.
-     *
-     * @param sourceClass      the internal name of the class, e.g. its fully qualified name (as
-     *                         returned by Class.getName(), but with '.' replaced by '/'.
-     * @param destinationClass the class to cast the sourceClass to
-     * @return the minimum API version the method is supported for, or 1 or -1 if it's unknown.
-     */
-    public int getValidCastVersion(@NonNull String sourceClass,
-            @NonNull String destinationClass) {
-        if (mData != null) {
-            int classNumber = findClass(sourceClass);
-            if (classNumber != -1) {
-                int interfaceNumber = findClass(destinationClass);
-                if (interfaceNumber != -1) {
-                    int offset = seekClassData(classNumber, CLASS_HEADER_INTERFACES);
-                    int interfaceCount = mData[offset++];
-                    for (int i = 0; i < interfaceCount; i++) {
-                        int clsNumber = get3ByteInt(mData, offset);
-                        offset += 3;
-                        int api = mData[offset++];
-                        if (clsNumber == interfaceNumber) {
-                           return api;
-                        }
-                    }
-                    return getClassVersion(classNumber);
-                }
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(sourceClass);
-            if (clz != null) {
-                List<Pair<String, Integer>> interfaces = clz.getInterfaces();
-                for (Pair<String,Integer> pair : interfaces) {
-                    String interfaceName = pair.getFirst();
-                    if (interfaceName.equals(destinationClass)) {
-                        return pair.getSecond();
-                    }
-                }
-            }
-        }
-
-        return -1;
-    }
-    /**
-     * Returns the API version the given class was deprecated in, or -1 if the class
-     * is not deprecated.
-     *
-     * @param className the internal name of the method's owner class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @return the API version the API was deprecated in, or -1 if
-     *         it's unknown <b>or version 0</b>.
-     */
-    public int getClassDeprecatedIn(@NonNull String className) {
-        if (mData != null) {
-            int classNumber = findClass(className);
-            if (classNumber != -1) {
-                int offset = seekClassData(classNumber, CLASS_HEADER_DEPRECATED);
-                if (offset == -1) {
-                    // Not deprecated
-                    return -1;
-                }
-                int deprecatedIn = UnsignedBytes.toInt(mData[offset]);
-                return deprecatedIn != 0 ? deprecatedIn : -1;
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(className);
-            if (clz != null) {
-                int deprecatedIn = clz.getDeprecatedIn();
-                if (deprecatedIn == Integer.MAX_VALUE) {
-                    deprecatedIn = -1;
-                }
-                return deprecatedIn;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the API version required by the given method call. The method is
-     * referred to by its {@code owner}, {@code name} and {@code desc} fields.
-     * If the method is unknown it returns -1. Note that it may return -1 for
-     * classes introduced in version 1; internally the database only stores
-     * version data for version 2 and up.
-     *
-     * @param owner the internal name of the method's owner class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @param name the method's name
-     * @param desc the method's descriptor - see {@link Type}
-     * @return the minimum API version the method is supported for, or 1 or -1 if
-     *         it's unknown.
-     */
-    public int getCallVersion(
-            @NonNull String owner,
-            @NonNull String name,
-            @NonNull String desc) {
-        //noinspection VariableNotUsedInsideIf
-        if (mData != null) {
-            int classNumber = findClass(owner);
-            if (classNumber != -1) {
-                int api = findMember(classNumber, name, desc);
-                if (api == -1) {
-                    return getClassVersion(classNumber);
-                }
-                return api;
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(owner);
-            if (clz != null) {
-                String signature = name + desc;
-                int since = clz.getMethod(signature, mInfo);
-                if (since == Integer.MAX_VALUE) {
-                    since = -1;
-                }
-                return since;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the API version the given call was deprecated in, or -1 if the method
-     * is not deprecated.
-     *
-     * @param owner the internal name of the method's owner class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @param name the method's name
-     * @param desc the method's descriptor - see {@link Type}
-     * @return the API version the API was deprecated in, or 1 or -1 if
-     *         it's unknown.
-     */
-    public int getCallDeprecatedIn(
-            @NonNull String owner,
-            @NonNull String name,
-            @NonNull String desc) {
-        //noinspection VariableNotUsedInsideIf
-        if (mData != null) {
-            int classNumber = findClass(owner);
-            if (classNumber != -1) {
-                int deprecatedIn = findMemberDeprecatedIn(classNumber, name, desc);
-                return deprecatedIn != 0 ? deprecatedIn : -1;
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(owner);
-            if (clz != null) {
-                String signature = name + desc;
-                int deprecatedIn = clz.getMemberDeprecatedIn(signature, mInfo);
-                if (deprecatedIn == Integer.MAX_VALUE) {
-                    deprecatedIn = -1;
-                }
-                return deprecatedIn;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the API version required to access the given field, or -1 if this
-     * is not a known API method. Note that it may return -1 for classes
-     * introduced in version 1; internally the database only stores version data
-     * for version 2 and up.
-     *
-     * @param owner the internal name of the method's owner class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @param name the method's name
-     * @return the minimum API version the method is supported for, or 1 or -1 if
-     *         it's unknown.
-     */
-    public int getFieldVersion(
-            @NonNull String owner,
-            @NonNull String name) {
-        //noinspection VariableNotUsedInsideIf
-        if (mData != null) {
-            int classNumber = findClass(owner);
-            if (classNumber != -1) {
-                int api = findMember(classNumber, name, null);
-                if (api == -1) {
-                    return getClassVersion(classNumber);
-                }
-                return api;
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(owner);
-            if (clz != null) {
-                int since = clz.getField(name, mInfo);
-                if (since == Integer.MAX_VALUE) {
-                    since = -1;
-                }
-                return since;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the API version the given field was deprecated in, or -1 if the field
-     * is not deprecated.
-     *
-     * @param owner the internal name of the method's owner class, e.g. its
-     *            fully qualified name (as returned by Class.getName(), but with
-     *            '.' replaced by '/'.
-     * @param name the method's name
-     * @return the API version the API was deprecated in, or 1 or -1 if
-     *         it's unknown.
-     */
-    public int getFieldDeprecatedIn(
-            @NonNull String owner,
-            @NonNull String name) {
-        //noinspection VariableNotUsedInsideIf
-        if (mData != null) {
-            int classNumber = findClass(owner);
-            if (classNumber != -1) {
-                int deprecatedIn = findMemberDeprecatedIn(classNumber, name, null);
-                return deprecatedIn != 0 ? deprecatedIn : -1;
-            }
-        }  else {
-            assert mInfo != null;
-            ApiClass clz = mInfo.getClass(owner);
-            if (clz != null) {
-                int deprecatedIn = clz.getMemberDeprecatedIn(name, mInfo);
-                if (deprecatedIn == Integer.MAX_VALUE) {
-                    deprecatedIn = -1;
-                }
-                return deprecatedIn;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns true if the given owner (in VM format) is relevant to the database.
-     * This allows quick filtering out of owners that won't return any data
-     * for the various {@code #getFieldVersion} etc methods.
-     *
-     * @param owner the owner to look up
-     * @return true if the owner might be relevant to the API database
-     */
-    public static boolean isRelevantOwner(@NonNull String owner) {
-        if (owner.startsWith("java")) {                   //$NON-NLS-1$ // includes javax/
-            return true;
-        }
-        if (owner.startsWith(ANDROID_PKG)) {
-            return !owner.startsWith("/support/", 7);
-        } else if (owner.startsWith("org/")) {            //$NON-NLS-1$
-            if (owner.startsWith("xml", 4)                //$NON-NLS-1$
-                    || owner.startsWith("w3c/", 4)        //$NON-NLS-1$
-                    || owner.startsWith("json/", 4)       //$NON-NLS-1$
-                    || owner.startsWith("apache/", 4)) {  //$NON-NLS-1$
-                return true;
-            }
-        } else if (owner.startsWith("com/")) {            //$NON-NLS-1$
-            if (owner.startsWith("google/", 4)            //$NON-NLS-1$
-                    || owner.startsWith("android/", 4)) { //$NON-NLS-1$
-                return true;
-            }
-        } else if (owner.startsWith("junit")              //$NON-NLS-1$
-                    || owner.startsWith("dalvik")) {      //$NON-NLS-1$
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns true if the given owner (in VM format) is a valid Java package supported
-     * in any version of Android.
-     *
-     * @param owner the package, in VM format
-     * @return true if the package is included in one or more versions of Android
-     */
-    public boolean isValidJavaPackage(@NonNull String owner) {
-        return findPackage(owner) != -1;
-    }
-
-    /** Returns the package index of the given class, or -1 if it is unknown */
-    private int findPackage(@NonNull String owner) {
-        assert owner.indexOf('.') == -1 : "Should use / instead of . in owner: " + owner;
-
-        // The index array contains class indexes from 0 to classCount and
-        //   member indices from classCount to mIndices.length.
-        int low = 0;
-        int high = mPackageCount - 1;
-        // Compare the api info at the given index.
-        int classNameLength = owner.lastIndexOf('/');
-        while (low <= high) {
-            int middle = (low + high) >>> 1;
-            int offset = mIndices[middle];
-
-            if (DEBUG_SEARCH) {
-                System.out.println("Comparing string " + owner.substring(0, classNameLength)
-                        + " with entry at " + offset + ": " + dumpEntry(offset));
-            }
-
-            int compare = compare(mData, offset, (byte) 0, owner, 0, classNameLength);
-            if (compare == 0) {
-                if (DEBUG_SEARCH) {
-                    System.out.println("Found " + dumpEntry(offset));
-                }
-                return middle;
-            }
-
-            if (compare < 0) {
-                low = middle + 1;
-            } else if (compare > 0) {
-                high = middle - 1;
-            } else {
-                assert false; // compare == 0 already handled above
-                return -1;
-            }
-        }
-
-        return -1;
-    }
-
-    private static int get4ByteInt(@NonNull byte[] data, int offset) {
-        byte b1 = data[offset++];
-        byte b2 = data[offset++];
-        byte b3 = data[offset++];
-        byte b4 = data[offset];
-        // The byte data is always big endian.
-        return (b1 & 0xFF) << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
-    }
-
-    private static void put3ByteInt(@NonNull ByteBuffer buffer, int value) {
-        // Big endian
-        byte b3 = (byte) (value & 0xFF);
-        value >>>= 8;
-        byte b2 = (byte) (value & 0xFF);
-        value >>>= 8;
-        byte b1 = (byte) (value & 0xFF);
-        buffer.put(b1);
-        buffer.put(b2);
-        buffer.put(b3);
-    }
-
-    private static void put2ByteInt(@NonNull ByteBuffer buffer, int value) {
-        // Big endian
-        byte b2 = (byte) (value & 0xFF);
-        value >>>= 8;
-        byte b1 = (byte) (value & 0xFF);
-        buffer.put(b1);
-        buffer.put(b2);
-    }
-
-    private static int get3ByteInt(@NonNull byte[] mData, int offset) {
-        byte b1 = mData[offset++];
-        byte b2 = mData[offset++];
-        byte b3 = mData[offset];
-        // The byte data is always big endian.
-        return (b1 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b3 & 0xFF);
-    }
-
-    private static int get2ByteInt(@NonNull byte[] data, int offset) {
-        byte b1 = data[offset++];
-        byte b2 = data[offset];
-        // The byte data is always big endian.
-        return (b1 & 0xFF) << 8 | (b2 & 0xFF);
-    }
-
-    /** Returns the class number of the given class, or -1 if it is unknown */
-    private int findClass(@NonNull String owner) {
-        assert owner.indexOf('.') == -1 : "Should use / instead of . in owner: " + owner;
-
-        int packageNumber = findPackage(owner);
-        if (packageNumber == -1) {
-            return -1;
-        }
-        int curr = mIndices[packageNumber];
-        while (mData[curr] != 0) {
-            curr++;
-        }
-        curr++;
-
-        // 3 bytes for first offset
-        int low = get3ByteInt(mData, curr);
-        curr += 3;
-
-        int length = get2ByteInt(mData, curr);
-        if (length == 0) {
-            return -1;
-        }
-        int high = low + length - 1;
-        int index = owner.lastIndexOf('/');
-        int classNameLength = owner.length();
-        while (low <= high) {
-            int middle = (low + high) >>> 1;
-            int offset = mIndices[middle];
-            offset++; // skip the byte which points to the metadata after the name
-
-            if (DEBUG_SEARCH) {
-                System.out.println("Comparing string " + owner.substring(0, classNameLength)
-                        + " with entry at " + offset + ": " + dumpEntry(offset));
-            }
-
-            int compare = compare(mData, offset, (byte) 0, owner, index + 1, classNameLength);
-            if (compare == 0) {
-                if (DEBUG_SEARCH) {
-                    System.out.println("Found " + dumpEntry(offset));
-                }
-                return middle;
-            }
-
-            if (compare < 0) {
-                low = middle + 1;
-            } else if (compare > 0) {
-                high = middle - 1;
-            } else {
-                assert false; // compare == 0 already handled above
-                return -1;
-            }
-        }
-
-        return -1;
-    }
-
-    private int findMember(int classNumber, @NonNull String name, @Nullable String desc) {
-        return findMember(classNumber, name, desc, false);
-    }
-
-    private int findMemberDeprecatedIn(int classNumber, @NonNull String name,
-            @Nullable String desc) {
-        return findMember(classNumber, name, desc, true);
-    }
-
-    private int seekClassData(int classNumber, int field) {
-        int offset = mIndices[classNumber];
-        offset += mData[offset] & 0xFF;
-        if (field == CLASS_HEADER_MEMBER_OFFSETS) {
-            return offset;
-        }
-        offset += 5; // 3 bytes for start, 2 bytes for length
-        if (field == CLASS_HEADER_API) {
-            return offset;
-        }
-        boolean hasDeprecation = (mData[offset] & HAS_DEPRECATION_BYTE_FLAG) != 0;
-        offset++;
-        if (field == CLASS_HEADER_DEPRECATED) {
-            return hasDeprecation ? offset : -1;
-        } else if (hasDeprecation) {
-            offset++;
-        }
-        assert field == CLASS_HEADER_INTERFACES;
-        return offset;
-    }
-
-    private int findMember(int classNumber, @NonNull String name, @Nullable String desc,
-            boolean deprecation) {
-        int curr = seekClassData(classNumber, CLASS_HEADER_MEMBER_OFFSETS);
-
-        // 3 bytes for first offset
-        int low = get3ByteInt(mData, curr);
-        curr += 3;
-
-        int length = get2ByteInt(mData, curr);
-        if (length == 0) {
-            return -1;
-        }
-        int high = low + length - 1;
-
-        while (low <= high) {
-            int middle = (low + high) >>> 1;
-            int offset = mIndices[middle];
-
-            if (DEBUG_SEARCH) {
-                System.out.println("Comparing string " + (name + ';' + desc) +
-                        " with entry at " + offset + ": " + dumpEntry(offset));
-            }
-
-            int compare;
-            if (desc != null) {
-                // Method
-                int nameLength = name.length();
-                compare = compare(mData, offset, (byte) '(', name, 0, nameLength);
-                if (compare == 0) {
-                    offset += nameLength;
-                    int argsEnd = desc.indexOf(')');
-                    // Only compare up to the ) -- after that we have a return value in the
-                    // input description, which isn't there in the database
-                    compare = compare(mData, offset, (byte) ')', desc, 0, argsEnd);
-                    if (compare == 0) {
-                        if (DEBUG_SEARCH) {
-                            System.out.println("Found " + dumpEntry(offset));
-                        }
-
-                        offset += argsEnd + 1;
-
-                        if (mData[offset++] == 0) {
-                            // Yes, terminated argument list: get the API level
-                            int api = UnsignedBytes.toInt(mData[offset]);
-                            if (deprecation) {
-                                if ((api & HAS_DEPRECATION_BYTE_FLAG) != 0) {
-                                    return UnsignedBytes.toInt(mData[offset + 1]);
-                                } else {
-                                    return -1;
-                                }
-                            } else {
-                                return api & API_MASK;
-                            }
-                        }
-                    }
-                }
-            } else {
-                // Field
-                int nameLength = name.length();
-                compare = compare(mData, offset, (byte) 0, name, 0, nameLength);
-                if (compare == 0) {
-                    offset += nameLength;
-                    if (mData[offset++] == 0) {
-                        // Yes, terminated argument list: get the API level
-                        int api = UnsignedBytes.toInt(mData[offset]);
-                        if (deprecation) {
-                            if ((api & HAS_DEPRECATION_BYTE_FLAG) != 0) {
-                                return UnsignedBytes.toInt(mData[offset + 1]);
-                            } else {
-                                return -1;
-                            }
-                        } else {
-                            return api & API_MASK;
-                        }
-                    }
-                }
-            }
-
-            if (compare < 0) {
-                low = middle + 1;
-            } else if (compare > 0) {
-                high = middle - 1;
-            } else {
-                assert false; // compare == 0 already handled above
-                return -1;
-            }
-        }
-
-        return -1;
-    }
-
-    /** Clears out any existing lookup instances */
-    @VisibleForTesting
-    static void dispose() {
-        sInstance.clear();
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiPackage.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiPackage.java
deleted file mode 100644
index e233a21..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiPackage.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-/**
- * Represents a package and its classes
- */
-public class ApiPackage implements Comparable<ApiPackage> {
-    private final String mName;
-    private final List<ApiClass> mClasses = Lists.newArrayListWithExpectedSize(100);
-
-    // Persistence data: Used when writing out binary data in ApiLookup
-    int indexOffset;         // offset of the package entry
-
-    ApiPackage(@NonNull String name) {
-        mName = name;
-    }
-
-    /**
-     * Returns the name of the class (fully qualified name)
-     * @return the name of the class
-     */
-    @NonNull
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Returns the classes in this package
-     * @return the classes in this package
-     */
-    @NonNull
-    public List<ApiClass> getClasses() {
-        return mClasses;
-    }
-
-    void addClass(@NonNull ApiClass clz) {
-        mClasses.add(clz);
-    }
-
-    @Override
-    public int compareTo(@NonNull ApiPackage other) {
-        return mName.compareTo(other.mName);
-    }
-
-    @Override
-    public String toString() {
-        return mName;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiParser.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiParser.java
deleted file mode 100644
index 56a09bc..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiParser.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Parser for the simplified XML API format version 1.
- */
-public class ApiParser extends DefaultHandler {
-
-    private static final String NODE_API = "api";
-    private static final String NODE_CLASS = "class";
-    private static final String NODE_FIELD = "field";
-    private static final String NODE_METHOD = "method";
-    private static final String NODE_EXTENDS = "extends";
-    private static final String NODE_IMPLEMENTS = "implements";
-
-    private static final String ATTR_NAME = "name";
-    private static final String ATTR_SINCE = "since";
-    private static final String ATTR_DEPRECATED = "deprecated";
-
-    private final Map<String, ApiClass> mClasses = new HashMap<String, ApiClass>(1000);
-    private final Map<String, ApiPackage> mPackages = new HashMap<String, ApiPackage>();
-
-    private ApiClass mCurrentClass;
-
-    ApiParser() {
-    }
-
-    Map<String, ApiClass> getClasses() {
-        return mClasses;
-    }
-    Map<String, ApiPackage> getPackages() { return mPackages; }
-
-    @Override
-    public void startElement(String uri, String localName, String qName, Attributes attributes)
-            throws SAXException {
-
-        if (localName == null || localName.isEmpty()) {
-            localName = qName;
-        }
-
-        try {
-            //noinspection StatementWithEmptyBody
-            if (NODE_API.equals(localName)) {
-                // do nothing.
-            } else if (NODE_CLASS.equals(localName)) {
-                String name = attributes.getValue(ATTR_NAME);
-                int since = Integer.parseInt(attributes.getValue(ATTR_SINCE));
-
-                String deprecatedAttr = attributes.getValue(ATTR_DEPRECATED);
-                int deprecatedIn;
-                if (deprecatedAttr != null) {
-                    deprecatedIn = Integer.parseInt(deprecatedAttr);
-                } else {
-                    deprecatedIn = 0;
-                }
-                mCurrentClass = addClass(name, since, deprecatedIn);
-
-            } else if (NODE_EXTENDS.equals(localName)) {
-                String name = attributes.getValue(ATTR_NAME);
-                int since = getSince(attributes);
-
-                mCurrentClass.addSuperClass(name, since);
-
-            } else if (NODE_IMPLEMENTS.equals(localName)) {
-                String name = attributes.getValue(ATTR_NAME);
-                int since = getSince(attributes);
-
-                mCurrentClass.addInterface(name, since);
-
-            } else if (NODE_METHOD.equals(localName)) {
-                String name = attributes.getValue(ATTR_NAME);
-                int since = getSince(attributes);
-                int deprecatedIn = getDeprecatedIn(attributes);
-                mCurrentClass.addMethod(name, since, deprecatedIn);
-
-            } else if (NODE_FIELD.equals(localName)) {
-                String name = attributes.getValue(ATTR_NAME);
-                int since = getSince(attributes);
-                int deprecatedIn = getDeprecatedIn(attributes);
-
-                mCurrentClass.addField(name, since, deprecatedIn);
-
-            }
-
-        } finally {
-            super.startElement(uri, localName, qName, attributes);
-        }
-    }
-
-    private ApiClass addClass(String name, int apiLevel, int deprecatedIn) {
-        // There should not be any duplicates
-        ApiClass theClass = mClasses.get(name);
-        assert theClass == null;
-        theClass = new ApiClass(name, apiLevel, deprecatedIn);
-        mClasses.put(name, theClass);
-
-        String pkg = theClass.getPackage();
-        if (pkg != null) {
-            ApiPackage apiPackage = mPackages.get(pkg);
-            if (apiPackage == null) {
-                apiPackage = new ApiPackage(pkg);
-                mPackages.put(pkg, apiPackage);
-            }
-            apiPackage.addClass(theClass);
-        }
-
-        return theClass;
-    }
-
-    private int getSince(Attributes attributes) {
-        int since = mCurrentClass.getSince();
-        String sinceAttr = attributes.getValue(ATTR_SINCE);
-
-        if (sinceAttr != null) {
-            since = Integer.parseInt(sinceAttr);
-        }
-
-        return since;
-    }
-
-    private int getDeprecatedIn(Attributes attributes) {
-        int deprecatedIn = mCurrentClass.getDeprecatedIn();
-        String deprecatedAttr = attributes.getValue(ATTR_DEPRECATED);
-
-        if (deprecatedAttr != null) {
-            deprecatedIn = Integer.parseInt(deprecatedAttr);
-        }
-
-        return deprecatedIn;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppCompatCallDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppCompatCallDetector.java
deleted file mode 100644
index a02c873..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppCompatCallDetector.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT;
-import static com.android.SdkConstants.CLASS_ACTIVITY;
-import static com.android.tools.klint.detector.api.TextFormat.RAW;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.intellij.psi.PsiMethod;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class AppCompatCallDetector extends Detector implements Detector.UastScanner {
-    public static final Issue ISSUE = Issue.create(
-            "AppCompatMethod",
-            "Using Wrong AppCompat Method",
-            "When using the appcompat library, there are some methods you should be calling " +
-            "instead of the normal ones; for example, `getSupportActionBar()` instead of " +
-            "`getActionBar()`. This lint check looks for calls to the wrong method.",
-            Category.CORRECTNESS, 6, Severity.WARNING,
-            new Implementation(
-                    AppCompatCallDetector.class,
-                    Scope.JAVA_FILE_SCOPE)).
-            addMoreInfo("http://developer.android.com/tools/support-library/index.html");
-
-    private static final String GET_ACTION_BAR = "getActionBar";
-    private static final String START_ACTION_MODE = "startActionMode";
-    private static final String SET_PROGRESS_BAR_VIS = "setProgressBarVisibility";
-    private static final String SET_PROGRESS_BAR_IN_VIS = "setProgressBarIndeterminateVisibility";
-    private static final String SET_PROGRESS_BAR_INDETERMINATE = "setProgressBarIndeterminate";
-    private static final String REQUEST_WINDOW_FEATURE = "requestWindowFeature";
-    /** If you change number of parameters or order, update {@link #getMessagePart(String, int,TextFormat)} */
-    private static final String ERROR_MESSAGE_FORMAT = "Should use `%1$s` instead of `%2$s` name";
-
-    private boolean mDependsOnAppCompat;
-
-    public AppCompatCallDetector() {
-    }
-
-    @Override
-    public void beforeCheckProject(@NonNull Context context) {
-        Boolean dependsOnAppCompat = context.getProject().dependsOn(APPCOMPAT_LIB_ARTIFACT);
-        mDependsOnAppCompat = dependsOnAppCompat != null && dependsOnAppCompat;
-    }
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                GET_ACTION_BAR,
-                START_ACTION_MODE,
-                SET_PROGRESS_BAR_VIS,
-                SET_PROGRESS_BAR_IN_VIS,
-                SET_PROGRESS_BAR_INDETERMINATE,
-                REQUEST_WINDOW_FEATURE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        if (mDependsOnAppCompat && isAppBarActivityCall(context, node, method)) {
-            String name = method.getName();
-            String replace = null;
-            if (GET_ACTION_BAR.equals(name)) {
-                replace = "getSupportActionBar";
-            } else if (START_ACTION_MODE.equals(name)) {
-                replace = "startSupportActionMode";
-            } else if (SET_PROGRESS_BAR_VIS.equals(name)) {
-                replace = "setSupportProgressBarVisibility";
-            } else if (SET_PROGRESS_BAR_IN_VIS.equals(name)) {
-                replace = "setSupportProgressBarIndeterminateVisibility";
-            } else if (SET_PROGRESS_BAR_INDETERMINATE.equals(name)) {
-                replace = "setSupportProgressBarIndeterminate";
-            } else if (REQUEST_WINDOW_FEATURE.equals(name)) {
-                replace = "supportRequestWindowFeature";
-            }
-
-            if (replace != null) {
-                String message = String.format(ERROR_MESSAGE_FORMAT, replace, name);
-                context.report(ISSUE, node, context.getUastLocation(node), message);
-            }
-        }
-
-    }
-
-    private static boolean isAppBarActivityCall(@NonNull JavaContext context,
-            @NonNull UCallExpression node, @NonNull PsiMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isMemberInSubClassOf(method, CLASS_ACTIVITY, false)) {
-            // Make sure that the calling context is a subclass of ActionBarActivity;
-            // we don't want to flag these calls if they are in non-appcompat activities
-            // such as PreferenceActivity (see b.android.com/58512)
-            UClass cls = UastUtils.getParentOfType(node, UClass.class, true);
-            return cls != null && InheritanceUtil.isInheritor(
-                    cls, false, "android.support.v7.app.ActionBarActivity");
-        }
-        return false;
-    }
-
-    /**
-     * Given an error message created by this lint check, return the corresponding old method name
-     * that it suggests should be deleted. (Intended to support quickfix implementations
-     * for this lint check.)
-     *
-     * @param errorMessage the error message originally produced by this detector
-     * @param format the format of the error message
-     * @return the corresponding old method name, or null if not recognized
-     */
-    @Nullable
-    public static String getOldCall(@NonNull String errorMessage, @NonNull TextFormat format) {
-        return getMessagePart(errorMessage, 2, format);
-    }
-
-    /**
-     * Given an error message created by this lint check, return the corresponding new method name
-     * that it suggests replace the old method name. (Intended to support quickfix implementations
-     * for this lint check.)
-     *
-     * @param errorMessage the error message originally produced by this detector
-     * @param format the format of the error message
-     * @return the corresponding new method name, or null if not recognized
-     */
-    @Nullable
-    public static String getNewCall(@NonNull String errorMessage, @NonNull TextFormat format) {
-        return getMessagePart(errorMessage, 1, format);
-    }
-
-    @Nullable
-    private static String getMessagePart(@NonNull String errorMessage, int group,
-            @NonNull TextFormat format) {
-        List<String> parameters = LintUtils.getFormattedParameters(
-                RAW.convertTo(ERROR_MESSAGE_FORMAT, format),
-                errorMessage);
-        if (parameters.size() == 2 && group <= 2) {
-            return parameters.get(group - 1);
-        }
-
-        return null;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppIndexingApiDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppIndexingApiDetector.java
deleted file mode 100644
index 5989552..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AppIndexingApiDetector.java
+++ /dev/null
@@ -1,744 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_EXPORTED;
-import static com.android.SdkConstants.ATTR_HOST;
-import static com.android.SdkConstants.ATTR_PATH;
-import static com.android.SdkConstants.ATTR_PATH_PREFIX;
-import static com.android.SdkConstants.ATTR_SCHEME;
-import static com.android.SdkConstants.CLASS_ACTIVITY;
-import static com.android.xml.AndroidManifest.ATTRIBUTE_MIME_TYPE;
-import static com.android.xml.AndroidManifest.ATTRIBUTE_NAME;
-import static com.android.xml.AndroidManifest.ATTRIBUTE_PORT;
-import static com.android.xml.AndroidManifest.NODE_ACTION;
-import static com.android.xml.AndroidManifest.NODE_ACTIVITY;
-import static com.android.xml.AndroidManifest.NODE_APPLICATION;
-import static com.android.xml.AndroidManifest.NODE_CATEGORY;
-import static com.android.xml.AndroidManifest.NODE_DATA;
-import static com.android.xml.AndroidManifest.NODE_INTENT;
-import static com.android.xml.AndroidManifest.NODE_MANIFEST;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceUrl;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.XmlParser;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-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 java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-
-/**
- * Check if the usage of App Indexing is correct.
- */
-public class AppIndexingApiDetector extends Detector implements XmlScanner, Detector.UastScanner {
-
-    private static final Implementation URL_IMPLEMENTATION = new Implementation(
-            AppIndexingApiDetector.class, Scope.MANIFEST_SCOPE);
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation APP_INDEXING_API_IMPLEMENTATION =
-            new Implementation(
-                    AppIndexingApiDetector.class,
-                    EnumSet.of(Scope.JAVA_FILE, Scope.MANIFEST),
-                    Scope.JAVA_FILE_SCOPE, Scope.MANIFEST_SCOPE);
-
-    public static final Issue ISSUE_URL_ERROR = Issue.create(
-            "GoogleAppIndexingUrlError", //$NON-NLS-1$
-            "URL not supported by app for Google App Indexing",
-            "Ensure the URL is supported by your app, to get installs and traffic to your"
-                    + " app from Google Search.",
-            Category.USABILITY, 5, Severity.ERROR, URL_IMPLEMENTATION)
-            .addMoreInfo("https://g.co/AppIndexing/AndroidStudio");
-
-    public static final Issue ISSUE_APP_INDEXING =
-      Issue.create(
-        "GoogleAppIndexingWarning", //$NON-NLS-1$
-        "Missing support for Google App Indexing",
-        "Adds URLs to get your app into the Google index, to get installs"
-          + " and traffic to your app from Google Search.",
-        Category.USABILITY, 5, Severity.WARNING, URL_IMPLEMENTATION)
-        .addMoreInfo("https://g.co/AppIndexing/AndroidStudio");
-
-    public static final Issue ISSUE_APP_INDEXING_API =
-            Issue.create(
-                    "GoogleAppIndexingApiWarning", //$NON-NLS-1$
-                    "Missing support for Google App Indexing Api",
-                    "Adds URLs to get your app into the Google index, to get installs"
-                            + " and traffic to your app from Google Search.",
-                    Category.USABILITY, 5, Severity.WARNING, APP_INDEXING_API_IMPLEMENTATION)
-                    .addMoreInfo("https://g.co/AppIndexing/AndroidStudio")
-                    .setEnabledByDefault(false);
-
-    private static final String[] PATH_ATTR_LIST = new String[]{ATTR_PATH_PREFIX, ATTR_PATH};
-    private static final String SCHEME_MISSING = "android:scheme is missing";
-    private static final String HOST_MISSING = "android:host is missing";
-    private static final String DATA_MISSING = "Missing data element";
-    private static final String URL_MISSING = "Missing URL for the intent filter";
-    private static final String NOT_BROWSABLE
-            = "Activity supporting ACTION_VIEW is not set as BROWSABLE";
-    private static final String ILLEGAL_NUMBER = "android:port is not a legal number";
-
-    private static final String APP_INDEX_START = "start"; //$NON-NLS-1$
-    private static final String APP_INDEX_END = "end"; //$NON-NLS-1$
-    private static final String APP_INDEX_VIEW = "view"; //$NON-NLS-1$
-    private static final String APP_INDEX_VIEW_END = "viewEnd"; //$NON-NLS-1$
-    private static final String CLIENT_CONNECT = "connect"; //$NON-NLS-1$
-    private static final String CLIENT_DISCONNECT = "disconnect"; //$NON-NLS-1$
-    private static final String ADD_API = "addApi"; //$NON-NLS-1$
-
-    private static final String APP_INDEXING_API_CLASS
-            = "com.google.android.gms.appindexing.AppIndexApi";
-    private static final String GOOGLE_API_CLIENT_CLASS
-            = "com.google.android.gms.common.api.GoogleApiClient";
-    private static final String GOOGLE_API_CLIENT_BUILDER_CLASS
-            = "com.google.android.gms.common.api.GoogleApiClient.Builder";
-    private static final String API_CLASS = "com.google.android.gms.appindexing.AppIndex";
-
-    public enum IssueType {
-        SCHEME_MISSING(AppIndexingApiDetector.SCHEME_MISSING),
-        HOST_MISSING(AppIndexingApiDetector.HOST_MISSING),
-        DATA_MISSING(AppIndexingApiDetector.DATA_MISSING),
-        URL_MISSING(AppIndexingApiDetector.URL_MISSING),
-        NOT_BROWSABLE(AppIndexingApiDetector.NOT_BROWSABLE),
-        ILLEGAL_NUMBER(AppIndexingApiDetector.ILLEGAL_NUMBER),
-        EMPTY_FIELD("cannot be empty"),
-        MISSING_SLASH("attribute should start with '/'"),
-        UNKNOWN("unknown error type");
-
-        private final String message;
-
-        IssueType(String str) {
-            this.message = str;
-        }
-
-        public static IssueType parse(String str) {
-            for (IssueType type : IssueType.values()) {
-                if (str.contains(type.message)) {
-                    return type;
-                }
-            }
-            return UNKNOWN;
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-    @Override
-    @Nullable
-    public Collection<String> getApplicableElements() {
-        return Collections.singletonList(NODE_APPLICATION);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element application) {
-        List<Element> activities = extractChildrenByName(application, NODE_ACTIVITY);
-        boolean applicationHasActionView = false;
-        for (Element activity : activities) {
-            List<Element> intents = extractChildrenByName(activity, NODE_INTENT);
-            boolean activityHasActionView = false;
-            for (Element intent : intents) {
-                boolean actionView = hasActionView(intent);
-                if (actionView) {
-                    activityHasActionView = true;
-                }
-                visitIntent(context, intent);
-            }
-            if (activityHasActionView) {
-                applicationHasActionView = true;
-                if (activity.hasAttributeNS(ANDROID_URI, ATTR_EXPORTED)) {
-                    Attr exported = activity.getAttributeNodeNS(ANDROID_URI, ATTR_EXPORTED);
-                    if (!exported.getValue().equals("true")) {
-                        // Report error if the activity supporting action view is not exported.
-                        context.report(ISSUE_URL_ERROR, activity,
-                                       context.getLocation(activity),
-                                       "Activity supporting ACTION_VIEW is not exported");
-                    }
-                }
-            }
-        }
-        if (!applicationHasActionView && !context.getProject().isLibrary()) {
-            // Report warning if there is no activity that supports action view.
-            context.report(ISSUE_APP_INDEXING, application, context.getLocation(application),
-                           // This error message is more verbose than the other app indexing lint warnings, because it
-                           // shows up on a blank project, and we want to make it obvious by just looking at the error
-                           // message what this is
-                           "App is not indexable by Google Search; consider adding at least one Activity with an ACTION-VIEW " +
-                           "intent filter. See issue explanation for more details.");
-        }
-    }
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(CLASS_ACTIVITY);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        if (declaration.getName() == null) {
-            return;
-        }
-
-        // In case linting the base class itself.
-        if (!InheritanceUtil.isInheritor(declaration, true, CLASS_ACTIVITY)) {
-            return;
-        }
-
-        declaration.accept(new MethodVisitor(context, declaration));
-    }
-
-    static class MethodVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-        private final UClass mCls;
-
-        private final List<UCallExpression> mStartMethods;
-        private final List<UCallExpression> mEndMethods;
-        private final List<UCallExpression> mConnectMethods;
-        private final List<UCallExpression> mDisconnectMethods;
-        private boolean mHasAddAppIndexApi;
-
-        private MethodVisitor(JavaContext context, UClass cls) {
-            mCls = cls;
-            mContext = context;
-            mStartMethods = Lists.newArrayListWithExpectedSize(2);
-            mEndMethods = Lists.newArrayListWithExpectedSize(2);
-            mConnectMethods = Lists.newArrayListWithExpectedSize(2);
-            mDisconnectMethods = Lists.newArrayListWithExpectedSize(2);
-        }
-
-        @Override
-        public boolean visitClass(UClass aClass) {
-            if (aClass.getPsi().equals(mCls.getPsi())) {
-                return super.visitClass(aClass);
-            } else {
-                // Don't go into inner classes
-                return true;
-            }
-        }
-
-        @Override
-        public void afterVisitClass(UClass node) {
-            report();
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (UastExpressionUtils.isMethodCall(node)) {
-                visitMethodCallExpression(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void visitMethodCallExpression(UCallExpression node) {
-            String methodName = node.getMethodName();
-            if (methodName == null) {
-                return;
-            }
-
-            if (methodName.equals(APP_INDEX_START)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), APP_INDEXING_API_CLASS)) {
-                    mStartMethods.add(node);
-                }
-            }
-            else if (methodName.equals(APP_INDEX_END)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), APP_INDEXING_API_CLASS)) {
-                    mEndMethods.add(node);
-                }
-            }
-            else if (methodName.equals(APP_INDEX_VIEW)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), APP_INDEXING_API_CLASS)) {
-                    mStartMethods.add(node);
-                }
-            }
-            else if (methodName.equals(APP_INDEX_VIEW_END)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), APP_INDEXING_API_CLASS)) {
-                    mEndMethods.add(node);
-                }
-            }
-            else if (methodName.equals(CLIENT_CONNECT)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), GOOGLE_API_CLIENT_CLASS)) {
-                    mConnectMethods.add(node);
-                }
-            }
-            else if (methodName.equals(CLIENT_DISCONNECT)) {
-                if (JavaEvaluator.isMemberInClass(node.resolve(), GOOGLE_API_CLIENT_CLASS)) {
-                    mDisconnectMethods.add(node);
-                }
-            }
-            else if (methodName.equals(ADD_API)) {
-                if (JavaEvaluator
-                        .isMemberInClass(node.resolve(), GOOGLE_API_CLIENT_BUILDER_CLASS)) {
-                    List<UExpression> args = node.getValueArguments();
-                    if (!args.isEmpty()) {
-                        PsiElement resolved = UastUtils.tryResolve(args.get(0));
-                        if (resolved instanceof PsiField &&
-                            JavaEvaluator.isMemberInClass((PsiField) resolved, API_CLASS)) {
-                            mHasAddAppIndexApi = true;
-                        }
-                    }
-                }
-            }
-        }
-
-        private void report() {
-            // finds the activity classes that need app activity annotation
-            Set<String> activitiesToCheck = getActivitiesToCheck(mContext);
-
-            // app indexing API used but no support in manifest
-            boolean hasIntent = activitiesToCheck.contains(mCls.getQualifiedName());
-            if (!hasIntent) {
-                for (UCallExpression call : mStartMethods) {
-                    mContext.report(ISSUE_APP_INDEXING_API, call,
-                            mContext.getUastNameLocation(call),
-                            "Missing support for Google App Indexing in the manifest");
-                }
-                for (UCallExpression call : mEndMethods) {
-                    mContext.report(ISSUE_APP_INDEXING_API, call,
-                            mContext.getUastNameLocation(call),
-                            "Missing support for Google App Indexing in the manifest");
-                }
-                return;
-            }
-
-            // `AppIndex.AppIndexApi.start / end / view / viewEnd` should exist
-            if (mStartMethods.isEmpty() && mEndMethods.isEmpty()) {
-                mContext.reportUast(ISSUE_APP_INDEXING_API, mCls,
-                        mContext.getUastNameLocation(mCls),
-                        "Missing support for Google App Indexing API");
-                return;
-            }
-
-            for (UCallExpression startNode : mStartMethods) {
-                List<UExpression> expressions = startNode.getValueArguments();
-                if (expressions.isEmpty()) {
-                    continue;
-                }
-                UExpression startClient = expressions.get(0);
-
-                // GoogleApiClient should `addApi(AppIndex.APP_INDEX_API)`
-                if (!mHasAddAppIndexApi) {
-                    String message = String.format(
-                            "GoogleApiClient `%1$s` has not added support for App Indexing API",
-                            startClient.asSourceString());
-                    mContext.report(ISSUE_APP_INDEXING_API, startClient,
-                                    mContext.getUastLocation(startClient), message);
-                }
-
-                // GoogleApiClient `connect` should exist
-                if (!hasOperand(startClient, mConnectMethods)) {
-                    String message = String.format("GoogleApiClient `%1$s` is not connected",
-                                    startClient.asSourceString());
-                    mContext.report(ISSUE_APP_INDEXING_API, startClient,
-                                    mContext.getUastLocation(startClient), message);
-                }
-
-                // `AppIndex.AppIndexApi.end` should pair with `AppIndex.AppIndexApi.start`
-                if (!hasFirstArgument(startClient, mEndMethods)) {
-                    mContext.report(ISSUE_APP_INDEXING_API, startNode,
-                            mContext.getUastNameLocation(startNode),
-                            "Missing corresponding `AppIndex.AppIndexApi.end` method");
-                }
-            }
-
-            for (UCallExpression endNode : mEndMethods) {
-                List<UExpression> expressions = endNode.getValueArguments();
-                if (expressions.isEmpty()) {
-                    continue;
-                }
-                UExpression endClient = expressions.get(0);
-
-                // GoogleApiClient should `addApi(AppIndex.APP_INDEX_API)`
-                if (!mHasAddAppIndexApi) {
-                    String message = String.format(
-                            "GoogleApiClient `%1$s` has not added support for App Indexing API",
-                            endClient.asSourceString());
-                    mContext.report(ISSUE_APP_INDEXING_API, endClient,
-                                    mContext.getUastLocation(endClient), message);
-                }
-
-                // GoogleApiClient `disconnect` should exist
-                if (!hasOperand(endClient, mDisconnectMethods)) {
-                    String message = String.format("GoogleApiClient `%1$s`"
-                            + " is not disconnected", endClient.asSourceString());
-                    mContext.report(ISSUE_APP_INDEXING_API, endClient,
-                                    mContext.getUastLocation(endClient), message);
-                }
-
-                // `AppIndex.AppIndexApi.start` should pair with `AppIndex.AppIndexApi.end`
-                if (!hasFirstArgument(endClient, mStartMethods)) {
-                    mContext.report(ISSUE_APP_INDEXING_API, endNode,
-                            mContext.getUastNameLocation(endNode),
-                            "Missing corresponding `AppIndex.AppIndexApi.start` method");
-                }
-            }
-        }
-    }
-
-    /**
-     * Gets names of activities which needs app indexing. i.e. the activities have data tag in their
-     * intent filters.
-     * TODO: Cache the activities to speed up batch lint.
-     *
-     * @param context The context to check in.
-     */
-    private static Set<String> getActivitiesToCheck(Context context) {
-        Set<String> activitiesToCheck = Sets.newHashSet();
-        List<File> manifestFiles = context.getProject().getManifestFiles();
-        XmlParser xmlParser = context.getDriver().getClient().getXmlParser();
-        if (xmlParser != null) {
-            // TODO: Avoid visit all manifest files before enable this check by default.
-            for (File manifest : manifestFiles) {
-                XmlContext xmlContext =
-                        new XmlContext(context.getDriver(), context.getProject(),
-                                null, manifest, null, xmlParser);
-                Document doc = xmlParser.parseXml(xmlContext);
-                if (doc != null) {
-                    List<Element> children = LintUtils.getChildren(doc);
-                    for (Element child : children) {
-                        if (child.getNodeName().equals(NODE_MANIFEST)) {
-                            List<Element> apps = extractChildrenByName(child, NODE_APPLICATION);
-                            for (Element app : apps) {
-                                List<Element> acts = extractChildrenByName(app, NODE_ACTIVITY);
-                                for (Element act : acts) {
-                                    List<Element> intents = extractChildrenByName(act, NODE_INTENT);
-                                    for (Element intent : intents) {
-                                        List<Element> data = extractChildrenByName(intent,
-                                                NODE_DATA);
-                                        if (!data.isEmpty() && act.hasAttributeNS(
-                                                ANDROID_URI, ATTRIBUTE_NAME)) {
-                                            Attr attr = act.getAttributeNodeNS(
-                                                    ANDROID_URI, ATTRIBUTE_NAME);
-                                            String activityName = attr.getValue();
-                                            int dotIndex = activityName.indexOf('.');
-                                            if (dotIndex <= 0) {
-                                                String pkg = context.getMainProject().getPackage();
-                                                if (pkg != null) {
-                                                    if (dotIndex == 0) {
-                                                        activityName = pkg + activityName;
-                                                    }
-                                                    else {
-                                                        activityName = pkg + '.' + activityName;
-                                                    }
-                                                }
-                                            }
-                                            activitiesToCheck.add(activityName);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return activitiesToCheck;
-    }
-
-    private static void visitIntent(@NonNull XmlContext context, @NonNull Element intent) {
-        boolean actionView = hasActionView(intent);
-        boolean browsable = isBrowsable(intent);
-        boolean isHttp = false;
-        boolean hasScheme = false;
-        boolean hasHost = false;
-        boolean hasPort = false;
-        boolean hasPath = false;
-        boolean hasMimeType = false;
-        Element firstData = null;
-        List<Element> children = extractChildrenByName(intent, NODE_DATA);
-        for (Element data : children) {
-            if (firstData == null) {
-                firstData = data;
-            }
-            if (isHttpSchema(data)) {
-                isHttp = true;
-            }
-            checkSingleData(context, data);
-
-            for (String name : PATH_ATTR_LIST) {
-                if (data.hasAttributeNS(ANDROID_URI, name)) {
-                    hasPath = true;
-                }
-            }
-
-            if (data.hasAttributeNS(ANDROID_URI, ATTR_SCHEME)) {
-                hasScheme = true;
-            }
-
-            if (data.hasAttributeNS(ANDROID_URI, ATTR_HOST)) {
-                hasHost = true;
-            }
-
-            if (data.hasAttributeNS(ANDROID_URI, ATTRIBUTE_PORT)) {
-                hasPort = true;
-            }
-
-            if (data.hasAttributeNS(ANDROID_URI, ATTRIBUTE_MIME_TYPE)) {
-                hasMimeType = true;
-            }
-        }
-
-        // In data field, a URL is consisted by
-        // <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
-        // Each part of the URL should not have illegal character.
-        if ((hasPath || hasHost || hasPort) && !hasScheme) {
-            context.report(ISSUE_URL_ERROR, firstData, context.getLocation(firstData),
-                    SCHEME_MISSING);
-        }
-
-        if ((hasPath || hasPort) && !hasHost) {
-            context.report(ISSUE_URL_ERROR, firstData, context.getLocation(firstData),
-                    HOST_MISSING);
-        }
-
-        if (actionView && browsable) {
-            if (firstData == null) {
-                // If this activity is an ACTION_VIEW action with category BROWSABLE, but doesn't
-                // have data node, it may be a mistake and we will report error.
-                context.report(ISSUE_URL_ERROR, intent, context.getLocation(intent),
-                        DATA_MISSING);
-            } else if (!hasScheme && !hasMimeType) {
-                // If this activity is an action view, is browsable, but has neither a
-                // URL nor mimeType, it may be a mistake and we will report error.
-                context.report(ISSUE_URL_ERROR, firstData, context.getLocation(firstData),
-                        URL_MISSING);
-            }
-        }
-
-        // If this activity is an ACTION_VIEW action, has a http URL but doesn't have
-        // BROWSABLE, it may be a mistake and and we will report warning.
-        if (actionView && isHttp && !browsable) {
-            context.report(ISSUE_APP_INDEXING, intent, context.getLocation(intent),
-                    NOT_BROWSABLE);
-        }
-
-        if (actionView && !hasScheme) {
-            context.report(ISSUE_APP_INDEXING, intent, context.getLocation(intent),
-                    "Missing URL");
-        }
-    }
-
-    /**
-     * Check if the intent filter supports action view.
-     *
-     * @param intent the intent filter
-     * @return true if it does
-     */
-    private static boolean hasActionView(@NonNull Element intent) {
-        List<Element> children = extractChildrenByName(intent, NODE_ACTION);
-        for (Element action : children) {
-            if (action.hasAttributeNS(ANDROID_URI, ATTRIBUTE_NAME)) {
-                Attr attr = action.getAttributeNodeNS(ANDROID_URI, ATTRIBUTE_NAME);
-                if (attr.getValue().equals("android.intent.action.VIEW")) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if the intent filter is browsable.
-     *
-     * @param intent the intent filter
-     * @return true if it does
-     */
-    private static boolean isBrowsable(@NonNull Element intent) {
-        List<Element> children = extractChildrenByName(intent, NODE_CATEGORY);
-        for (Element e : children) {
-            if (e.hasAttributeNS(ANDROID_URI, ATTRIBUTE_NAME)) {
-                Attr attr = e.getAttributeNodeNS(ANDROID_URI, ATTRIBUTE_NAME);
-                if (attr.getNodeValue().equals("android.intent.category.BROWSABLE")) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if the data node contains http schema
-     *
-     * @param data the data node
-     * @return true if it does
-     */
-    private static boolean isHttpSchema(@NonNull Element data) {
-        if (data.hasAttributeNS(ANDROID_URI, ATTR_SCHEME)) {
-            String value = data.getAttributeNodeNS(ANDROID_URI, ATTR_SCHEME).getValue();
-            if (value.equalsIgnoreCase("http") || value.equalsIgnoreCase("https")) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static void checkSingleData(@NonNull XmlContext context, @NonNull Element data) {
-        // path, pathPrefix and pathPattern should starts with /.
-        for (String name : PATH_ATTR_LIST) {
-            if (data.hasAttributeNS(ANDROID_URI, name)) {
-                Attr attr = data.getAttributeNodeNS(ANDROID_URI, name);
-                String path = replaceUrlWithValue(context, attr.getValue());
-                if (!path.startsWith("/") && !path.startsWith(SdkConstants.PREFIX_RESOURCE_REF)) {
-                    context.report(ISSUE_URL_ERROR, attr, context.getLocation(attr),
-                            "android:" + name + " attribute should start with '/', but it is : "
-                                    + path);
-                }
-            }
-        }
-
-        // port should be a legal number.
-        if (data.hasAttributeNS(ANDROID_URI, ATTRIBUTE_PORT)) {
-            Attr attr = data.getAttributeNodeNS(ANDROID_URI, ATTRIBUTE_PORT);
-            try {
-                String port = replaceUrlWithValue(context, attr.getValue());
-                //noinspection ResultOfMethodCallIgnored
-                Integer.parseInt(port);
-            } catch (NumberFormatException e) {
-                context.report(ISSUE_URL_ERROR, attr, context.getLocation(attr),
-                        ILLEGAL_NUMBER);
-            }
-        }
-
-        // Each field should be non empty.
-        NamedNodeMap attrs = data.getAttributes();
-        for (int i = 0; i < attrs.getLength(); i++) {
-            Node item = attrs.item(i);
-            if (item.getNodeType() == Node.ATTRIBUTE_NODE) {
-                Attr attr = (Attr) attrs.item(i);
-                if (attr.getValue().isEmpty()) {
-                    context.report(ISSUE_URL_ERROR, attr, context.getLocation(attr),
-                            attr.getName() + " cannot be empty");
-                }
-            }
-        }
-    }
-
-    private static String replaceUrlWithValue(@NonNull XmlContext context,
-            @NonNull String str) {
-        Project project = context.getProject();
-        LintClient client = context.getClient();
-        if (!client.supportsProjectResources()) {
-            return str;
-        }
-        ResourceUrl style = ResourceUrl.parse(str);
-        if (style == null || style.type != ResourceType.STRING || style.framework) {
-            return str;
-        }
-        AbstractResourceRepository resources = client.getProjectResources(project, true);
-        if (resources == null) {
-            return str;
-        }
-        List<ResourceItem> items = resources.getResourceItem(ResourceType.STRING, style.name);
-        if (items == null || items.isEmpty()) {
-            return str;
-        }
-        ResourceValue resourceValue = items.get(0).getResourceValue(false);
-        if (resourceValue == null) {
-            return str;
-        }
-        return resourceValue.getValue() == null ? str : resourceValue.getValue();
-    }
-
-    /**
-     * If a method with a certain argument exists in the list of methods.
-     *
-     * @param argument The first argument of the method.
-     * @param list     The methods list.
-     * @return If such a method exists in the list.
-     */
-    private static boolean hasFirstArgument(UExpression argument, List<UCallExpression> list) {
-        for (UCallExpression call : list) {
-            List<UExpression> expressions = call.getValueArguments();
-            if (!expressions.isEmpty()) {
-                UExpression argument2 = expressions.get(0);
-                if (argument.asSourceString().equals(argument2.asSourceString())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * If a method with a certain operand exists in the list of methods.
-     *
-     * @param operand The operand of the method.
-     * @param list    The methods list.
-     * @return If such a method exists in the list.
-     */
-    private static boolean hasOperand(UExpression operand, List<UCallExpression> list) {
-        for (UCallExpression method : list) {
-            UElement operand2 = method.getReceiver();
-            if (operand2 != null && operand.asSourceString().equals(operand2.asSourceString())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static List<Element> extractChildrenByName(@NonNull Element node,
-            @NonNull String name) {
-        List<Element> result = Lists.newArrayList();
-        List<Element> children = LintUtils.getChildren(node);
-        for (Element child : children) {
-            if (child.getNodeName().equals(name)) {
-                result.add(child);
-            }
-        }
-        return result;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BadHostnameVerifierDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BadHostnameVerifierDetector.java
deleted file mode 100644
index cc6a6c5..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BadHostnameVerifierDetector.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.JavaRecursiveElementVisitor;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiReturnStatement;
-import com.intellij.psi.PsiThrowStatement;
-
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-public class BadHostnameVerifierDetector extends Detector implements Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION =
-            new Implementation(BadHostnameVerifierDetector.class,
-                    Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue ISSUE = Issue.create("BadHostnameVerifier",
-            "Insecure HostnameVerifier",
-            "This check looks for implementations of `HostnameVerifier` " +
-            "whose `verify` method always returns true (thus trusting any hostname) " +
-            "which could result in insecure network traffic caused by trusting arbitrary " +
-            "hostnames in TLS/SSL certificates presented by peers.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList("javax.net.ssl.HostnameVerifier");
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        for (PsiMethod method : declaration.findMethodsByName("verify", false)) {
-            if (evaluator.methodMatches(method, null, false,
-                    TYPE_STRING, "javax.net.ssl.SSLSession")) {
-                ComplexVisitor visitor = new ComplexVisitor(context);
-                declaration.accept(visitor);
-                if (visitor.isComplex()) {
-                    return;
-                }
-
-                Location location = context.getNameLocation(method);
-                String message = String.format("`%1$s` always returns `true`, which " +
-                                "could cause insecure network traffic due to trusting "
-                                + "TLS/SSL server certificates for wrong hostnames",
-                        method.getName());
-                context.report(ISSUE, location, message);
-                break;
-            }
-        }
-    }
-
-    private static class ComplexVisitor extends AbstractUastVisitor {
-        @SuppressWarnings("unused")
-        private final JavaContext mContext;
-        private boolean mComplex;
-
-        public ComplexVisitor(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitThrowExpression(UThrowExpression node) {
-            mComplex = true;
-            return super.visitThrowExpression(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            // TODO: Ignore certain known safe methods, e.g. Logging etc
-            mComplex = true;
-            return super.visitCallExpression(node);
-        }
-
-        @Override
-        public boolean visitReturnExpression(UReturnExpression node) {
-            UExpression argument = node.getReturnExpression();
-            if (argument != null) {
-                // TODO: Only do this if certain that there isn't some intermediate
-                // assignment, as exposed by the unit test
-                //Object value = ConstantEvaluator.evaluate(mContext, argument);
-                //if (Boolean.TRUE.equals(value)) {
-                if (UastLiteralUtils.isTrueLiteral(argument)) {
-                    mComplex = false;
-                } else {
-                    mComplex = true; // "return false" or some complicated logic
-                }
-            }
-            return super.visitReturnExpression(node);
-        }
-
-        private boolean isComplex() {
-            return mComplex;
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BatteryDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BatteryDetector.java
deleted file mode 100644
index 7853317..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BatteryDetector.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.*;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-
-import static com.android.SdkConstants.*;
-
-/**
- * Checks looking for issues that negatively affect battery life
- */
-public class BatteryDetector extends ResourceXmlDetector implements
-        Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    public static final Implementation IMPLEMENTATION = new Implementation(
-            BatteryDetector.class,
-            EnumSet.of(Scope.MANIFEST, Scope.JAVA_FILE),
-            Scope.MANIFEST_SCOPE,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Issues that negatively affect battery life */
-    public static final Issue ISSUE = Issue.create(
-            "BatteryLife", //$NON-NLS-1$
-            "Battery Life Issues",
-
-            "This issue flags code that either\n" +
-            "* negatively affects battery life, or\n" +
-            "* uses APIs that have recently changed behavior to prevent background tasks " +
-            "from consuming memory and battery excessively.\n" +
-            "\n" +
-            "Generally, you should be using `JobScheduler` or `GcmNetworkManager` instead.\n" +
-            "\n" +
-            "For more details on how to update your code, please see" +
-            "http://developer.android.com/preview/features/background-optimization.html",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo("http://developer.android.com/preview/features/background-optimization.html");
-
-    /** Constructs a new {@link BatteryDetector} */
-    public BatteryDetector() {
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Collections.singletonList("action");
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        assert element.getTagName().equals("action");
-        Attr attr = element.getAttributeNodeNS(ANDROID_URI, ATTR_NAME);
-        if (attr == null) {
-            return;
-        }
-        String name = attr.getValue();
-        if ("android.net.conn.CONNECTIVITY_CHANGE".equals(name)
-                && element.getParentNode() != null
-                && element.getParentNode().getParentNode() != null
-                && TAG_RECEIVER.equals(element.getParentNode().getParentNode().getNodeName())
-                && context.getMainProject().getTargetSdkVersion().getFeatureLevel() >= 24) {
-            String message = "Declaring a broadcastreceiver for "
-                + "`android.net.conn.CONNECTIVITY_CHANGE` is deprecated for apps targeting "
-                + "N and higher. In general, apps should not rely on this broadcast and "
-                + "instead use `JobScheduler` or `GCMNetworkManager`.";
-            context.report(ISSUE, element, context.getValueLocation(attr), message);
-        }
-
-        if ("android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS".equals(name)
-                && context.getMainProject().getTargetSdkVersion().getFeatureLevel() >= 23) {
-            String message = getBatteryOptimizationsErrorMessage();
-            context.report(ISSUE, element, context.getValueLocation(attr), message);
-        }
-
-        if ("android.hardware.action.NEW_PICTURE".equals(name)
-                || "android.hardware.action.NEW_VIDEO".equals(name)
-                || "com.android.camera.NEW_PICTURE".equals(name)) {
-            String message = String.format("Use of %1$s is deprecated for all apps starting "
-                    + "with the N release independent of the target SDK. Apps should not "
-                    + "rely on these broadcasts and instead use `JobScheduler`", name);
-            context.report(ISSUE, element, context.getValueLocation(attr), message);
-        }
-    }
-
-    @Nullable
-    @Override
-    public List<String> getApplicableReferenceNames() {
-        return Collections.singletonList("ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS");
-    }
-
-    @Override
-    public void visitReference(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UReferenceExpression reference, @NonNull PsiElement resolved) {
-        if (resolved instanceof PsiField &&
-                context.getEvaluator().isMemberInSubClassOf((PsiField) resolved,
-                        "android.provider.Settings", false)
-                && context.getMainProject().getTargetSdkVersion().getFeatureLevel() >= 23) {
-            String message = getBatteryOptimizationsErrorMessage();
-            context.report(ISSUE, reference, context.getUastNameLocation(reference), message);
-        }
-    }
-
-    @NonNull
-    private static String getBatteryOptimizationsErrorMessage() {
-        return "Use of `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` violates the "
-                + "Play Store Content Policy regarding acceptable use cases, as described in "
-                + "http://developer.android.com/training/monitoring-device-state/doze-standby.html";
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BuiltinIssueRegistry.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BuiltinIssueRegistry.java
deleted file mode 100644
index 3990ffa..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/BuiltinIssueRegistry.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.client.api.IssueRegistry;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Scope;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-
-/** Registry which provides a list of checks to be performed on an Android project */
-public class BuiltinIssueRegistry extends IssueRegistry {
-    private static final List<Issue> sIssues;
-
-    static final int INITIAL_CAPACITY = 262;
-
-    static {
-        List<Issue> issues = new ArrayList<Issue>(INITIAL_CAPACITY);
-
-        issues.add(AddJavascriptInterfaceDetector.ISSUE);
-        issues.add(AlarmDetector.ISSUE);
-        issues.add(AllowAllHostnameVerifierDetector.ISSUE);
-        issues.add(AlwaysShowActionDetector.ISSUE);
-        issues.add(AndroidAutoDetector.INVALID_USES_TAG_ISSUE);
-        issues.add(AndroidAutoDetector.MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH);
-        issues.add(AndroidAutoDetector.MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE);
-        issues.add(AndroidAutoDetector.MISSING_ON_PLAY_FROM_SEARCH);
-        issues.add(AnnotationDetector.ANNOTATION_USAGE);
-        issues.add(AnnotationDetector.FLAG_STYLE);
-        issues.add(AnnotationDetector.INSIDE_METHOD);
-        issues.add(AnnotationDetector.SWITCH_TYPE_DEF);
-        issues.add(AnnotationDetector.UNIQUE);
-        issues.add(ApiDetector.INLINED);
-        issues.add(ApiDetector.OVERRIDE);
-        issues.add(ApiDetector.UNSUPPORTED);
-        issues.add(ApiDetector.UNUSED);
-        issues.add(AppCompatCallDetector.ISSUE);
-        issues.add(AppIndexingApiDetector.ISSUE_APP_INDEXING_API);
-        issues.add(AppIndexingApiDetector.ISSUE_URL_ERROR);
-        issues.add(AppIndexingApiDetector.ISSUE_APP_INDEXING);
-        issues.add(BadHostnameVerifierDetector.ISSUE);
-        issues.add(BatteryDetector.ISSUE);
-        issues.add(CallSuperDetector.ISSUE);
-        issues.add(CipherGetInstanceDetector.ISSUE);
-        issues.add(CleanupDetector.COMMIT_FRAGMENT);
-        issues.add(CleanupDetector.RECYCLE_RESOURCE);
-        issues.add(CleanupDetector.SHARED_PREF);
-        issues.add(CommentDetector.EASTER_EGG);
-        issues.add(CommentDetector.STOP_SHIP);
-        issues.add(CustomViewDetector.ISSUE);
-        issues.add(CutPasteDetector.ISSUE);
-        issues.add(DateFormatDetector.DATE_FORMAT);
-        issues.add(SetTextDetector.SET_TEXT_I18N);
-        issues.add(UnsafeNativeCodeDetector.LOAD);
-        issues.add(UnsafeNativeCodeDetector.UNSAFE_NATIVE_CODE_LOCATION);
-        issues.add(FragmentDetector.ISSUE);
-        issues.add(GetSignaturesDetector.ISSUE);
-        issues.add(HandlerDetector.ISSUE);
-        issues.add(IconDetector.DUPLICATES_CONFIGURATIONS);
-        issues.add(IconDetector.DUPLICATES_NAMES);
-        issues.add(IconDetector.GIF_USAGE);
-        issues.add(IconDetector.ICON_COLORS);
-        issues.add(IconDetector.ICON_DENSITIES);
-        issues.add(IconDetector.ICON_DIP_SIZE);
-        issues.add(IconDetector.ICON_EXPECTED_SIZE);
-        issues.add(IconDetector.ICON_EXTENSION);
-        issues.add(IconDetector.ICON_LAUNCHER_SHAPE);
-        issues.add(IconDetector.ICON_LOCATION);
-        issues.add(IconDetector.ICON_MISSING_FOLDER);
-        issues.add(IconDetector.ICON_MIX_9PNG);
-        issues.add(IconDetector.ICON_NODPI);
-        issues.add(IconDetector.ICON_XML_AND_PNG);
-        issues.add(TrustAllX509TrustManagerDetector.ISSUE);
-        issues.add(JavaPerformanceDetector.PAINT_ALLOC);
-        issues.add(JavaPerformanceDetector.USE_SPARSE_ARRAY);
-        issues.add(JavaPerformanceDetector.USE_VALUE_OF);
-        issues.add(JavaScriptInterfaceDetector.ISSUE);
-        issues.add(LayoutConsistencyDetector.INCONSISTENT_IDS);
-        issues.add(LayoutInflationDetector.ISSUE);
-        issues.add(LeakDetector.ISSUE);
-        issues.add(LocaleDetector.STRING_LOCALE);
-        issues.add(LogDetector.CONDITIONAL);
-        issues.add(LogDetector.LONG_TAG);
-        issues.add(LogDetector.WRONG_TAG);
-        issues.add(MathDetector.ISSUE);
-        issues.add(MergeRootFrameLayoutDetector.ISSUE);
-        issues.add(NonInternationalizedSmsDetector.ISSUE);
-        issues.add(OverdrawDetector.ISSUE);
-        issues.add(OverrideConcreteDetector.ISSUE);
-        issues.add(ParcelDetector.ISSUE);
-        issues.add(PreferenceActivityDetector.ISSUE);
-        issues.add(PrivateResourceDetector.ISSUE);
-        issues.add(ReadParcelableDetector.ISSUE);
-        issues.add(RecyclerViewDetector.DATA_BINDER);
-        issues.add(RecyclerViewDetector.FIXED_POSITION);
-        issues.add(RegistrationDetector.ISSUE);
-        issues.add(RequiredAttributeDetector.ISSUE);
-        issues.add(RtlDetector.COMPAT);
-        issues.add(RtlDetector.ENABLED);
-        issues.add(RtlDetector.SYMMETRY);
-        issues.add(RtlDetector.USE_START);
-        issues.add(SdCardDetector.ISSUE);
-        issues.add(SecureRandomDetector.ISSUE);
-        issues.add(SecurityDetector.EXPORTED_PROVIDER);
-        issues.add(SecurityDetector.EXPORTED_RECEIVER);
-        issues.add(SecurityDetector.EXPORTED_SERVICE);
-        issues.add(SecurityDetector.SET_READABLE);
-        issues.add(SecurityDetector.SET_WRITABLE);
-        issues.add(SecurityDetector.OPEN_PROVIDER);
-        issues.add(SecurityDetector.WORLD_READABLE);
-        issues.add(SecurityDetector.WORLD_WRITEABLE);
-        issues.add(ServiceCastDetector.ISSUE);
-        issues.add(SetJavaScriptEnabledDetector.ISSUE);
-        issues.add(SQLiteDetector.ISSUE);
-        issues.add(SslCertificateSocketFactoryDetector.CREATE_SOCKET);
-        issues.add(SslCertificateSocketFactoryDetector.GET_INSECURE);
-        issues.add(StringAuthLeakDetector.AUTH_LEAK);
-        issues.add(StringFormatDetector.ARG_COUNT);
-        issues.add(StringFormatDetector.ARG_TYPES);
-        issues.add(StringFormatDetector.INVALID);
-        issues.add(StringFormatDetector.POTENTIAL_PLURAL);
-        issues.add(SupportAnnotationDetector.CHECK_PERMISSION);
-        issues.add(SupportAnnotationDetector.CHECK_RESULT);
-        issues.add(SupportAnnotationDetector.COLOR_USAGE);
-        issues.add(SupportAnnotationDetector.MISSING_PERMISSION);
-        issues.add(SupportAnnotationDetector.RANGE);
-        issues.add(SupportAnnotationDetector.RESOURCE_TYPE);
-        issues.add(SupportAnnotationDetector.THREAD);
-        issues.add(SupportAnnotationDetector.TYPE_DEF);
-        issues.add(ToastDetector.ISSUE);
-        issues.add(UnsafeBroadcastReceiverDetector.ACTION_STRING);
-        issues.add(UnsafeBroadcastReceiverDetector.BROADCAST_SMS);
-        issues.add(ViewConstructorDetector.ISSUE);
-        issues.add(ViewHolderDetector.ISSUE);
-        issues.add(ViewTagDetector.ISSUE);
-        issues.add(ViewTypeDetector.ISSUE);
-        issues.add(WrongCallDetector.ISSUE);
-        issues.add(WrongImportDetector.ISSUE);
-
-        sIssues = Collections.unmodifiableList(issues);
-    }
-
-    /**
-     * Constructs a new {@link BuiltinIssueRegistry}
-     */
-    public BuiltinIssueRegistry() {
-    }
-
-    @NonNull
-    @Override
-    public List<Issue> getIssues() {
-        return sIssues;
-    }
-
-    @Override
-    protected int getIssueCapacity(@NonNull EnumSet<Scope> scope) {
-        if (scope.equals(Scope.ALL)) {
-            return getIssues().size();
-        } else {
-            int initialSize = 12;
-            if (scope.contains(Scope.RESOURCE_FILE)) {
-                initialSize += 80;
-            } else if (scope.contains(Scope.ALL_RESOURCE_FILES)) {
-                initialSize += 12;
-            }
-
-            if (scope.contains(Scope.JAVA_FILE)) {
-                initialSize += 74;
-            } else if (scope.contains(Scope.CLASS_FILE)) {
-                initialSize += 15;
-            } else if (scope.contains(Scope.MANIFEST)) {
-                initialSize += 38;
-            } else if (scope.contains(Scope.GRADLE_FILE)) {
-                initialSize += 5;
-            }
-            return initialSize;
-        }
-    }
-
-    /**
-     * Reset the registry such that it recomputes its available issues.
-     * <p>
-     * NOTE: This is only intended for testing purposes.
-     */
-    @VisibleForTesting
-    public static void reset() {
-        IssueRegistry.reset();
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java
deleted file mode 100644
index a62707d..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.*;
-import com.intellij.psi.PsiAnnotation;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.USuperExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-import static com.android.SdkConstants.CLASS_VIEW;
-import static com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.filterRelevantAnnotations;
-import static com.android.tools.klint.detector.api.LintUtils.skipParentheses;
-
-/**
- * Makes sure that methods call super when overriding methods.
- */
-public class CallSuperDetector extends Detector implements Detector.UastScanner {
-    private static final String CALL_SUPER_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "CallSuper"; //$NON-NLS-1$
-    private static final String ON_DETACHED_FROM_WINDOW = "onDetachedFromWindow";   //$NON-NLS-1$
-    private static final String ON_VISIBILITY_CHANGED = "onVisibilityChanged";      //$NON-NLS-1$
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            CallSuperDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Missing call to super */
-    public static final Issue ISSUE = Issue.create(
-            "MissingSuperCall", //$NON-NLS-1$
-            "Missing Super Call",
-
-            "Some methods, such as `View#onDetachedFromWindow`, require that you also " +
-            "call the super implementation as part of your method.",
-
-            Category.CORRECTNESS,
-            9,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** Constructs a new {@link CallSuperDetector} check */
-    public CallSuperDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(UMethod.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull final JavaContext context) {
-        return new AbstractUastVisitor() {
-            @Override
-            public boolean visitMethod(UMethod method) {
-                checkCallSuper(context, method);
-                return super.visitMethod(method);
-            }
-        };
-    }
-
-    private static void checkCallSuper(@NonNull JavaContext context,
-            @NonNull UMethod method) {
-
-        PsiMethod superMethod = getRequiredSuperMethod(context, method);
-        if (superMethod != null) {
-            if (!SuperCallVisitor.callsSuper(method, superMethod)) {
-                String methodName = method.getName();
-                String message = "Overriding method should call `super."
-                        + methodName + "`";
-                Location location = context.getUastNameLocation(method);
-                context.reportUast(ISSUE, method, location, message);
-            }
-        }
-    }
-
-    /**
-     * Checks whether the given method overrides a method which requires the super method
-     * to be invoked, and if so, returns it (otherwise returns null)
-     */
-    @Nullable
-    private static PsiMethod getRequiredSuperMethod(@NonNull JavaContext context,
-            @NonNull PsiMethod method) {
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        PsiMethod directSuper = evaluator.getSuperMethod(method);
-        if (directSuper == null) {
-            return null;
-        }
-
-        String name = method.getName();
-        if (ON_DETACHED_FROM_WINDOW.equals(name)) {
-            // No longer annotated on the framework method since it's
-            // now handled via onDetachedFromWindowInternal, but overriding
-            // is still dangerous if supporting older versions so flag
-            // this for now (should make annotation carry metadata like
-            // compileSdkVersion >= N).
-            if (!evaluator.isMemberInSubClassOf(method, CLASS_VIEW, false)) {
-                return null;
-            }
-            return directSuper;
-        } else if (ON_VISIBILITY_CHANGED.equals(name)) {
-            // From Android Wear API; doesn't yet have an annotation
-            // but we want to enforce this right away until the AAR
-            // is updated to supply it once @CallSuper is available in
-            // the support library
-            if (!evaluator.isMemberInSubClassOf(method,
-                    "android.support.wearable.watchface.WatchFaceService.Engine", false)) {
-                return null;
-            }
-            return directSuper;
-        }
-
-        // Look up annotations metadata
-        PsiMethod superMethod = directSuper;
-        while (superMethod != null) {
-            PsiAnnotation[] annotations = superMethod.getModifierList().getAnnotations();
-            annotations = filterRelevantAnnotations(context.getEvaluator(), annotations);
-            for (PsiAnnotation annotation : annotations) {
-                String signature = annotation.getQualifiedName();
-                if (CALL_SUPER_ANNOTATION.equals(signature)) {
-                    return directSuper;
-                } else if (signature != null && signature.endsWith(".OverrideMustInvoke")) {
-                    // Handle findbugs annotation on the fly too
-                    return directSuper;
-                }
-            }
-            superMethod = evaluator.getSuperMethod(superMethod);
-        }
-
-        return null;
-    }
-
-    /** Visits a method and determines whether the method calls its super method */
-    private static class SuperCallVisitor extends AbstractUastVisitor {
-        private final PsiMethod mMethod;
-        private boolean mCallsSuper;
-
-        public static boolean callsSuper(@NonNull UMethod method,
-                @NonNull PsiMethod superMethod) {
-            SuperCallVisitor visitor = new SuperCallVisitor(superMethod);
-            method.accept(visitor);
-            return visitor.mCallsSuper;
-        }
-
-        private SuperCallVisitor(@NonNull PsiMethod method) {
-            mMethod = method;
-        }
-
-        @Override
-        public boolean visitSuperExpression(USuperExpression node) {
-            UElement parent = skipParentheses(node.getUastParent());
-            if (parent instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) parent).resolve();
-                if (mMethod.equals(resolved)) {
-                    mCallsSuper = true;
-                }
-            }
-            
-            return super.visitSuperExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CipherGetInstanceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CipherGetInstanceDetector.java
deleted file mode 100644
index cdb9f53..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CipherGetInstanceDetector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.collect.Sets;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Ensures that Cipher.getInstance is not called with AES as the parameter.
- */
-public class CipherGetInstanceDetector extends Detector implements Detector.UastScanner {
-    public static final Issue ISSUE = Issue.create(
-            "GetInstance", //$NON-NLS-1$
-            "Cipher.getInstance with ECB",
-            "`Cipher#getInstance` should not be called with ECB as the cipher mode or without " +
-            "setting the cipher mode because the default mode on android is ECB, which " +
-            "is insecure.",
-            Category.SECURITY,
-            9,
-            Severity.WARNING,
-            new Implementation(
-                    CipherGetInstanceDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    private static final String CIPHER = "javax.crypto.Cipher"; //$NON-NLS-1$
-    private static final String GET_INSTANCE = "getInstance"; //$NON-NLS-1$
-    private static final Set<String> ALGORITHM_ONLY =
-            Sets.newHashSet("AES", "DES", "DESede"); //$NON-NLS-1$
-    private static final String ECB = "ECB"; //$NON-NLS-1$
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(GET_INSTANCE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        if (!context.getEvaluator().isMemberInSubClassOf(method, CIPHER, false)) {
-            return;
-        }
-        List<UExpression> arguments = node.getValueArguments();
-        if (arguments.size() == 1) {
-            UExpression expression = arguments.get(0);
-            Object value = ConstantEvaluator.evaluate(context, expression);
-            if (value instanceof String) {
-                checkParameter(context, node, expression, (String)value,
-                        !(expression instanceof ULiteralExpression));
-            }
-        }
-    }
-
-    private static void checkParameter(@NonNull JavaContext context,
-            @NonNull UCallExpression call, @NonNull UElement node, @NonNull String value,
-            boolean includeValue) {
-        if (ALGORITHM_ONLY.contains(value)) {
-            String message = "`Cipher.getInstance` should not be called without setting the"
-                    + " encryption mode and padding";
-            context.report(ISSUE, call, context.getUastLocation(node), message);
-        } else if (value.contains(ECB)) {
-            String message = "ECB encryption mode should not be used";
-            if (includeValue) {
-                message += " (was \"" + value + "\")";
-            }
-            context.report(ISSUE, call, context.getUastLocation(node), message);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java
deleted file mode 100644
index c55d7cb..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.collect.Lists;
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.util.containers.Predicate;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static com.android.SdkConstants.CLASS_CONTENTPROVIDER;
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.tools.klint.detector.api.LintUtils.skipParentheses;
-import static org.jetbrains.uast.UastUtils.*;
-
-/**
- * Checks for missing {@code recycle} calls on resources that encourage it, and
- * for missing {@code commit} calls on FragmentTransactions, etc.
- */
-public class CleanupDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            CleanupDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Problems with missing recycle calls */
-    public static final Issue RECYCLE_RESOURCE = Issue.create(
-            "Recycle", //$NON-NLS-1$
-            "Missing `recycle()` calls",
-
-            "Many resources, such as TypedArrays, VelocityTrackers, etc., " +
-            "should be recycled (with a `recycle()` call) after use. This lint check looks " +
-            "for missing `recycle()` calls.",
-
-            Category.PERFORMANCE,
-            7,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Problems with missing commit calls. */
-    public static final Issue COMMIT_FRAGMENT = Issue.create(
-            "CommitTransaction", //$NON-NLS-1$
-            "Missing `commit()` calls",
-
-            "After creating a `FragmentTransaction`, you typically need to commit it as well",
-
-            Category.CORRECTNESS,
-            7,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** The main issue discovered by this detector */
-    public static final Issue SHARED_PREF = Issue.create(
-            "CommitPrefEdits", //$NON-NLS-1$
-            "Missing `commit()` on `SharedPreference` editor",
-
-            "After calling `edit()` on a `SharedPreference`, you must call `commit()` " +
-            "or `apply()` on the editor to save the results.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    CleanupDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    // Target method names
-    private static final String RECYCLE = "recycle";                                  //$NON-NLS-1$
-    private static final String RELEASE = "release";                                  //$NON-NLS-1$
-    private static final String OBTAIN = "obtain";                                    //$NON-NLS-1$
-    private static final String SHOW = "show";                                        //$NON-NLS-1$
-    private static final String ACQUIRE_CPC = "acquireContentProviderClient";         //$NON-NLS-1$
-    private static final String OBTAIN_NO_HISTORY = "obtainNoHistory";                //$NON-NLS-1$
-    private static final String OBTAIN_ATTRIBUTES = "obtainAttributes";               //$NON-NLS-1$
-    private static final String OBTAIN_TYPED_ARRAY = "obtainTypedArray";              //$NON-NLS-1$
-    private static final String OBTAIN_STYLED_ATTRIBUTES = "obtainStyledAttributes";  //$NON-NLS-1$
-    private static final String BEGIN_TRANSACTION = "beginTransaction";               //$NON-NLS-1$
-    private static final String COMMIT = "commit";                                    //$NON-NLS-1$
-    private static final String APPLY = "apply";                                      //$NON-NLS-1$
-    private static final String COMMIT_ALLOWING_LOSS = "commitAllowingStateLoss";     //$NON-NLS-1$
-    private static final String QUERY = "query";                                      //$NON-NLS-1$
-    private static final String RAW_QUERY = "rawQuery";                               //$NON-NLS-1$
-    private static final String QUERY_WITH_FACTORY = "queryWithFactory";              //$NON-NLS-1$
-    private static final String RAW_QUERY_WITH_FACTORY = "rawQueryWithFactory";       //$NON-NLS-1$
-    private static final String CLOSE = "close";                                      //$NON-NLS-1$
-    private static final String USE = "use";                                          //$NON-NLS-1$
-    private static final String EDIT = "edit";                                        //$NON-NLS-1$
-
-    private static final String MOTION_EVENT_CLS = "android.view.MotionEvent";        //$NON-NLS-1$
-    private static final String PARCEL_CLS = "android.os.Parcel";                     //$NON-NLS-1$
-    private static final String VELOCITY_TRACKER_CLS = "android.view.VelocityTracker";//$NON-NLS-1$
-    private static final String DIALOG_FRAGMENT = "android.app.DialogFragment";       //$NON-NLS-1$
-    private static final String DIALOG_V4_FRAGMENT =
-            "android.support.v4.app.DialogFragment";                                  //$NON-NLS-1$
-    private static final String FRAGMENT_MANAGER_CLS = "android.app.FragmentManager"; //$NON-NLS-1$
-    private static final String FRAGMENT_MANAGER_V4_CLS =
-            "android.support.v4.app.FragmentManager";                                 //$NON-NLS-1$
-    private static final String FRAGMENT_TRANSACTION_CLS =
-            "android.app.FragmentTransaction";                                        //$NON-NLS-1$
-    private static final String FRAGMENT_TRANSACTION_V4_CLS =
-            "android.support.v4.app.FragmentTransaction";                             //$NON-NLS-1$
-
-    public static final String SURFACE_CLS = "android.view.Surface";
-    public static final String SURFACE_TEXTURE_CLS = "android.graphics.SurfaceTexture";
-
-    public static final String CONTENT_PROVIDER_CLIENT_CLS
-            = "android.content.ContentProviderClient";
-
-    public static final String CONTENT_RESOLVER_CLS = "android.content.ContentResolver";
-
-    @SuppressWarnings("SpellCheckingInspection")
-    public static final String SQLITE_DATABASE_CLS = "android.database.sqlite.SQLiteDatabase";
-    public static final String CURSOR_CLS = "android.database.Cursor";
-
-    public static final String ANDROID_CONTENT_SHARED_PREFERENCES =
-            "android.content.SharedPreferences"; //$NON-NLS-1$
-    private static final String ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR =
-            "android.content.SharedPreferences.Editor"; //$NON-NLS-1$
-    private static final String CLOSABLE = "java.io.Closeable"; //$NON-NLS-1$
-
-
-    /** Constructs a new {@link CleanupDetector} */
-    public CleanupDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                // FragmentManager commit check
-                BEGIN_TRANSACTION,
-
-                // Recycle check
-                OBTAIN, OBTAIN_NO_HISTORY,
-                OBTAIN_STYLED_ATTRIBUTES,
-                OBTAIN_ATTRIBUTES,
-                OBTAIN_TYPED_ARRAY,
-
-                // Release check
-                ACQUIRE_CPC,
-
-                // Cursor close check
-                QUERY, RAW_QUERY, QUERY_WITH_FACTORY, RAW_QUERY_WITH_FACTORY,
-
-                // SharedPreferences check
-                EDIT
-        );
-    }
-
-    @Nullable
-    @Override
-    public List<String> getApplicableConstructorTypes() {
-        return Arrays.asList(SURFACE_TEXTURE_CLS, SURFACE_CLS);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        String name = method.getName();
-        if (BEGIN_TRANSACTION.equals(name)) {
-            checkTransactionCommits(context, call, method);
-        } else if (EDIT.equals(name)) {
-            checkEditorApplied(context, call, method);
-        } else {
-            checkResourceRecycled(context, call, method);
-        }
-    }
-
-    @Override
-    public void visitConstructor(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod constructor) {
-        PsiClass containingClass = constructor.getContainingClass();
-        if (containingClass != null) {
-            String type = containingClass.getQualifiedName();
-            if (type != null) {
-                checkRecycled(context, node, type, RELEASE);
-            }
-        }
-    }
-
-    private static void checkResourceRecycled(@NonNull JavaContext context,
-            @NonNull UCallExpression node, @NonNull PsiMethod method) {
-        String name = method.getName();
-        // Recycle detector
-        PsiClass containingClass = method.getContainingClass();
-        if (containingClass == null) {
-            return;
-        }
-        JavaEvaluator evaluator = context.getEvaluator();
-        if ((OBTAIN.equals(name) || OBTAIN_NO_HISTORY.equals(name)) &&
-            InheritanceUtil.isInheritor(containingClass, false, MOTION_EVENT_CLS)) {
-            checkRecycled(context, node, MOTION_EVENT_CLS, RECYCLE);
-        } else if (OBTAIN.equals(name) && InheritanceUtil.isInheritor(containingClass, false, PARCEL_CLS)) {
-            checkRecycled(context, node, PARCEL_CLS, RECYCLE);
-        } else if (OBTAIN.equals(name) &&
-                   InheritanceUtil.isInheritor(containingClass, false, VELOCITY_TRACKER_CLS)) {
-            checkRecycled(context, node, VELOCITY_TRACKER_CLS, RECYCLE);
-        } else if ((OBTAIN_STYLED_ATTRIBUTES.equals(name)
-                    || OBTAIN_ATTRIBUTES.equals(name)
-                    || OBTAIN_TYPED_ARRAY.equals(name)) &&
-                   (InheritanceUtil.isInheritor(containingClass, false, CLASS_CONTEXT) ||
-                    InheritanceUtil.isInheritor(containingClass, false, SdkConstants.CLASS_RESOURCES))) {
-            PsiType returnType = method.getReturnType();
-            if (returnType instanceof PsiClassType) {
-                PsiClass cls = ((PsiClassType)returnType).resolve();
-                if (cls != null && "android.content.res.TypedArray".equals(cls.getQualifiedName())) {
-                    checkRecycled(context, node, "android.content.res.TypedArray", RECYCLE);
-                }
-            }
-        } else if (ACQUIRE_CPC.equals(name) && InheritanceUtil.isInheritor(containingClass,
-                                                                           false, CONTENT_RESOLVER_CLS)) {
-            checkRecycled(context, node, CONTENT_PROVIDER_CLIENT_CLS, RELEASE);
-        } else if ((QUERY.equals(name)
-                    || RAW_QUERY.equals(name)
-                    || QUERY_WITH_FACTORY.equals(name)
-                    || RAW_QUERY_WITH_FACTORY.equals(name))
-                   && (InheritanceUtil.isInheritor(containingClass, false, SQLITE_DATABASE_CLS) ||
-                       InheritanceUtil.isInheritor(containingClass, false, CONTENT_RESOLVER_CLS) ||
-                       InheritanceUtil.isInheritor(containingClass, false, CLASS_CONTENTPROVIDER) ||
-                       InheritanceUtil.isInheritor(containingClass, false, CONTENT_PROVIDER_CLIENT_CLS))) {
-            // Other potential cursors-returning methods that should be tracked:
-            //    android.app.DownloadManager#query
-            //    android.content.ContentProviderClient#query
-            //    android.content.ContentResolver#query
-            //    android.database.sqlite.SQLiteQueryBuilder#query
-            //    android.provider.Browser#getAllBookmarks
-            //    android.provider.Browser#getAllVisitedUrls
-            //    android.provider.DocumentsProvider#queryChildDocuments
-            //    android.provider.DocumentsProvider#qqueryDocument
-            //    android.provider.DocumentsProvider#queryRecentDocuments
-            //    android.provider.DocumentsProvider#queryRoots
-            //    android.provider.DocumentsProvider#querySearchDocuments
-            //    android.provider.MediaStore$Images$Media#query
-            //    android.widget.FilterQueryProvider#runQuery
-            checkClosedOrUsed(context, node, CURSOR_CLS);
-        }
-    }
-
-    private static void reportRecycleResource(JavaContext context, String recycleType, String recycleName, @NonNull UCallExpression node) {
-        String className = recycleType.substring(recycleType.lastIndexOf('.') + 1);
-        String message;
-        if (RECYCLE.equals(recycleName)) {
-            message = String.format(
-                    "This `%1$s` should be recycled after use with `#recycle()`", className);
-        } else {
-            message = String.format(
-                    "This `%1$s` should be freed up after use with `#%2$s()`", className,
-                    recycleName);
-        }
-
-        UElement locationNode = node.getMethodIdentifier();
-        if (locationNode == null) {
-            locationNode = node;
-        }
-        Location location = context.getUastLocation(locationNode);
-        context.report(RECYCLE_RESOURCE, node, location, message);
-    }
-
-    private static void checkClosedOrUsed(@NonNull final JavaContext context, @NonNull UCallExpression node,
-            @NonNull final String recycleType) {
-
-        if (isCleanedUpInChain(node, new Predicate<UCallExpression>() {
-            @Override
-            public boolean apply(@org.jetbrains.annotations.Nullable UCallExpression call) {
-                return isCloseMethodCall(call) || isUseMethodCall(call);
-            }
-        })) {
-            return;
-        }
-
-        PsiVariable boundVariable = getVariableElement(node);
-        if (boundVariable == null) {
-            reportRecycleResource(context, recycleType, CLOSE, node);
-            return;
-        }
-
-        UMethod method = getParentOfType(node, UMethod.class, true);
-        if (method == null) {
-            return;
-        }
-
-        FinishVisitor visitor = new FinishVisitor(context, boundVariable) {
-            @Override
-            protected boolean isCleanupCall(@NonNull UCallExpression call) {
-                if (isUseMethodCall(call) || isCloseMethodCall(call)) {
-                    UExpression receiver = call.getReceiver();
-                    if (receiver instanceof UReferenceExpression) {
-                        PsiElement resolved = ((UReferenceExpression) receiver).resolve();
-                        //noinspection SuspiciousMethodCalls
-                        if (resolved != null && mVariables.contains(resolved)) {
-                            return true;
-                        }
-                    }
-                }
-                return false;
-            }
-        };
-
-        method.accept(visitor);
-        if (visitor.isCleanedUp() || visitor.variableEscapes()) {
-            return;
-        }
-
-        reportRecycleResource(context, recycleType, CLOSE, node);
-    }
-
-    private static boolean isCloseMethodCall(UCallExpression call) {
-        return isValidCleanupMethodCall(call, CLOSE, CLOSABLE);
-    }
-
-    private static boolean isUseMethodCall(UCallExpression call) {
-        return USE.equals(call.getMethodName());
-    }
-
-    private static boolean isValidCleanupMethodCall(@NonNull UCallExpression call, @NonNull String methodName, @NonNull String className) {
-        if (!methodName.equals(call.getMethodName())) {
-            return false;
-        }
-
-        PsiMethod method = call.resolve();
-        if (method == null) {
-            return false;
-        }
-
-        return InheritanceUtil.isInheritor(method.getContainingClass(), false, className);
-    }
-
-    private static boolean isCleanedUpInChain(UExpression expression, Predicate<UCallExpression> isCleanupCallPredicate) {
-        List<UExpression> chain = getQualifiedChain(getOutermostQualified(expression));
-        boolean skip = true;
-        for (UExpression e : chain) {
-            if (e == expression) {
-                skip = false;
-                continue;
-            }
-
-            if (skip) {
-                continue;
-            }
-
-            if (e instanceof UCallExpression) {
-                UCallExpression call = (UCallExpression) e;
-                if (isCleanupCallPredicate.apply(call)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private static void checkRecycled(@NonNull final JavaContext context, @NonNull UCallExpression node,
-            @NonNull final String recycleType, @NonNull final String recycleName) {
-
-        if (isCleanedUpInChain(node, new Predicate<UCallExpression>() {
-            @Override
-            public boolean apply(@org.jetbrains.annotations.Nullable UCallExpression call) {
-                return isValidCleanupMethodCall(call, recycleName, recycleType);
-            }
-        })) {
-            return;
-        }
-
-        PsiVariable boundVariable = getVariableElement(node);
-        if (boundVariable == null) {
-            reportRecycleResource(context, recycleType, recycleName, node);
-            return;
-        }
-
-        UMethod method = getParentOfType(node, UMethod.class, true);
-        if (method == null) {
-            return;
-        }
-
-        FinishVisitor visitor = new FinishVisitor(context, boundVariable) {
-            @Override
-            protected boolean isCleanupCall(@NonNull UCallExpression call) {
-                if (isValidCleanupMethodCall(call, recycleName, recycleType)) {
-                    // Yes, called the right recycle() method; now make sure
-                    // we're calling it on the right variable
-                    UExpression operand = call.getReceiver();
-                    if (operand instanceof UReferenceExpression) {
-                        PsiElement resolved = ((UReferenceExpression) operand).resolve();
-                        //noinspection SuspiciousMethodCalls
-                        if (resolved != null && mVariables.contains(resolved)) {
-                            return true;
-                        }
-                    }
-                }
-                return false;
-            }
-        };
-
-        method.accept(visitor);
-        if (visitor.isCleanedUp() || visitor.variableEscapes()) {
-            return;
-        }
-
-        reportRecycleResource(context, recycleType, recycleName, node);
-    }
-
-    private static void checkTransactionCommits(@NonNull JavaContext context,
-            @NonNull UCallExpression node, @NonNull PsiMethod calledMethod) {
-        if (isBeginTransaction(context, calledMethod)) {
-            if (isCommittedInChainedCalls(context, node)) {
-                return;
-            }
-
-            PsiVariable boundVariable = getVariableElement(node, true);
-            if (boundVariable != null) {
-                UMethod method = getParentOfType(node, UMethod.class, true);
-                if (method == null) {
-                    return;
-                }
-
-                FinishVisitor commitVisitor = new FinishVisitor(context, boundVariable) {
-                    @Override
-                    protected boolean isCleanupCall(@NonNull UCallExpression call) {
-                        if (isTransactionCommitMethodCall(mContext, call)) {
-                            List<UExpression> chain = getQualifiedChain(getOutermostQualified(call));
-                            if (chain.isEmpty()) {
-                                return false;
-                            }
-
-                            UExpression operand = chain.get(0);
-                            if (operand != null) {
-                                PsiElement resolved = UastUtils.tryResolve(operand);
-                                //noinspection SuspiciousMethodCalls
-                                if (resolved != null && mVariables.contains(resolved)) {
-                                    return true;
-                                } else if (resolved instanceof PsiMethod
-                                           && operand instanceof UCallExpression
-                                           && isCommittedInChainedCalls(mContext,
-                                                                        (UCallExpression) operand)) {
-                                    // Check that the target of the committed chains is the
-                                    // right variable!
-                                    while (operand instanceof UCallExpression) {
-                                        operand = ((UCallExpression) operand).getReceiver();
-                                    }
-                                    if (operand instanceof UReferenceExpression) {
-                                        resolved = ((UReferenceExpression) operand).resolve();
-                                        //noinspection SuspiciousMethodCalls
-                                        if (resolved != null && mVariables.contains(resolved)) {
-                                            return true;
-                                        }
-                                    }
-                                }
-                            }
-                        } else if (isShowFragmentMethodCall(mContext, call)) {
-                            List<UExpression> arguments = call.getValueArguments();
-                            if (arguments.size() == 2) {
-                                UExpression first = arguments.get(0);
-                                PsiElement resolved = UastUtils.tryResolve(first);
-                                //noinspection SuspiciousMethodCalls
-                                if (resolved != null && mVariables.contains(resolved)) {
-                                    return true;
-                                }
-                            }
-                        }
-                        return false;
-                    }
-                };
-
-                method.accept(commitVisitor);
-                if (commitVisitor.isCleanedUp() || commitVisitor.variableEscapes()) {
-                    return;
-                }
-            }
-
-            String message = "This transaction should be completed with a `commit()` call";
-            context.report(COMMIT_FRAGMENT, node, context.getUastNameLocation(node), message);
-        }
-    }
-
-    private static boolean isCommittedInChainedCalls(@NonNull final JavaContext context,
-            @NonNull UCallExpression node) {
-        // Look for chained calls since the FragmentManager methods all return "this"
-        // to allow constructor chaining, e.g.
-        //    getFragmentManager().beginTransaction().addToBackStack("test")
-        //            .disallowAddToBackStack().hide(mFragment2).setBreadCrumbShortTitle("test")
-        //            .show(mFragment2).setCustomAnimations(0, 0).commit();
-
-        return isCleanedUpInChain(node, new Predicate<UCallExpression>() {
-            @Override
-            public boolean apply(@org.jetbrains.annotations.Nullable UCallExpression call) {
-                return isTransactionCommitMethodCall(context, call) || isShowFragmentMethodCall(context, call);
-            }
-        });
-    }
-
-    private static boolean isTransactionCommitMethodCall(@NonNull JavaContext context,
-            @NonNull UCallExpression call) {
-
-        String methodName = call.getMethodName();
-        return (COMMIT.equals(methodName) || COMMIT_ALLOWING_LOSS.equals(methodName)) &&
-               isMethodOnFragmentClass(context, call,
-                                       FRAGMENT_TRANSACTION_CLS,
-                                       FRAGMENT_TRANSACTION_V4_CLS,
-                                       true);
-    }
-
-    private static boolean isShowFragmentMethodCall(@NonNull JavaContext context,
-            @NonNull UCallExpression call) {
-        String methodName = call.getMethodName();
-        return SHOW.equals(methodName)
-               && isMethodOnFragmentClass(context, call,
-                                          DIALOG_FRAGMENT, DIALOG_V4_FRAGMENT, true);
-    }
-
-    private static boolean isMethodOnFragmentClass(
-            @NonNull JavaContext context,
-            @NonNull UCallExpression call,
-            @NonNull String fragmentClass,
-            @NonNull String v4FragmentClass,
-            boolean returnForUnresolved) {
-        PsiMethod method = call.resolve();
-        if (method != null) {
-            PsiClass containingClass = method.getContainingClass();
-            JavaEvaluator evaluator = context.getEvaluator();
-            return InheritanceUtil.isInheritor(containingClass, false, fragmentClass) ||
-                   InheritanceUtil.isInheritor(containingClass, false, v4FragmentClass);
-        } else {
-            // If we *can't* resolve the method call, caller can decide
-            // whether to consider the method called or not
-            return returnForUnresolved;
-        }
-    }
-
-    private static void checkEditorApplied(@NonNull JavaContext context,
-            @NonNull UCallExpression node, @NonNull PsiMethod calledMethod) {
-        if (isSharedEditorCreation(context, calledMethod)) {
-            PsiVariable boundVariable = getVariableElement(node, true);
-            if (isEditorCommittedInChainedCalls(context, node)) {
-                return;
-            }
-
-            if (boundVariable != null) {
-                UMethod method = getParentOfType(node, UMethod.class, true);
-                if (method == null) {
-                    return;
-                }
-
-                FinishVisitor commitVisitor = new FinishVisitor(context, boundVariable) {
-                    @Override
-                    protected boolean isCleanupCall(@NonNull UCallExpression call) {
-                        if (isEditorApplyMethodCall(mContext, call)
-                            || isEditorCommitMethodCall(mContext, call)) {
-                            List<UExpression> chain = getQualifiedChain(getOutermostQualified(call));
-                            if (chain.isEmpty()) {
-                                return false;
-                            }
-
-                            UExpression operand = chain.get(0);
-                            if (operand != null) {
-                                PsiElement resolved = UastUtils.tryResolve(operand);
-                                //noinspection SuspiciousMethodCalls
-                                if (resolved != null && mVariables.contains(resolved)) {
-                                    return true;
-                                } else if (resolved instanceof PsiMethod
-                                           && operand instanceof UCallExpression
-                                           && isEditorCommittedInChainedCalls(mContext,
-                                                                              (UCallExpression) operand)) {
-                                    // Check that the target of the committed chains is the
-                                    // right variable!
-                                    while (operand instanceof UCallExpression) {
-                                        operand = ((UCallExpression)operand).getReceiver();
-                                    }
-                                    if (operand instanceof UReferenceExpression) {
-                                        resolved = ((UReferenceExpression) operand).resolve();
-                                        //noinspection SuspiciousMethodCalls
-                                        if (resolved != null && mVariables.contains(resolved)) {
-                                            return true;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        return false;
-                    }
-                };
-
-                method.accept(commitVisitor);
-                if (commitVisitor.isCleanedUp() || commitVisitor.variableEscapes()) {
-                    return;
-                }
-            } else if (UastUtils.getParentOfType(node, UReturnExpression.class) != null) {
-                // Allocation is in a return statement
-                return;
-            }
-
-            String message = "`SharedPreferences.edit()` without a corresponding `commit()` or "
-                             + "`apply()` call";
-            context.report(SHARED_PREF, node, context.getUastLocation(node), message);
-        }
-    }
-
-    private static boolean isSharedEditorCreation(@NonNull JavaContext context,
-            @NonNull PsiMethod method) {
-        String methodName = method.getName();
-        if (EDIT.equals(methodName)) {
-            PsiClass containingClass = method.getContainingClass();
-            JavaEvaluator evaluator = context.getEvaluator();
-            return InheritanceUtil.isInheritor(
-                    containingClass, false, ANDROID_CONTENT_SHARED_PREFERENCES);
-        }
-
-        return false;
-    }
-
-    private static boolean isEditorCommittedInChainedCalls(@NonNull final JavaContext context,
-            @NonNull UCallExpression node) {
-        return isCleanedUpInChain(node, new Predicate<UCallExpression>() {
-            @Override
-            public boolean apply(@org.jetbrains.annotations.Nullable UCallExpression call) {
-                return isEditorCommitMethodCall(context, call) || isEditorApplyMethodCall(context, call);
-            }
-        });
-    }
-
-    private static boolean isEditorCommitMethodCall(@NonNull JavaContext context,
-            @NonNull UCallExpression call) {
-        String methodName = call.getMethodName();
-        if (COMMIT.equals(methodName)) {
-            PsiMethod method = call.resolve();
-            if (method != null) {
-                PsiClass containingClass = method.getContainingClass();
-                JavaEvaluator evaluator = context.getEvaluator();
-                if (InheritanceUtil.isInheritor(containingClass, false,
-                                                ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR)) {
-                    suggestApplyIfApplicable(context, call);
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isEditorApplyMethodCall(@NonNull JavaContext context,
-            @NonNull UCallExpression call) {
-        String methodName = call.getMethodName();
-        if (APPLY.equals(methodName)) {
-            PsiMethod method = call.resolve();
-            if (method != null) {
-                PsiClass containingClass = method.getContainingClass();
-                JavaEvaluator evaluator = context.getEvaluator();
-                return InheritanceUtil.isInheritor(containingClass, false,
-                                                   ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR);
-            }
-        }
-
-        return false;
-    }
-
-    private static void suggestApplyIfApplicable(@NonNull JavaContext context,
-            @NonNull UCallExpression node) {
-        if (context.getProject().getMinSdkVersion().getApiLevel() >= 9) {
-            // See if the return value is read: can only replace commit with
-            // apply if the return value is not considered
-
-            UElement qualifiedNode = node;
-            UElement parent = skipParentheses(node.getUastParent());
-            while (parent instanceof UReferenceExpression) {
-                qualifiedNode = parent;
-                parent = skipParentheses(parent.getUastParent());
-            }
-            boolean returnValueIgnored = true;
-
-            if (parent instanceof UCallExpression
-                || parent instanceof UVariable
-                || parent instanceof UBinaryExpression
-                || parent instanceof UUnaryExpression
-                || parent instanceof UReturnExpression) {
-                returnValueIgnored = false;
-            } else if (parent instanceof UIfExpression) {
-                UExpression condition = ((UIfExpression) parent).getCondition();
-                returnValueIgnored = !condition.equals(qualifiedNode);
-            } else if (parent instanceof UWhileExpression) {
-                UExpression condition = ((UWhileExpression) parent).getCondition();
-                returnValueIgnored = !condition.equals(qualifiedNode);
-            } else if (parent instanceof UDoWhileExpression) {
-                UExpression condition = ((UDoWhileExpression) parent).getCondition();
-                returnValueIgnored = !condition.equals(qualifiedNode);
-            }
-
-            if (returnValueIgnored) {
-                String message = "Consider using `apply()` instead; `commit` writes "
-                                 + "its data to persistent storage immediately, whereas "
-                                 + "`apply` will handle it in the background";
-                context.report(SHARED_PREF, node, context.getUastLocation(node), message);
-            }
-        }
-    }
-
-    /** Returns the variable the expression is assigned to, if any */
-    @Nullable
-    public static PsiVariable getVariableElement(@NonNull UCallExpression rhs) {
-        return getVariableElement(rhs, false);
-    }
-
-    @Nullable
-    public static PsiVariable getVariableElement(@NonNull UCallExpression rhs,
-            boolean allowChainedCalls) {
-        UElement parent = skipParentheses(
-                UastUtils.getQualifiedParentOrThis(rhs).getUastParent());
-
-        // Handle some types of chained calls; e.g. you might have
-        //    var = prefs.edit().put(key,value)
-        // and here we want to skip past the put call
-        if (allowChainedCalls) {
-            while (true) {
-                if ((parent instanceof UQualifiedReferenceExpression)) {
-                    UElement parentParent = skipParentheses(parent.getUastParent());
-                    if ((parentParent instanceof UQualifiedReferenceExpression)) {
-                        parent = skipParentheses(parentParent.getUastParent());
-                    } else if (parentParent instanceof UVariable
-                               || parentParent instanceof UBinaryExpression) {
-                        parent = parentParent;
-                        break;
-                    } else {
-                        break;
-                    }
-                } else {
-                    break;
-                }
-            }
-        }
-
-        if (UastExpressionUtils.isAssignment(parent)) {
-            UBinaryExpression assignment = (UBinaryExpression) parent;
-            assert assignment != null;
-            UExpression lhs = assignment.getLeftOperand();
-            if (lhs instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) lhs).resolve();
-                if (resolved instanceof PsiVariable && !(resolved instanceof PsiField)) {
-                    // e.g. local variable, parameter - but not a field
-                    return ((PsiVariable) resolved);
-                }
-            }
-        } else if (parent instanceof UVariable && !(parent instanceof UField)) {
-            return ((UVariable) parent).getPsi();
-        }
-
-        return null;
-    }
-
-    private static boolean isBeginTransaction(@NonNull JavaContext context, @NonNull PsiMethod method) {
-        String methodName = method.getName();
-        if (BEGIN_TRANSACTION.equals(methodName)) {
-            PsiClass containingClass = method.getContainingClass();
-            JavaEvaluator evaluator = context.getEvaluator();
-            if (InheritanceUtil.isInheritor(containingClass, false, FRAGMENT_MANAGER_CLS)
-                || InheritanceUtil.isInheritor(containingClass, false, FRAGMENT_MANAGER_V4_CLS)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Visitor which checks whether an operation is "finished"; in the case
-     * of a FragmentTransaction we're looking for a "commit" call; in the
-     * case of a TypedArray we're looking for a "recycle", call, in the
-     * case of a database cursor we're looking for a "close" call, etc.
-     */
-    private abstract static class FinishVisitor extends AbstractUastVisitor {
-        protected final JavaContext mContext;
-        protected final List<PsiVariable> mVariables;
-        private final PsiVariable mOriginalVariableNode;
-
-        private boolean mContainsCleanup;
-        private boolean mEscapes;
-
-        public FinishVisitor(JavaContext context, @NonNull PsiVariable variableNode) {
-            mContext = context;
-            mOriginalVariableNode = variableNode;
-            mVariables = Lists.newArrayList(variableNode);
-        }
-
-        public boolean isCleanedUp() {
-            return mContainsCleanup;
-        }
-
-        public boolean variableEscapes() {
-            return mEscapes;
-        }
-
-        @Override
-        public boolean visitElement(UElement node) {
-            return mContainsCleanup || super.visitElement(node);
-        }
-
-        protected abstract boolean isCleanupCall(@NonNull UCallExpression call);
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (node.getKind() == UastCallKind.METHOD_CALL) {
-                visitMethodCallExpression(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void visitMethodCallExpression(UCallExpression call) {
-            if (mContainsCleanup) {
-                return;
-            }
-
-            // Look for escapes
-            if (!mEscapes) {
-                for (UExpression expression : call.getValueArguments()) {
-                    if (expression instanceof UReferenceExpression) {
-                        PsiElement resolved = ((UReferenceExpression) expression).resolve();
-                        //noinspection SuspiciousMethodCalls
-                        if (resolved != null && mVariables.contains(resolved)) {
-                            boolean wasEscaped = mEscapes;
-                            mEscapes = true;
-
-                            // Special case: MotionEvent.obtain(MotionEvent): passing in an
-                            // event here does not recycle the event, and we also know it
-                            // doesn't escape
-                            if (OBTAIN.equals(call.getMethodName())) {
-                                PsiMethod method = call.resolve();
-                                if (JavaEvaluator.isMemberInClass(method, MOTION_EVENT_CLS)) {
-                                    mEscapes = wasEscaped;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (isCleanupCall(call)) {
-                mContainsCleanup = true;
-            }
-        }
-
-        @Override
-        public boolean visitVariable(UVariable variable) {
-            if (variable instanceof ULocalVariable) {
-                UExpression initializer = variable.getUastInitializer();
-                if (initializer instanceof UReferenceExpression) {
-                    PsiElement resolved = ((UReferenceExpression) initializer).resolve();
-                    //noinspection SuspiciousMethodCalls
-                    if (resolved != null && mVariables.contains(resolved)) {
-                        mVariables.add(variable.getPsi());
-                    }
-                }
-            }
-
-            return super.visitVariable(variable);
-        }
-
-        @Override
-        public boolean visitBinaryExpression(UBinaryExpression expression) {
-            if (!UastExpressionUtils.isAssignment(expression)) {
-                return super.visitBinaryExpression(expression);
-            }
-
-            // TEMPORARILY DISABLED; see testDatabaseCursorReassignment
-            // This can result in some false positives right now. Play it
-            // safe instead.
-            boolean clearLhs = false;
-
-            UExpression rhs = expression.getRightOperand();
-            if (rhs instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) rhs).resolve();
-                //noinspection SuspiciousMethodCalls
-                if (resolved != null && mVariables.contains(resolved)) {
-                    clearLhs = false;
-                    PsiElement lhs = UastUtils.tryResolve(expression.getLeftOperand());
-                    if (lhs instanceof PsiLocalVariable) {
-                        mVariables.add(((PsiLocalVariable) lhs));
-                    } else if (lhs instanceof PsiField) {
-                        mEscapes = true;
-                    }
-                }
-            }
-
-            //noinspection ConstantConditions
-            if (clearLhs) {
-                // If we reassign one of the variables, clear it out
-                PsiElement lhs = UastUtils.tryResolve(expression.getLeftOperand());
-                //noinspection SuspiciousMethodCalls
-                if (lhs != null && !lhs.equals(mOriginalVariableNode)
-                    && mVariables.contains(lhs)) {
-                    //noinspection SuspiciousMethodCalls
-                    mVariables.remove(lhs);
-                }
-            }
-
-            return super.visitBinaryExpression(expression);
-        }
-
-        @Override
-        public boolean visitReturnExpression(UReturnExpression node) {
-            UExpression returnValue = node.getReturnExpression();
-            if (returnValue instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) returnValue).resolve();
-                //noinspection SuspiciousMethodCalls
-                if (resolved != null && mVariables.contains(resolved)) {
-                    mEscapes = true;
-                }
-            }
-
-            return super.visitReturnExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CommentDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CommentDetector.java
deleted file mode 100644
index 0ba5f18..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CommentDetector.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UComment;
-import org.jetbrains.uast.UFile;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for issues in Java comments
- */
-public class CommentDetector extends Detector implements Detector.UastScanner {
-    private static final String STOPSHIP_COMMENT = "STOPSHIP"; //$NON-NLS-1$
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            CommentDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Looks for hidden code */
-    public static final Issue EASTER_EGG = Issue.create(
-            "EasterEgg", //$NON-NLS-1$
-            "Code contains easter egg",
-            "An \"easter egg\" is code deliberately hidden in the code, both from potential " +
-            "users and even from other developers. This lint check looks for code which " +
-            "looks like it may be hidden from sight.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .setEnabledByDefault(false);
-
-    /** Looks for special comment markers intended to stop shipping the code */
-    public static final Issue STOP_SHIP = Issue.create(
-            "StopShip", //$NON-NLS-1$
-            "Code contains `STOPSHIP` marker",
-
-            "Using the comment `// STOPSHIP` can be used to flag code that is incomplete but " +
-            "checked in. This comment marker can be used to indicate that the code should not " +
-            "be shipped until the issue is addressed, and lint will look for these.",
-            Category.CORRECTNESS,
-            10,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .setEnabledByDefault(false);
-
-    private static final String ESCAPE_STRING = "\\u002a\\u002f"; //$NON-NLS-1$
-
-    /** The current AST only passes comment nodes for Javadoc so I need to do manual token scanning
-     instead */
-    private static final boolean USE_AST = false;
-
-
-    /** Constructs a new {@link CommentDetector} check */
-    public CommentDetector() {
-    }
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        if (USE_AST) {
-            return Collections.<Class<? extends UElement>>singletonList(
-                    UFile.class);
-        } else {
-            return null;
-        }
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        if (USE_AST) {
-            return new CommentChecker(context);
-        } else {
-            String source = context.getContents();
-            if (source == null) {
-                return null;
-            }
-            // Process the Java source such that we pass tokens to it
-
-            for (int i = 0, n = source.length() - 1; i < n; i++) {
-                char c = source.charAt(i);
-                if (c == '\\') {
-                    i += 1;
-                } else if (c == '/') {
-                    char next = source.charAt(i + 1);
-                    if (next == '/') {
-                        // Line comment
-                        int start = i + 2;
-                        int end = source.indexOf('\n', start);
-                        if (end == -1) {
-                            end = n;
-                        }
-                        checkComment(context, null, source, 0, start, end);
-                    } else if (next == '*') {
-                        // Block comment
-                        int start = i + 2;
-                        int end = source.indexOf("*/", start);
-                        if (end == -1) {
-                            end = n;
-                        }
-                        checkComment(context, null, source, 0, start, end);
-                    }
-                }
-            }
-            return null;
-        }
-    }
-
-    private static class CommentChecker extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        public CommentChecker(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitFile(UFile node) {
-            for (UComment comment : node.getAllCommentsInFile()) {
-                String contents = comment.getText();
-                checkComment(mContext, comment, contents,
-                             comment.getPsi().getTextRange().getStartOffset(), 0, contents.length());
-            }
-            return super.visitFile(node);
-        }
-    }
-
-    private static void checkComment(
-            @NonNull JavaContext context,
-            @Nullable UComment node,
-            @NonNull String source,
-            int offset,
-            int start,
-            int end) {
-        char prev = 0;
-        char c;
-        for (int i = start; i < end - 2; i++, prev = c) {
-            c = source.charAt(i);
-            if (prev == '\\') {
-                if (c == 'u' || c == 'U') {
-                    if (source.regionMatches(true, i - 1, ESCAPE_STRING,
-                                             0, ESCAPE_STRING.length())) {
-                        Location location = Location.create(context.file, source,
-                                                            offset + i - 1, offset + i - 1 + ESCAPE_STRING.length());
-                        context.report(EASTER_EGG, node, location,
-                                       "Code might be hidden here; found unicode escape sequence " +
-                                       "which is interpreted as comment end, compiled code follows");
-                    }
-                } else {
-                    i++;
-                }
-            } else if (prev == 'S' && c == 'T' &&
-                       source.regionMatches(i - 1, STOPSHIP_COMMENT, 0, STOPSHIP_COMMENT.length())) {
-
-                // TODO: Only flag this issue in release mode??
-                Location location;
-                if (node != null) {
-                    location = context.getUastLocation(node);
-                } else {
-                    location = Location.create(context.file, source,
-                                               offset + i - 1, offset + i - 1 + STOPSHIP_COMMENT.length());
-                }
-
-                context.report(STOP_SHIP, node, location,
-                               "`STOPSHIP` comment found; points to code which must be fixed prior " +
-                               "to release");
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ControlFlowGraph.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ControlFlowGraph.java
deleted file mode 100644
index e524f52..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ControlFlowGraph.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import org.jetbrains.org.objectweb.asm.Opcodes;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.FrameNode;
-import org.jetbrains.org.objectweb.asm.tree.InsnList;
-import org.jetbrains.org.objectweb.asm.tree.IntInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.LabelNode;
-import org.jetbrains.org.objectweb.asm.tree.LdcInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.LineNumberNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode;
-import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer;
-import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
-import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-//import org.jetbrains.org.objectweb.asm.util.Printer;
-
-/**
- * A {@linkplain ControlFlowGraph} is a graph containing a node for each
- * instruction in a method, and an edge for each possible control flow; usually
- * just "next" for the instruction following the current instruction, but in the
- * case of a branch such as an "if", multiple edges to each successive location,
- * or with a "goto", a single edge to the jumped-to instruction.
- * <p>
- * It also adds edges for abnormal control flow, such as the possibility of a
- * method call throwing a runtime exception.
- */
-public class ControlFlowGraph {
-    /** Map from instructions to nodes */
-    private Map<AbstractInsnNode, Node> mNodeMap;
-    private MethodNode mMethod;
-
-    /**
-     * Creates a new {@link ControlFlowGraph} and populates it with the flow
-     * control for the given method. If the optional {@code initial} parameter is
-     * provided with an existing graph, then the graph is simply populated, not
-     * created. This allows subclassing of the graph instance, if necessary.
-     *
-     * @param initial usually null, but can point to an existing instance of a
-     *            {@link ControlFlowGraph} in which that graph is reused (but
-     *            populated with new edges)
-     * @param classNode the class containing the method to be analyzed
-     * @param method the method to be analyzed
-     * @return a {@link ControlFlowGraph} with nodes for the control flow in the
-     *         given method
-     * @throws AnalyzerException if the underlying bytecode library is unable to
-     *             analyze the method bytecode
-     */
-    @NonNull
-    public static ControlFlowGraph create(
-            @Nullable ControlFlowGraph initial,
-            @NonNull ClassNode classNode,
-            @NonNull MethodNode method) throws AnalyzerException {
-        final ControlFlowGraph graph = initial != null ? initial : new ControlFlowGraph();
-        final InsnList instructions = method.instructions;
-        graph.mNodeMap = Maps.newHashMapWithExpectedSize(instructions.size());
-        graph.mMethod = method;
-
-        // Create a flow control graph using ASM5's analyzer. According to the ASM 4 guide
-        // (download.forge.objectweb.org/asm/asm4-guide.pdf) there are faster ways to construct
-        // it, but those require a lot more code.
-        Analyzer analyzer = new Analyzer(new BasicInterpreter()) {
-            @Override
-            protected void newControlFlowEdge(int insn, int successor) {
-                // Update the information as of whether the this object has been
-                // initialized at the given instruction.
-                AbstractInsnNode from = instructions.get(insn);
-                AbstractInsnNode to = instructions.get(successor);
-                graph.add(from, to);
-            }
-
-            @Override
-            protected boolean newControlFlowExceptionEdge(int insn, TryCatchBlockNode tcb) {
-                AbstractInsnNode from = instructions.get(insn);
-                graph.exception(from, tcb);
-                return super.newControlFlowExceptionEdge(insn, tcb);
-            }
-
-            @Override
-            protected boolean newControlFlowExceptionEdge(int insn, int successor) {
-                AbstractInsnNode from = instructions.get(insn);
-                AbstractInsnNode to = instructions.get(successor);
-                graph.exception(from, to);
-                return super.newControlFlowExceptionEdge(insn, successor);
-            }
-        };
-
-        analyzer.analyze(classNode.name, method);
-        return graph;
-    }
-
-    /**
-     * Checks whether there is a path from the given source node to the given
-     * destination node
-     */
-    @SuppressWarnings("MethodMayBeStatic")
-    private boolean isConnected(@NonNull Node from,
-            @NonNull Node to, @NonNull Set<Node> seen) {
-        if (from == to) {
-            return true;
-        } else if (seen.contains(from)) {
-            return false;
-        }
-        seen.add(from);
-
-        List<Node> successors = from.successors;
-        List<Node> exceptions = from.exceptions;
-        if (exceptions != null) {
-            for (Node successor : exceptions) {
-                if (isConnected(successor, to, seen)) {
-                    return true;
-                }
-            }
-        }
-
-        if (successors != null) {
-            for (Node successor : successors) {
-                if (isConnected(successor, to, seen)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks whether there is a path from the given source node to the given
-     * destination node
-     */
-    public boolean isConnected(@NonNull Node from, @NonNull Node to) {
-        return isConnected(from, to, Sets.<Node>newIdentityHashSet());
-    }
-
-    /**
-     * Checks whether there is a path from the given instruction to the given
-     * instruction node
-     */
-    public boolean isConnected(@NonNull AbstractInsnNode from, @NonNull AbstractInsnNode to) {
-        return isConnected(getNode(from), getNode(to));
-    }
-
-    /** A {@link Node} is a node in the control flow graph for a method, pointing to
-     * the instruction and its possible successors */
-    public static class Node {
-        /** The instruction */
-        public final AbstractInsnNode instruction;
-        /** Any normal successors (e.g. following instruction, or goto or conditional flow) */
-        public final List<Node> successors = new ArrayList<Node>(2);
-        /** Any abnormal successors (e.g. the handler to go to following an exception) */
-        public final List<Node> exceptions = new ArrayList<Node>(1);
-
-        /** A tag for use during depth-first-search iteration of the graph etc */
-        public int visit;
-
-        /**
-         * Constructs a new control graph node
-         *
-         * @param instruction the instruction to associate with this node
-         */
-        public Node(@NonNull AbstractInsnNode instruction) {
-            this.instruction = instruction;
-        }
-
-        void addSuccessor(@NonNull Node node) {
-            if (!successors.contains(node)) {
-                successors.add(node);
-            }
-        }
-
-        void addExceptionPath(@NonNull Node node) {
-            if (!exceptions.contains(node)) {
-                exceptions.add(node);
-            }
-        }
-
-        /**
-         * Represents this instruction as a string, for debugging purposes
-         *
-         * @param includeAdjacent whether it should include a display of
-         *            adjacent nodes as well
-         * @return a string representation
-         */
-        @NonNull
-        public String toString(boolean includeAdjacent) {
-            StringBuilder sb = new StringBuilder(100);
-
-            sb.append(getId(instruction));
-            sb.append(':');
-
-            if (instruction instanceof LabelNode) {
-                //LabelNode l = (LabelNode) instruction;
-                //sb.append('L' + l.getLabel().getOffset() + ":");
-                //sb.append('L' + l.getLabel().info + ":");
-                sb.append("LABEL");
-            } else if (instruction instanceof LineNumberNode) {
-                sb.append("LINENUMBER ").append(((LineNumberNode)instruction).line);
-            } else if (instruction instanceof FrameNode) {
-                sb.append("FRAME");
-            } else {
-                int opcode = instruction.getOpcode();
-                String opcodeName = getOpcodeName(opcode);
-                sb.append(opcodeName);
-                if (instruction.getType() == AbstractInsnNode.METHOD_INSN) {
-                    sb.append('(').append(((MethodInsnNode)instruction).name).append(')');
-                }
-            }
-
-            if (includeAdjacent) {
-                if (successors != null && !successors.isEmpty()) {
-                    sb.append(" Next:");
-                    for (Node successor : successors) {
-                        sb.append(' ');
-                        sb.append(successor.toString(false));
-                    }
-                }
-
-                if (exceptions != null && !exceptions.isEmpty()) {
-                    sb.append(" Exceptions:");
-                    for (Node exception : exceptions) {
-                        sb.append(' ');
-                        sb.append(exception.toString(false));
-                    }
-                }
-                sb.append('\n');
-            }
-
-            return sb.toString();
-        }
-    }
-
-    /** Adds an exception flow to this graph */
-    protected void add(@NonNull AbstractInsnNode from, @NonNull AbstractInsnNode to) {
-        getNode(from).addSuccessor(getNode(to));
-    }
-
-    /** Adds an exception flow to this graph */
-    protected void exception(@NonNull AbstractInsnNode from, @NonNull AbstractInsnNode to) {
-        // For now, these edges appear useless; we also get more specific
-        // information via the TryCatchBlockNode which we use instead.
-        //getNode(from).addExceptionPath(getNode(to));
-    }
-
-    /** Adds an exception try block node to this graph */
-    protected void exception(@NonNull AbstractInsnNode from, @NonNull TryCatchBlockNode tcb) {
-        // Add tcb's to all instructions in the range
-        LabelNode start = tcb.start;
-        LabelNode end = tcb.end; // exclusive
-
-        // Add exception edges for all method calls in the range
-        AbstractInsnNode curr = start;
-        Node handlerNode = getNode(tcb.handler);
-        while (curr != end && curr != null) {
-            // A method can throw can exception, or a throw instruction directly
-            if (curr.getType() == AbstractInsnNode.METHOD_INSN
-                    || (curr.getType() == AbstractInsnNode.INSN
-                    && curr.getOpcode() == Opcodes.ATHROW)) {
-                // Method call; add exception edge to handler
-                if (tcb.type == null) {
-                    // finally block: not an exception path
-                    getNode(curr).addSuccessor(handlerNode);
-                }
-                getNode(curr).addExceptionPath(handlerNode);
-            }
-            curr = curr.getNext();
-        }
-    }
-
-    /**
-     * Looks up (and if necessary) creates a graph node for the given instruction
-     *
-     * @param instruction the instruction
-     * @return the control flow graph node corresponding to the given
-     *         instruction
-     */
-    @NonNull
-    public Node getNode(@NonNull AbstractInsnNode instruction) {
-        Node node = mNodeMap.get(instruction);
-        if (node == null) {
-            node = new Node(instruction);
-            mNodeMap.put(instruction, node);
-        }
-
-        return node;
-    }
-
-    /**
-     * Creates a human readable version of the graph
-     *
-     * @param start the starting instruction, or null if not known or to use the
-     *            first instruction
-     * @return a string version of the graph
-     */
-    @NonNull
-    public String toString(@Nullable Node start) {
-        StringBuilder sb = new StringBuilder(400);
-
-        AbstractInsnNode curr;
-        if (start != null) {
-            curr = start.instruction;
-        } else {
-            if (mNodeMap.isEmpty()) {
-                return "<empty>";
-            } else {
-                curr = mNodeMap.keySet().iterator().next();
-                while (curr.getPrevious() != null) {
-                    curr = curr.getPrevious();
-                }
-            }
-        }
-
-        while (curr != null) {
-            Node node = mNodeMap.get(curr);
-            if (node != null) {
-                sb.append(node.toString(true));
-            }
-            curr = curr.getNext();
-        }
-
-        return sb.toString();
-    }
-
-    @Override
-    public String toString() {
-        return toString(null);
-    }
-
-    // ---- For debugging only ----
-
-    private static Map<Object, String> sIds = null;
-    private static int sNextId = 1;
-    private static String getId(Object object) {
-        if (sIds == null) {
-            sIds = Maps.newHashMap();
-        }
-        String id = sIds.get(object);
-        if (id == null) {
-            id = Integer.toString(sNextId++);
-            sIds.put(object, id);
-        }
-        return id;
-    }
-
-    /**
-     * Generates dot output of the graph. This can be used with
-     * graphwiz to visualize the graph. For example, if you
-     * save the output as graph1.gv you can run
-     * <pre>
-     * $ dot -Tps graph1.gv -o graph1.ps
-     * </pre>
-     * to generate a postscript file, which you can then view
-     * with "gv graph1.ps".
-     *
-     * (There are also some online web sites where you can
-     * paste in dot graphs and see the visualization right
-     * there in the browser.)
-     *
-     * @return a dot description of this control flow graph,
-     *    useful for debugging
-     */
-    @SuppressWarnings("unused")
-    public String toDot(@Nullable Set<Node> highlight) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("digraph G {\n");
-
-
-        AbstractInsnNode instruction = mMethod.instructions.getFirst();
-
-        // Special start node
-        sb.append("  start -> ").append(getId(mNodeMap.get(instruction))).append(";\n");
-        sb.append("  start [shape=plaintext];\n");
-
-        while (instruction != null) {
-            Node node = mNodeMap.get(instruction);
-            if (node != null) {
-                if (node.successors != null) {
-                    for (Node to : node.successors) {
-                        sb.append("  ").append(getId(node)).append(" -> ").append(getId(to));
-                        if (node.instruction instanceof JumpInsnNode) {
-                            sb.append(" [label=\"");
-                            if (((JumpInsnNode)node.instruction).label == to.instruction) {
-                                sb.append("yes");
-                            } else {
-                                sb.append("no");
-                            }
-                            sb.append("\"]");
-                        }
-                        sb.append(";\n");
-                    }
-                }
-                if (node.exceptions != null) {
-                    for (Node to : node.exceptions) {
-                        sb.append(getId(node)).append(" -> ").append(getId(to));
-                        sb.append(" [label=\"exception\"];\n");
-                    }
-                }
-            }
-
-            instruction = instruction.getNext();
-        }
-
-
-        // Labels
-        sb.append("\n");
-        for (Node node : mNodeMap.values()) {
-            instruction = node.instruction;
-            sb.append("  ").append(getId(node)).append(" ");
-            sb.append("[label=\"").append(dotDescribe(node)).append("\"");
-            if (highlight != null && highlight.contains(node)) {
-                sb.append(",shape=box,style=filled");
-            } else if (instruction instanceof LineNumberNode ||
-              instruction instanceof LabelNode ||
-              instruction instanceof FrameNode) {
-                sb.append(",shape=oval,style=dotted");
-            } else {
-                sb.append(",shape=box");
-            }
-            sb.append("];\n");
-        }
-
-        sb.append("}");
-        return sb.toString();
-    }
-
-    private static String dotDescribe(Node node) {
-        AbstractInsnNode instruction = node.instruction;
-        if (instruction instanceof LabelNode) {
-            return "Label";
-        } else if (instruction instanceof LineNumberNode) {
-            LineNumberNode lineNode = (LineNumberNode)instruction;
-            return "Line " + lineNode.line;
-        } else if (instruction instanceof FrameNode) {
-            return "Stack Frame";
-        } else if (instruction instanceof MethodInsnNode) {
-            MethodInsnNode method = (MethodInsnNode)instruction;
-            String cls = method.owner.substring(method.owner.lastIndexOf('/') + 1);
-            cls = cls.replace('$','.');
-            return "Call " + cls + "#" + method.name;
-        } else if (instruction instanceof FieldInsnNode) {
-            FieldInsnNode field = (FieldInsnNode) instruction;
-            String cls = field.owner.substring(field.owner.lastIndexOf('/') + 1);
-            cls = cls.replace('$','.');
-            return "Field " + cls + "#" + field.name;
-        } else if (instruction instanceof TypeInsnNode && instruction.getOpcode() == Opcodes.NEW) {
-            return "New " + ((TypeInsnNode)instruction).desc;
-        }
-        StringBuilder sb = new StringBuilder();
-        String opcodeName = getOpcodeName(instruction.getOpcode());
-        sb.append(opcodeName);
-
-        if (instruction instanceof IntInsnNode) {
-            IntInsnNode in = (IntInsnNode) instruction;
-            sb.append(" ").append(Integer.toString(in.operand));
-        } else if (instruction instanceof LdcInsnNode) {
-            LdcInsnNode ldc = (LdcInsnNode) instruction;
-            sb.append(" ");
-            if (ldc.cst instanceof String) {
-                sb.append("\\\"");
-            }
-            sb.append(ldc.cst);
-            if (ldc.cst instanceof String) {
-                sb.append("\\\"");
-            }
-        }
-        return sb.toString();
-    }
-
-    private static String getOpcodeName(int opcode) {
-        if (sOpcodeNames == null) {
-            sOpcodeNames = new String[255];
-            try {
-                Field[] fields = Opcodes.class.getDeclaredFields();
-                for (Field field : fields) {
-                    if (field.getType() == int.class) {
-                        String name = field.getName();
-                        if (name.startsWith("ASM") || name.startsWith("V1_") ||
-                            name.startsWith("ACC_") || name.startsWith("T_") ||
-                            name.startsWith("H_") || name.startsWith("F_")) {
-                            continue;
-                        }
-                        int val = field.getInt(null);
-                        if (val >= 0 && val < sOpcodeNames.length) {
-                            sOpcodeNames[val] = field.getName();
-                        }
-
-                    }
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        if (opcode >= 0 && opcode < sOpcodeNames.length) {
-            String name = sOpcodeNames[opcode];
-            if (name != null) {
-                return name;
-            }
-        }
-
-        return Integer.toString(opcode);
-    }
-
-    private static String[] sOpcodeNames;
-}
-
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CustomViewDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CustomViewDetector.java
deleted file mode 100644
index 934fb6f..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CustomViewDetector.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.*;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-import static com.android.SdkConstants.*;
-import static com.android.tools.klint.detector.api.LintUtils.skipParentheses;
-
-/**
- * Makes sure that custom views use a declare styleable that matches
- * the name of the custom view
- */
-public class CustomViewDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            CustomViewDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Mismatched style and class names */
-    public static final Issue ISSUE = Issue.create(
-            "CustomViewStyleable", //$NON-NLS-1$
-            "Mismatched Styleable/Custom View Name",
-
-            "The convention for custom views is to use a `declare-styleable` whose name " +
-            "matches the custom view class name. The IDE relies on this convention such that " +
-            "for example code completion can be offered for attributes in a custom view " +
-            "in layout XML resource files.\n" +
-            "\n" +
-            "(Similarly, layout parameter classes should use the suffix `_Layout`.)",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    private static final String OBTAIN_STYLED_ATTRIBUTES = "obtainStyledAttributes"; //$NON-NLS-1$
-
-    /** Constructs a new {@link CustomViewDetector} check */
-    public CustomViewDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(OBTAIN_STYLED_ATTRIBUTES);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        if (skipParentheses(node.getUastParent()) instanceof UExpression) {
-            if (!context.getEvaluator().isMemberInSubClassOf(method, CLASS_CONTEXT, false)) {
-                return;
-            }
-            List<UExpression> arguments = node.getValueArguments();
-            int size = arguments.size();
-            // Which parameter contains the styleable (attrs) ?
-            int parameterIndex;
-            if (size == 1) {
-                // obtainStyledAttributes(int[] attrs)
-                parameterIndex = 0;
-            } else {
-                // obtainStyledAttributes(int resid, int[] attrs)
-                // obtainStyledAttributes(AttributeSet set, int[] attrs)
-                // obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
-                parameterIndex = 1;
-            }
-            UExpression expression = arguments.get(parameterIndex);
-            if (!UastUtils.startsWithQualified(expression, R_STYLEABLE_PREFIX)) {
-                return;
-            }
-
-            List<String> path = UastUtils.asQualifiedPath(expression);
-            if (path == null || path.size() < 3) {
-                return;
-            }
-
-            String styleableName = path.get(2);
-            UClass cls = UastUtils.getParentOfType(node, UClass.class, false);
-            if (cls == null) {
-                return;
-            }
-
-            String className = cls.getName();
-            if (InheritanceUtil.isInheritor(cls, false, CLASS_VIEW)) {
-                if (!styleableName.equals(className)) {
-                    String message = String.format(
-                            "By convention, the custom view (`%1$s`) and the declare-styleable (`%2$s`) "
-                                    + "should have the same name (various editor features rely on "
-                                    + "this convention)",
-                            className, styleableName);
-                    context.report(ISSUE, node, context.getUastLocation(expression), message);
-                }
-            } else if (InheritanceUtil.isInheritor(cls, false,
-                    CLASS_VIEWGROUP + DOT_LAYOUT_PARAMS)) {
-                PsiClass outer = PsiTreeUtil.getParentOfType(cls, PsiClass.class, true);
-                if (outer == null) {
-                    return;
-                }
-                String layoutClassName = outer.getName();
-                String expectedName = layoutClassName + "_Layout";
-                if (!styleableName.equals(expectedName)) {
-                    String message = String.format(
-                            "By convention, the declare-styleable (`%1$s`) for a layout parameter "
-                                    + "class (`%2$s`) is expected to be the surrounding "
-                                    + "class (`%3$s`) plus \"`_Layout`\", e.g. `%4$s`. "
-                                    + "(Various editor features rely on this convention.)",
-                            styleableName, className, layoutClassName, expectedName);
-                    context.report(ISSUE, node, context.getUastLocation(expression), message);
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java
deleted file mode 100644
index b37e857..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.collect.Maps;
-import com.intellij.psi.PsiMethod;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.SdkConstants.RESOURCE_CLZ_ID;
-
-/**
- * Detector looking for cut &amp; paste issues
- */
-public class CutPasteDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "CutPasteId", //$NON-NLS-1$
-            "Likely cut & paste mistakes",
-
-            "This lint check looks for cases where you have cut & pasted calls to " +
-            "`findViewById` but have forgotten to update the R.id field. It's possible " +
-            "that your code is simply (redundantly) looking up the field repeatedly, " +
-            "but lint cannot distinguish that from a case where you for example want to " +
-            "initialize fields `prev` and `next` and you cut & pasted `findViewById(R.id.prev)` " +
-            "and forgot to update the second initialization to `R.id.next`.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    CutPasteDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    private PsiMethod mLastMethod;
-    private Map<String, UCallExpression> mIds;
-    private Map<String, String> mLhs;
-    private Map<String, String> mCallOperands;
-
-    /** Constructs a new {@link CutPasteDetector} check */
-    public CutPasteDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("findViewById"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod calledMethod) {
-        String lhs = getLhs(call);
-        if (lhs == null) {
-            return;
-        }
-
-        UMethod method = UastUtils.getParentOfType(call, UMethod.class, false);
-        if (method == null) {
-            return; // prevent doing the same work for multiple findViewById calls in same method
-        } else if (method != mLastMethod) {
-            mIds = Maps.newHashMap();
-            mLhs = Maps.newHashMap();
-            mCallOperands = Maps.newHashMap();
-            mLastMethod = method;
-        }
-        
-        String callOperand = call.getReceiver() != null
-                             ? call.getReceiver().asSourceString() : "";
-
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.isEmpty()) {
-            return;
-        }
-        UExpression first = arguments.get(0);
-        if (first instanceof UReferenceExpression) {
-            UReferenceExpression psiReferenceExpression = (UReferenceExpression) first;
-            String id = psiReferenceExpression.getResolvedName();
-            UElement operand = (first instanceof UQualifiedReferenceExpression)
-                    ? ((UQualifiedReferenceExpression) first).getReceiver()
-                    : null;
-            
-            if (operand instanceof UReferenceExpression) {
-                UReferenceExpression type = (UReferenceExpression) operand;
-                if (RESOURCE_CLZ_ID.equals(type.getResolvedName())) {
-                    if (mIds.containsKey(id)) {
-                        if (lhs.equals(mLhs.get(id))) {
-                            return;
-                        }
-                        if (!callOperand.equals(mCallOperands.get(id))) {
-                            return;
-                        }
-                        UCallExpression earlierCall = mIds.get(id);
-                        if (!isReachableFrom(method, earlierCall, call)) {
-                            return;
-                        }
-                        Location location = context.getUastLocation(call);
-                        Location secondary = context.getUastLocation(earlierCall);
-                        secondary.setMessage("First usage here");
-                        location.setSecondary(secondary);
-                        context.report(ISSUE, call, location, String.format(
-                                "The id `%1$s` has already been looked up in this method; possible "
-                                        +
-                                        "cut & paste error?", first.asSourceString()));
-                    } else {
-                        mIds.put(id, call);
-                        mLhs.put(id, lhs);
-                        mCallOperands.put(id, callOperand);
-                    }
-                }
-
-            }
-        }
-    }
-
-    @Nullable
-    private static String getLhs(@NonNull UCallExpression call) {
-        UElement parent = call.getUastParent();
-        while (parent != null && !(parent instanceof UBlockExpression)) {
-            if (parent instanceof ULocalVariable) {
-                return ((ULocalVariable) parent).getName();
-            } else if (UastExpressionUtils.isAssignment(parent)) {
-                UExpression left = ((UBinaryExpression) parent).getLeftOperand();
-                if (left instanceof UReferenceExpression) {
-                    return left.asSourceString();
-                } else if (left instanceof UArrayAccessExpression) {
-                    UArrayAccessExpression aa = (UArrayAccessExpression) left;
-                    return aa.getReceiver().asSourceString();
-                }
-            }
-            parent = parent.getUastParent();
-        }
-        return null;
-    }
-
-    static boolean isReachableFrom(
-            @NonNull UMethod method,
-            @NonNull UElement from,
-            @NonNull UElement to) {
-        ReachabilityVisitor visitor = new ReachabilityVisitor(from, to);
-        method.accept(visitor);
-        return visitor.isReachable();
-    }
-
-    private static class ReachabilityVisitor extends AbstractUastVisitor {
-
-        private final UElement mFrom;
-        private final UElement mTarget;
-
-        private boolean mIsFromReached;
-        private boolean mIsTargetReachable;
-        private boolean mIsFinished;
-
-        private UExpression mBreakedExpression;
-        private UExpression mContinuedExpression;
-
-        ReachabilityVisitor(UElement from, UElement target) {
-            mFrom = from;
-            mTarget = target;
-        }
-
-        @Override
-        public boolean visitElement(UElement node) {
-            if (mIsFinished || mBreakedExpression != null || mContinuedExpression != null) {
-                return true;
-            }
-
-            if (node.equals(mFrom)) {
-                mIsFromReached = true;
-            }
-
-            if (node.equals(mTarget)) {
-                mIsFinished = true;
-                if (mIsFromReached) {
-                    mIsTargetReachable = true;
-                }
-                return true;
-            }
-
-            if (mIsFromReached) {
-                if (node instanceof UReturnExpression) {
-                    mIsFinished = true;
-                } else if (node instanceof UBreakExpression) {
-                    mBreakedExpression = getBreakedExpression((UBreakExpression) node);
-                } else if (node instanceof UContinueExpression) {
-                    UExpression expression = getContinuedExpression((UContinueExpression) node);
-                    if (expression != null && UastUtils.isChildOf(mTarget, expression, false)) {
-                        mIsTargetReachable = true;
-                        mIsFinished = true;
-                    } else {
-                        mContinuedExpression = expression;
-                    }
-                } else if (UastUtils.isChildOf(mTarget, node, false)) {
-                    mIsTargetReachable = true;
-                    mIsFinished = true;
-                }
-                return true;
-            } else {
-                if (node instanceof UIfExpression) {
-                    UIfExpression ifExpression = (UIfExpression) node;
-
-                    ifExpression.getCondition().accept(this);
-
-                    boolean isFromReached = mIsFromReached;
-
-                    UExpression thenExpression = ifExpression.getThenExpression();
-                    if (thenExpression != null) {
-                        thenExpression.accept(this);
-                    }
-
-                    UExpression elseExpression = ifExpression.getElseExpression();
-                    if (elseExpression != null && isFromReached == mIsFromReached) {
-                        elseExpression.accept(this);
-                    }
-                    return true;
-                } else if (node instanceof ULoopExpression) {
-                    visitLoopExpressionHeader(node);
-                    boolean isFromReached = mIsFromReached;
-
-                    ((ULoopExpression) node).getBody().accept(this);
-
-                    if (isFromReached != mIsFromReached
-                        && UastUtils.isChildOf(mTarget, node, false)) {
-                        mIsTargetReachable = true;
-                        mIsFinished = true;
-                    }
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        @Override
-        public void afterVisitElement(UElement node) {
-            if (node.equals(mBreakedExpression)) {
-                mBreakedExpression = null;
-            } else if (node.equals(mContinuedExpression)) {
-                mContinuedExpression = null;
-            }
-        }
-
-        private void visitLoopExpressionHeader(UElement node) {
-            if (node instanceof UWhileExpression) {
-                ((UWhileExpression) node).getCondition().accept(this);
-            } else if (node instanceof UDoWhileExpression) {
-                ((UDoWhileExpression) node).getCondition().accept(this);
-            } else if (node instanceof UForExpression) {
-                UForExpression forExpression = (UForExpression) node;
-
-                if (forExpression.getDeclaration() != null) {
-                    forExpression.getDeclaration().accept(this);
-                }
-
-                if (forExpression.getCondition() != null) {
-                    forExpression.getCondition().accept(this);
-                }
-
-                if (forExpression.getUpdate() != null) {
-                    forExpression.getUpdate().accept(this);
-                }
-            } else if (node instanceof UForEachExpression) {
-                UForEachExpression forEachExpression = (UForEachExpression) node;
-                forEachExpression.getForIdentifier().accept(this);
-                forEachExpression.getIteratedValue().accept(this);
-            }
-        }
-
-        private static UExpression getBreakedExpression(UBreakExpression node) {
-            UElement parent = node.getUastParent();
-            String label = node.getLabel();
-            while (parent != null) {
-                if (label != null) {
-                    if (parent instanceof ULabeledExpression) {
-                        ULabeledExpression labeledExpression = (ULabeledExpression) parent;
-                        if (labeledExpression.getLabel().equals(label)) {
-                            return labeledExpression.getExpression();
-                        }
-                    }
-                } else {
-                    if (parent instanceof ULoopExpression || parent instanceof USwitchExpression) {
-                        return (UExpression) parent;
-                    }
-                }
-                parent = parent.getUastParent();
-            }
-            return null;
-        }
-
-        private static UExpression getContinuedExpression(UContinueExpression node) {
-            UElement parent = node.getUastParent();
-            String label = node.getLabel();
-            while (parent != null) {
-                if (label != null) {
-                    if (parent instanceof ULabeledExpression) {
-                        ULabeledExpression labeledExpression = (ULabeledExpression) parent;
-                        if (labeledExpression.getLabel().equals(label)) {
-                            return labeledExpression.getExpression();
-                        }
-                    }
-                } else {
-                    if (parent instanceof ULoopExpression) {
-                        return (UExpression) parent;
-                    }
-                }
-                parent = parent.getUastParent();
-            }
-            return null;
-        }
-
-        public boolean isReachable() {
-            return mIsTargetReachable;
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/DateFormatDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/DateFormatDetector.java
deleted file mode 100644
index b5bc84e..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/DateFormatDetector.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiParameterList;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for errors related to Date Formats
- */
-public class DateFormatDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            DateFormatDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Constructing SimpleDateFormat without an explicit locale */
-    public static final Issue DATE_FORMAT = Issue.create(
-            "SimpleDateFormat", //$NON-NLS-1$
-            "Implied locale in date format",
-
-            "Almost all callers should use `getDateInstance()`, `getDateTimeInstance()`, or " +
-            "`getTimeInstance()` to get a ready-made instance of SimpleDateFormat suitable " +
-            "for the user's locale. The main reason you'd create an instance this class " +
-            "directly is because you need to format/parse a specific machine-readable format, " +
-            "in which case you almost certainly want to explicitly ask for US to ensure that " +
-            "you get ASCII digits (rather than, say, Arabic digits).\n" +
-            "\n" +
-            "Therefore, you should either use the form of the SimpleDateFormat constructor " +
-            "where you pass in an explicit locale, such as Locale.US, or use one of the " +
-            "get instance methods, or suppress this error if really know what you are doing.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo(
-            "http://developer.android.com/reference/java/text/SimpleDateFormat.html");//$NON-NLS-1$
-
-    public static final String LOCALE_CLS = "java.util.Locale";                       //$NON-NLS-1$
-    public static final String SIMPLE_DATE_FORMAT_CLS = "java.text.SimpleDateFormat"; //$NON-NLS-1$
-
-    /** Constructs a new {@link DateFormatDetector} */
-    public DateFormatDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableConstructorTypes() {
-        return Collections.singletonList(SIMPLE_DATE_FORMAT_CLS);
-    }
-
-    @Override
-    public void visitConstructor(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod constructor) {
-        if (!specifiesLocale(constructor)) {
-            Location location = context.getUastLocation(node);
-            String message =
-                    "To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, " +
-                            "or `getTimeInstance()`, or use `new SimpleDateFormat(String template, " +
-                            "Locale locale)` with for example `Locale.US` for ASCII dates.";
-            context.report(DATE_FORMAT, node, location, message);
-        }
-    }
-
-    private static boolean specifiesLocale(@NonNull PsiMethod method) {
-        PsiParameterList parameterList = method.getParameterList();
-        PsiParameter[] parameters = parameterList.getParameters();
-        for (PsiParameter parameter : parameters) {
-            PsiType type = parameter.getType();
-            if (type.getCanonicalText().equals(LOCALE_CLS)) {
-                    return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/FragmentDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/FragmentDetector.java
deleted file mode 100644
index 79d9756..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/FragmentDetector.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_FRAGMENT;
-import static com.android.SdkConstants.CLASS_V4_FRAGMENT;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UAnonymousClass;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Checks that Fragment subclasses can be instantiated via
- * {link {@link Class#newInstance()}}: the class is public, static, and has
- * a public null constructor.
- * <p>
- * This helps track down issues like
- *   http://stackoverflow.com/questions/8058809/fragment-activity-crashes-on-screen-rotate
- * (and countless duplicates)
- */
-public class FragmentDetector extends Detector implements Detector.UastScanner {
-    /** Are fragment subclasses instantiatable? */
-    public static final Issue ISSUE = Issue.create(
-        "ValidFragment", //$NON-NLS-1$
-        "Fragment not instantiatable",
-
-        "From the Fragment documentation:\n" +
-        "*Every* fragment must have an empty constructor, so it can be instantiated when " +
-        "restoring its activity's state. It is strongly recommended that subclasses do not " +
-        "have other constructors with parameters, since these constructors will not be " +
-        "called when the fragment is re-instantiated; instead, arguments can be supplied " +
-        "by the caller with `setArguments(Bundle)` and later retrieved by the Fragment " +
-        "with `getArguments()`.",
-
-        Category.CORRECTNESS,
-        6,
-        Severity.FATAL,
-        new Implementation(
-                FragmentDetector.class,
-                Scope.JAVA_FILE_SCOPE)
-        ).addMoreInfo(
-            "http://developer.android.com/reference/android/app/Fragment.html#Fragment()"); //$NON-NLS-1$
-
-
-    /** Constructs a new {@link FragmentDetector} */
-    public FragmentDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Arrays.asList(CLASS_FRAGMENT, CLASS_V4_FRAGMENT);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass node) {
-        if (node instanceof UAnonymousClass) {
-            String message = "Fragments should be static such that they can be re-instantiated by " +
-                    "the system, and anonymous classes are not static";
-            context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isAbstract(node)) {
-            return;
-        }
-
-        if (!evaluator.isPublic(node)) {
-            String message = String.format("This fragment class should be public (%1$s)",
-                    node.getQualifiedName());
-            context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
-            return;
-        }
-
-        if (node.getContainingClass() != null && !evaluator.isStatic(node)) {
-            String message = String.format(
-                    "This fragment inner class should be static (%1$s)", node.getQualifiedName());
-            context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
-            return;
-        }
-
-        boolean hasDefaultConstructor = false;
-        boolean hasConstructor = false;
-        for (PsiMethod constructor : node.getConstructors()) {
-            hasConstructor = true;
-            if (constructor.getParameterList().getParametersCount() == 0) {
-                if (evaluator.isPublic(constructor)) {
-                    hasDefaultConstructor = true;
-                } else {
-                    Location location = context.getNameLocation(constructor);
-                    context.report(ISSUE, constructor, location,
-                            "The default constructor must be public");
-                    // Also mark that we have a constructor so we don't complain again
-                    // below since we've already emitted a more specific error related
-                    // to the default constructor
-                    hasDefaultConstructor = true;
-                }
-            } else {
-                Location location = context.getNameLocation(constructor);
-                // TODO: Use separate issue for this which isn't an error
-                String message = "Avoid non-default constructors in fragments: "
-                        + "use a default constructor plus "
-                        + "`Fragment#setArguments(Bundle)` instead";
-                context.report(ISSUE, constructor, location, message);
-            }
-        }
-
-        if (!hasDefaultConstructor && hasConstructor) {
-            String message = String.format(
-                    "This fragment should provide a default constructor (a public " +
-                            "constructor with no arguments) (`%1$s`)",
-                    node.getQualifiedName());
-            context.reportUast(ISSUE, node, context.getNameLocation(node), message);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/GetSignaturesDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/GetSignaturesDetector.java
deleted file mode 100644
index a43817a..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/GetSignaturesDetector.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.JavaParser;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-public class GetSignaturesDetector extends Detector implements Detector.UastScanner {
-    public static final Issue ISSUE = Issue.create(
-            "PackageManagerGetSignatures", //$NON-NLS-1$
-            "Potential Multiple Certificate Exploit",
-            "Improper validation of app signatures could lead to issues where a malicious app " +
-            "submits itself to the Play Store with both its real certificate and a fake " +
-            "certificate and gains access to functionality or information it shouldn't " +
-            "have due to another application only checking for the fake certificate and " +
-            "ignoring the rest. Please make sure to validate all signatures returned " +
-            "by this method.",
-            Category.SECURITY,
-            8,
-            Severity.INFORMATIONAL,
-            new Implementation(
-                    GetSignaturesDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo("https://bluebox.com/technical/android-fake-id-vulnerability/");
-
-    private static final String PACKAGE_MANAGER_CLASS = "android.content.pm.PackageManager"; //$NON-NLS-1$
-    private static final String GET_PACKAGE_INFO = "getPackageInfo"; //$NON-NLS-1$
-    private static final int GET_SIGNATURES_FLAG = 0x00000040; //$NON-NLS-1$
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    @Nullable
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(GET_PACKAGE_INFO);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!evaluator.methodMatches(method, PACKAGE_MANAGER_CLASS, true,
-                JavaParser.TYPE_STRING,
-                JavaParser.TYPE_INT)) {
-            return;
-        }
-
-        List<UExpression> arguments = node.getValueArguments();
-        UExpression second = arguments.get(1);
-        Object number = ConstantEvaluator.evaluate(context, second);
-        if (number instanceof Number) {
-            int flagValue = ((Number)number).intValue();
-            maybeReportIssue(flagValue, context, node, second);
-        }
-    }
-    
-    private static void maybeReportIssue(
-            int flagValue, JavaContext context, UCallExpression node,
-            UExpression last) {
-        if ((flagValue & GET_SIGNATURES_FLAG) != 0) {
-            context.report(ISSUE, node, context.getUastLocation(last),
-                "Reading app signatures from getPackageInfo: The app signatures "
-                    + "could be exploited if not validated properly; "
-                    + "see issue explanation for details.");
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/HandlerDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/HandlerDetector.java
deleted file mode 100644
index 59a8517..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/HandlerDetector.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.intellij.psi.util.PsiTreeUtil.getParentOfType;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UAnonymousClass;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UObjectLiteralExpression;
-import org.jetbrains.uast.UastUtils;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks that Handler implementations are top level classes or static.
- * See the corresponding check in the android.os.Handler source code.
- */
-public class HandlerDetector extends Detector implements Detector.UastScanner {
-
-    /** Potentially leaking handlers */
-    public static final Issue ISSUE = Issue.create(
-            "HandlerLeak", //$NON-NLS-1$
-            "Handler reference leaks",
-
-            "Since this Handler is declared as an inner class, it may prevent the outer " +
-            "class from being garbage collected. If the Handler is using a Looper or " +
-            "MessageQueue for a thread other than the main thread, then there is no issue. " +
-            "If the Handler is using the Looper or MessageQueue of the main thread, you " +
-            "need to fix your Handler declaration, as follows: Declare the Handler as a " +
-            "static class; In the outer class, instantiate a WeakReference to the outer " +
-            "class and pass this object to your Handler when you instantiate the Handler; " +
-            "Make all references to members of the outer class using the WeakReference object.",
-
-            Category.PERFORMANCE,
-            4,
-            Severity.WARNING,
-            new Implementation(
-                    HandlerDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    private static final String LOOPER_CLS = "android.os.Looper";
-    private static final String HANDLER_CLS = "android.os.Handler";
-
-    /** Constructs a new {@link HandlerDetector} */
-    public HandlerDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(HANDLER_CLS);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        // Only consider static inner classes
-        if (context.getEvaluator().isStatic(declaration)) {
-            return;
-        }
-        boolean isAnonymous = declaration instanceof UAnonymousClass;
-        if (declaration.getContainingClass() == null && !isAnonymous) {
-            return;
-        }
-
-        //// Only flag handlers using the default looper
-        //noinspection unchecked
-        UCallExpression invocation = UastUtils.getParentOfType(
-                declaration, UObjectLiteralExpression.class, true, UMethod.class);
-        if (invocation != null) {
-            if (isAnonymous && invocation.getValueArgumentCount() > 0) {
-                for (UExpression expression : invocation.getValueArguments()) {
-                    PsiType type = expression.getExpressionType();
-                    if (type instanceof PsiClassType
-                            && LOOPER_CLS.equals(type.getCanonicalText())) {
-                        return;
-                    }
-                }
-            }
-        } else if (hasLooperConstructorParameter(declaration)) {
-            // This is an inner class which takes a Looper parameter:
-            // possibly used correctly from elsewhere
-            return;
-        }
-        
-        Location location = context.getUastNameLocation(declaration);
-        String name;
-        if (isAnonymous) {
-            name = "anonymous " + ((UAnonymousClass)declaration).getBaseClassReference().getQualifiedName();
-        } else {
-            name = declaration.getQualifiedName();
-        }
-
-        //noinspection VariableNotUsedInsideIf
-        context.reportUast(ISSUE, declaration, location, String.format(
-                "This Handler class should be static or leaks might occur (%1$s)",
-                name));
-
-    }
-
-    private static boolean hasLooperConstructorParameter(@NonNull PsiClass cls) {
-        for (PsiMethod constructor : cls.getConstructors()) {
-            for (PsiParameter parameter : constructor.getParameterList().getParameters()) {
-                PsiType type = parameter.getType();
-                if (LOOPER_CLS.equals(type.getCanonicalText())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java
deleted file mode 100644
index 12f6a26..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java
+++ /dev/null
@@ -1,2049 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.ProductFlavor;
-import com.android.builder.model.ProductFlavorContainer;
-import com.android.resources.ResourceUrl;
-import com.android.resources.Density;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.collect.*;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Element;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.stream.ImageInputStream;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.android.SdkConstants.*;
-import static com.android.tools.klint.detector.api.LintUtils.endsWith;
-
-/**
- * Checks for common icon problems, such as wrong icon sizes, placing icons in the
- * density independent drawable folder, etc.
- */
-public class IconDetector extends ResourceXmlDetector implements Detector.UastScanner {
-
-    private static final boolean INCLUDE_LDPI;
-    static {
-        boolean includeLdpi = false;
-
-        String value = System.getenv("ANDROID_LINT_INCLUDE_LDPI"); //$NON-NLS-1$
-        if (value != null) {
-            includeLdpi = Boolean.valueOf(value);
-        }
-        INCLUDE_LDPI = includeLdpi;
-    }
-
-    /** Pattern for the expected density folders to be found in the project */
-    private static final Pattern DENSITY_PATTERN = Pattern.compile(
-            "^drawable-(nodpi|xxxhdpi|xxhdpi|xhdpi|hdpi|mdpi"     //$NON-NLS-1$
-                + (INCLUDE_LDPI ? "|ldpi" : "") + ")$");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
-    /** Pattern for icon names that include their dp size as part of the name */
-    private static final Pattern DP_NAME_PATTERN = Pattern.compile(".+_(\\d+)dp\\.png"); //$NON-NLS-1$
-
-    /** Cache for {@link #getRequiredDensityFolders(Context)} */
-    private List<String> mCachedRequiredDensities;
-    /** Cache key for {@link #getRequiredDensityFolders(Context)} */
-    private Project mCachedDensitiesForProject;
-
-    // TODO: Convert this over to using the Density enum and FolderConfiguration
-    // for qualifier lookup
-    private static final String[] DENSITY_QUALIFIERS =
-        new String[] {
-            "-ldpi",  //$NON-NLS-1$
-            "-mdpi",  //$NON-NLS-1$
-            "-hdpi",  //$NON-NLS-1$
-            "-xhdpi", //$NON-NLS-1$
-            "-xxhdpi",//$NON-NLS-1$
-            "-xxxhdpi",//$NON-NLS-1$
-    };
-
-    /** Scope needed to detect the types of icons (which involves scanning .java files,
-     * the manifest, menu files etc to see how icons are used
-     */
-    private static final EnumSet<Scope> ICON_TYPE_SCOPE = EnumSet.of(Scope.ALL_RESOURCE_FILES,
-            Scope.JAVA_FILE, Scope.MANIFEST);
-
-    private static final Implementation IMPLEMENTATION_JAVA = new Implementation(
-            IconDetector.class,
-            ICON_TYPE_SCOPE);
-
-    private static final Implementation IMPLEMENTATION_RES_ONLY = new Implementation(
-            IconDetector.class,
-            Scope.ALL_RESOURCES_SCOPE);
-
-    /** Wrong icon size according to published conventions */
-    public static final Issue ICON_EXPECTED_SIZE = Issue.create(
-            "IconExpectedSize", //$NON-NLS-1$
-            "Icon has incorrect size",
-            "There are predefined sizes (for each density) for launcher icons. You " +
-            "should follow these conventions to make sure your icons fit in with the " +
-            "overall look of the platform.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA)
-            // Still some potential false positives:
-            .setEnabledByDefault(false)
-            .addMoreInfo(
-                    "http://developer.android.com/design/style/iconography.html"); //$NON-NLS-1$
-
-    /** Inconsistent dip size across densities */
-    public static final Issue ICON_DIP_SIZE = Issue.create(
-            "IconDipSize", //$NON-NLS-1$
-            "Icon density-independent size validation",
-            "Checks the all icons which are provided in multiple densities, all compute to " +
-            "roughly the same density-independent pixel (`dip`) size. This catches errors where " +
-            "images are either placed in the wrong folder, or icons are changed to new sizes " +
-            "but some folders are forgotten.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Images in res/drawable folder */
-    public static final Issue ICON_LOCATION = Issue.create(
-            "IconLocation", //$NON-NLS-1$
-            "Image defined in density-independent drawable folder",
-            "The res/drawable folder is intended for density-independent graphics such as " +
-            "shapes defined in XML. For bitmaps, move it to `drawable-mdpi` and consider " +
-            "providing higher and lower resolution versions in `drawable-ldpi`, `drawable-hdpi` " +
-            "and `drawable-xhdpi`. If the icon *really* is density independent (for example " +
-            "a solid color) you can place it in `drawable-nodpi`.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY).addMoreInfo(
-            "http://developer.android.com/guide/practices/screens_support.html"); //$NON-NLS-1$
-
-    /** Missing density versions of image */
-    public static final Issue ICON_DENSITIES = Issue.create(
-            "IconDensities", //$NON-NLS-1$
-            "Icon densities validation",
-            "Icons will look best if a custom version is provided for each of the " +
-            "major screen density classes (low, medium, high, extra high). " +
-            "This lint check identifies icons which do not have complete coverage " +
-            "across the densities.\n" +
-            "\n" +
-            "Low density is not really used much anymore, so this check ignores " +
-            "the ldpi density. To force lint to include it, set the environment " +
-            "variable `ANDROID_LINT_INCLUDE_LDPI=true`. For more information on " +
-            "current density usage, see " +
-            "http://developer.android.com/resources/dashboard/screens.html",
-            Category.ICONS,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY).addMoreInfo(
-            "http://developer.android.com/guide/practices/screens_support.html"); //$NON-NLS-1$
-
-    /** Missing density folders */
-    public static final Issue ICON_MISSING_FOLDER = Issue.create(
-            "IconMissingDensityFolder", //$NON-NLS-1$
-            "Missing density folder",
-            "Icons will look best if a custom version is provided for each of the " +
-            "major screen density classes (low, medium, high, extra-high, extra-extra-high). " +
-            "This lint check identifies folders which are missing, such as `drawable-hdpi`.\n" +
-            "\n" +
-            "Low density is not really used much anymore, so this check ignores " +
-            "the ldpi density. To force lint to include it, set the environment " +
-            "variable `ANDROID_LINT_INCLUDE_LDPI=true`. For more information on " +
-            "current density usage, see " +
-            "http://developer.android.com/resources/dashboard/screens.html",
-            Category.ICONS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY).addMoreInfo(
-            "http://developer.android.com/guide/practices/screens_support.html"); //$NON-NLS-1$
-
-    /** Using .gif bitmaps */
-    public static final Issue GIF_USAGE = Issue.create(
-            "GifUsage", //$NON-NLS-1$
-            "Using `.gif` format for bitmaps is discouraged",
-            "The `.gif` file format is discouraged. Consider using `.png` (preferred) " +
-            "or `.jpg` (acceptable) instead.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY).addMoreInfo(
-            "http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap"); //$NON-NLS-1$
-
-    /** Duplicated icons across different names */
-    public static final Issue DUPLICATES_NAMES = Issue.create(
-            "IconDuplicates", //$NON-NLS-1$
-            "Duplicated icons under different names",
-            "If an icon is repeated under different names, you can consolidate and just " +
-            "use one of the icons and delete the others to make your application smaller. " +
-            "However, duplicated icons usually are not intentional and can sometimes point " +
-            "to icons that were accidentally overwritten or accidentally not updated.",
-            Category.ICONS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Duplicated contents across configurations for a given name */
-    public static final Issue DUPLICATES_CONFIGURATIONS = Issue.create(
-            "IconDuplicatesConfig", //$NON-NLS-1$
-            "Identical bitmaps across various configurations",
-            "If an icon is provided under different configuration parameters such as " +
-            "`drawable-hdpi` or `-v11`, they should typically be different. This detector " +
-            "catches cases where the same icon is provided in different configuration folder " +
-            "which is usually not intentional.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Icons appearing in both -nodpi and a -Ndpi folder */
-    public static final Issue ICON_NODPI = Issue.create(
-            "IconNoDpi", //$NON-NLS-1$
-            "Icon appears in both `-nodpi` and dpi folders",
-            "Bitmaps that appear in `drawable-nodpi` folders will not be scaled by the " +
-            "Android framework. If a drawable resource of the same name appears *both* in " +
-            "a `-nodpi` folder as well as a dpi folder such as `drawable-hdpi`, then " +
-            "the behavior is ambiguous and probably not intentional. Delete one or the " +
-            "other, or use different names for the icons.",
-            Category.ICONS,
-            7,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Drawables provided as both .9.png and .png files */
-    public static final Issue ICON_MIX_9PNG = Issue.create(
-            "IconMixedNinePatch", //$NON-NLS-1$
-            "Clashing PNG and 9-PNG files",
-
-            "If you accidentally name two separate resources `file.png` and `file.9.png`, " +
-            "the image file and the nine patch file will both map to the same drawable " +
-            "resource, `@drawable/file`, which is probably not what was intended.",
-            Category.ICONS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Icons appearing as both drawable xml files and bitmaps */
-    public static final Issue ICON_XML_AND_PNG = Issue.create(
-            "IconXmlAndPng", //$NON-NLS-1$
-            "Icon is specified both as `.xml` file and as a bitmap",
-            "If a drawable resource appears as an `.xml` file in the `drawable/` folder, " +
-            "it's usually not intentional for it to also appear as a bitmap using the " +
-            "same name; generally you expect the drawable XML file to define states " +
-            "and each state has a corresponding drawable bitmap.",
-            Category.ICONS,
-            7,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Wrong filename according to the format */
-    public static final Issue ICON_EXTENSION = Issue.create(
-            "IconExtension", //$NON-NLS-1$
-            "Icon format does not match the file extension",
-
-            "Ensures that icons have the correct file extension (e.g. a `.png` file is " +
-            "really in the PNG format and not for example a GIF file named `.png`.)",
-            Category.ICONS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION_RES_ONLY);
-
-    /** Wrong filename according to the format */
-    public static final Issue ICON_COLORS = Issue.create(
-            "IconColors", //$NON-NLS-1$
-            "Icon colors do not follow the recommended visual style",
-
-            "Notification icons and Action Bar icons should only white and shades of gray. " +
-            "See the Android Design Guide for more details. " +
-            "Note that the way Lint decides whether an icon is an action bar icon or " +
-            "a notification icon is based on the filename prefix: `ic_menu_` for " +
-            "action bar icons, `ic_stat_` for notification icons etc. These correspond " +
-            "to the naming conventions documented in " +
-            "http://developer.android.com/guide/practices/ui_guidelines/icon_design.html",
-            Category.ICONS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA).addMoreInfo(
-                "http://developer.android.com/design/style/iconography.html"); //$NON-NLS-1$
-
-    /** Wrong launcher icon shape */
-    public static final Issue ICON_LAUNCHER_SHAPE = Issue.create(
-            "IconLauncherShape", //$NON-NLS-1$
-            "The launcher icon shape should use a distinct silhouette",
-
-            "According to the Android Design Guide " +
-            "(http://developer.android.com/design/style/iconography.html) " +
-            "your launcher icons should \"use a distinct silhouette\", " +
-            "a \"three-dimensional, front view, with a slight perspective as if viewed " +
-            "from above, so that users perceive some depth.\"\n" +
-            "\n" +
-            "The unique silhouette implies that your launcher icon should not be a filled " +
-            "square.",
-            Category.ICONS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA).addMoreInfo(
-                "http://developer.android.com/design/style/iconography.html"); //$NON-NLS-1$
-
-    /** Constructs a new {@link IconDetector} check */
-    public IconDetector() {
-    }
-
-    @Override
-    public void beforeCheckProject(@NonNull Context context) {
-        mLauncherIcons = null;
-        mActionBarIcons = null;
-        mNotificationIcons = null;
-    }
-
-    @Override
-    public void afterCheckLibraryProject(@NonNull Context context) {
-        if (!context.getProject().getReportIssues()) {
-            // If this is a library project not being analyzed, ignore it
-            return;
-        }
-
-        checkResourceFolder(context, context.getProject());
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        checkResourceFolder(context, context.getProject());
-    }
-
-    private void checkResourceFolder(Context context, @NonNull Project project) {
-        List<File> resourceFolders = project.getResourceFolders();
-        for (File res : resourceFolders) {
-            File[] folders = res.listFiles();
-            if (folders != null) {
-                boolean checkFolders = context.isEnabled(ICON_DENSITIES)
-                        || context.isEnabled(ICON_MISSING_FOLDER)
-                        || context.isEnabled(ICON_NODPI)
-                        || context.isEnabled(ICON_MIX_9PNG)
-                        || context.isEnabled(ICON_XML_AND_PNG);
-                boolean checkDipSizes = context.isEnabled(ICON_DIP_SIZE);
-                boolean checkDuplicates = context.isEnabled(DUPLICATES_NAMES)
-                         || context.isEnabled(DUPLICATES_CONFIGURATIONS);
-
-                Map<File, Dimension> pixelSizes = null;
-                Map<File, Long> fileSizes = null;
-                if (checkDipSizes || checkDuplicates) {
-                    pixelSizes = new HashMap<File, Dimension>();
-                    fileSizes = new HashMap<File, Long>();
-                }
-                Map<File, Set<String>> folderToNames = new HashMap<File, Set<String>>();
-                Map<File, Set<String>> nonDpiFolderNames = new HashMap<File, Set<String>>();
-                for (File folder : folders) {
-                    String folderName = folder.getName();
-                    if (folderName.startsWith(DRAWABLE_FOLDER)) {
-                        File[] files = folder.listFiles();
-                        if (files != null) {
-                            checkDrawableDir(context, folder, files, pixelSizes, fileSizes);
-
-                            if (checkFolders && DENSITY_PATTERN.matcher(folderName).matches()) {
-                                Set<String> names = new HashSet<String>(files.length);
-                                for (File f : files) {
-                                    String name = f.getName();
-                                    if (isDrawableFile(name)) {
-                                        names.add(name);
-                                    }
-                                }
-                                folderToNames.put(folder, names);
-                            } else if (checkFolders) {
-                                Set<String> names = new HashSet<String>(files.length);
-                                for (File f : files) {
-                                    String name = f.getName();
-                                    if (isDrawableFile(name)) {
-                                        names.add(name);
-                                    }
-                                }
-                                nonDpiFolderNames.put(folder, names);
-                            }
-                        }
-                    }
-                }
-
-                if (checkDipSizes) {
-                    checkDipSizes(context, pixelSizes);
-                }
-
-                if (checkDuplicates) {
-                    checkDuplicates(context, pixelSizes, fileSizes);
-                }
-
-                if (checkFolders && !folderToNames.isEmpty()) {
-                    checkDensities(context, res, folderToNames, nonDpiFolderNames);
-                }
-            }
-        }
-    }
-
-    /** Like {@link LintUtils#isBitmapFile(File)} but (a) operates on Strings instead
-     * of files and (b) also considers XML drawables as images */
-    private static boolean isDrawableFile(String name) {
-        // endsWith(name, DOT_PNG) is also true for endsWith(name, DOT_9PNG)
-        return endsWith(name, DOT_PNG)|| endsWith(name, DOT_JPG) || endsWith(name, DOT_GIF)
-                || endsWith(name, DOT_XML) || endsWith(name, DOT_JPEG) || endsWith(name, DOT_WEBP);
-    }
-
-    // This method looks for duplicates in the assets. This uses two pieces of information
-    // (file sizes and image dimensions) to quickly reject candidates, such that it only
-    // needs to check actual file contents on a small subset of the available files.
-    private static void checkDuplicates(Context context, Map<File, Dimension> pixelSizes,
-            Map<File, Long> fileSizes) {
-        Map<Long, Set<File>> sameSizes = new HashMap<Long, Set<File>>();
-        Map<Long, File> seenSizes = new HashMap<Long, File>(fileSizes.size());
-        for (Map.Entry<File, Long> entry : fileSizes.entrySet()) {
-            File file = entry.getKey();
-            Long size = entry.getValue();
-            if (seenSizes.containsKey(size)) {
-                Set<File> set = sameSizes.get(size);
-                if (set == null) {
-                    set = new HashSet<File>();
-                    set.add(seenSizes.get(size));
-                    sameSizes.put(size, set);
-                }
-                set.add(file);
-            } else {
-                seenSizes.put(size, file);
-            }
-        }
-
-        if (sameSizes.isEmpty()) {
-            return;
-        }
-
-        // Now go through the files that have the same size and check to see if we can
-        // split them apart based on image dimensions
-        // Note: we may not have file sizes on all the icons; in particular,
-        // we don't have file sizes for ninepatch files.
-        Collection<Set<File>> candidateLists = sameSizes.values();
-        for (Set<File> candidates : candidateLists) {
-            Map<Dimension, Set<File>> sameDimensions = new HashMap<Dimension, Set<File>>(
-                    candidates.size());
-            List<File> noSize = new ArrayList<File>();
-            for (File file : candidates) {
-                Dimension dimension = pixelSizes.get(file);
-                if (dimension != null) {
-                    Set<File> set = sameDimensions.get(dimension);
-                    if (set == null) {
-                        set = new HashSet<File>();
-                        sameDimensions.put(dimension, set);
-                    }
-                    set.add(file);
-                } else {
-                    noSize.add(file);
-                }
-            }
-
-
-            // Files that we have no dimensions for must be compared against everything
-            Collection<Set<File>> sets = sameDimensions.values();
-            if (!noSize.isEmpty()) {
-                if (!sets.isEmpty()) {
-                    for (Set<File> set : sets) {
-                        set.addAll(noSize);
-                    }
-                } else {
-                    // Must just test the noSize elements against themselves
-                    HashSet<File> noSizeSet = new HashSet<File>(noSize);
-                    sets = Collections.<Set<File>>singletonList(noSizeSet);
-                }
-            }
-
-            // Map from file to actual byte contents of the file.
-            // We store this in a map such that for repeated files, such as noSize files
-            // which can appear in multiple buckets, we only need to read them once
-            Map<File, byte[]> fileContents = new HashMap<File, byte[]>();
-
-            // Now we're ready for the final check where we actually check the
-            // bits. We have to partition the files into buckets of files that
-            // are identical.
-            for (Set<File> set : sets) {
-                if (set.size() < 2) {
-                    continue;
-                }
-
-                // Read all files in this set and store in map
-                for (File file : set) {
-                    byte[] bits = fileContents.get(file);
-                    if (bits == null) {
-                        try {
-                            bits = context.getClient().readBytes(file);
-                            fileContents.put(file, bits);
-                        } catch (IOException e) {
-                            context.log(e, null);
-                        }
-                    }
-                }
-
-                // Map where the key file is known to be equal to the value file.
-                // After we check individual files for equality this will be used
-                // to look for transitive equality.
-                Map<File, File> equal = new HashMap<File, File>();
-
-                // Now go and compare all the files. This isn't an efficient algorithm
-                // but the number of candidates should be very small
-
-                List<File> files = new ArrayList<File>(set);
-                Collections.sort(files);
-                for (int i = 0; i < files.size() - 1; i++) {
-                    for (int j = i + 1; j < files.size(); j++) {
-                        File file1 = files.get(i);
-                        File file2 = files.get(j);
-                        byte[] contents1 = fileContents.get(file1);
-                        byte[] contents2 = fileContents.get(file2);
-                        if (contents1 == null || contents2 == null) {
-                            // File couldn't be read: ignore
-                            continue;
-                        }
-                        if (contents1.length != contents2.length) {
-                            // Sizes differ: not identical.
-                            // This shouldn't happen since we've already partitioned based
-                            // on File.length(), but just make sure here since the file
-                            // system could have lied, or cached a value that has changed
-                            // if the file was just overwritten
-                            continue;
-                        }
-                        boolean same = true;
-                        for (int k = 0; k < contents1.length; k++) {
-                            if (contents1[k] != contents2[k]) {
-                                same = false;
-                                break;
-                            }
-                        }
-                        if (same) {
-                            equal.put(file1, file2);
-                        }
-                    }
-                }
-
-                if (!equal.isEmpty()) {
-                    Map<File, Set<File>> partitions = new HashMap<File, Set<File>>();
-                    List<Set<File>> sameSets = new ArrayList<Set<File>>();
-                    for (Map.Entry<File, File> entry : equal.entrySet()) {
-                        File file1 = entry.getKey();
-                        File file2 = entry.getValue();
-                        Set<File> set1 = partitions.get(file1);
-                        Set<File> set2 = partitions.get(file2);
-                        if (set1 != null) {
-                            set1.add(file2);
-                        } else if (set2 != null) {
-                            set2.add(file1);
-                        } else {
-                            set = new HashSet<File>();
-                            sameSets.add(set);
-                            set.add(file1);
-                            set.add(file2);
-                            partitions.put(file1, set);
-                            partitions.put(file2, set);
-                        }
-                    }
-
-                    // We've computed the partitions of equal files. Now sort them
-                    // for stable output.
-                    List<List<File>> lists = new ArrayList<List<File>>();
-                    for (Set<File> same : sameSets) {
-                        assert !same.isEmpty();
-                        ArrayList<File> sorted = new ArrayList<File>(same);
-                        Collections.sort(sorted);
-                        lists.add(sorted);
-                    }
-                    // Sort overall partitions by the first item in each list
-                    Collections.sort(lists, new Comparator<List<File>>() {
-                        @Override
-                        public int compare(List<File> list1, List<File> list2) {
-                            return list1.get(0).compareTo(list2.get(0));
-                        }
-                    });
-
-                    // Allow one specific scenario of duplicated icon contents:
-                    // Checking in different size icons (within a single density
-                    // folder). For now the only pattern we recognize is the
-                    // one advocated by the material design icons:
-                    //   https://github.com/google/material-design-icons
-                    // where the pattern is foo_<N>dp.png. (See issue 74584 for more.)
-                    ListIterator<List<File>> iterator = lists.listIterator();
-                    while (iterator.hasNext()) {
-                        List<File> list = iterator.next();
-                        boolean remove = true;
-                        for (File file : list) {
-                            String name = file.getName();
-                            if (!DP_NAME_PATTERN.matcher(name).matches()) {
-                                // One or more pattern in this list does not
-                                // conform to the dp naming pattern, so
-                                remove = false;
-                                break;
-                            }
-                        }
-                        if (remove) {
-                            iterator.remove();
-                        }
-                    }
-
-                    for (List<File> sameFiles : lists) {
-                        Location location = null;
-                        boolean sameNames = true;
-                        String lastName = null;
-                        for (File file : sameFiles) {
-                             if (lastName != null && !lastName.equals(file.getName())) {
-                                sameNames = false;
-                            }
-                            lastName = file.getName();
-                            // Chain locations together
-                            Location linkedLocation = location;
-                            location = Location.create(file);
-                            location.setSecondary(linkedLocation);
-                        }
-
-                        if (sameNames) {
-                            StringBuilder sb = new StringBuilder(sameFiles.size() * 16);
-                            for (File file : sameFiles) {
-                                if (sb.length() > 0) {
-                                    sb.append(", "); //$NON-NLS-1$
-                                }
-                                sb.append(file.getParentFile().getName());
-                            }
-                            String message = String.format(
-                                "The `%1$s` icon has identical contents in the following configuration folders: %2$s",
-                                        lastName, sb.toString());
-                            if (location != null) {
-                                context.report(DUPLICATES_CONFIGURATIONS, location, message);
-                            }
-                        } else {
-                            StringBuilder sb = new StringBuilder(sameFiles.size() * 16);
-                            for (File file : sameFiles) {
-                                if (sb.length() > 0) {
-                                    sb.append(", "); //$NON-NLS-1$
-                                }
-                                sb.append(file.getName());
-                            }
-                            String message = String.format(
-                                "The following unrelated icon files have identical contents: %1$s",
-                                        sb.toString());
-                                context.report(DUPLICATES_NAMES, location, message);
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    // This method checks the given map from resource file to pixel dimensions for each
-    // such image and makes sure that the normalized dip sizes across all the densities
-    // are mostly the same.
-    private static void checkDipSizes(Context context, Map<File, Dimension> pixelSizes) {
-        // Partition up the files such that I can look at a series by name. This
-        // creates a map from filename (such as foo.png) to a list of files
-        // providing that icon in various folders: drawable-mdpi/foo.png, drawable-hdpi/foo.png
-        // etc.
-        Map<String, List<File>> nameToFiles = new HashMap<String, List<File>>();
-        for (File file : pixelSizes.keySet()) {
-            String name = file.getName();
-            List<File> list = nameToFiles.get(name);
-            if (list == null) {
-                list = new ArrayList<File>();
-                nameToFiles.put(name, list);
-            }
-            list.add(file);
-        }
-
-        ArrayList<String> names = new ArrayList<String>(nameToFiles.keySet());
-        Collections.sort(names);
-
-        // We have to partition the files further because it's possible for the project
-        // to have different configurations for an icon, such as this:
-        //   drawable-large-hdpi/foo.png, drawable-large-mdpi/foo.png,
-        //   drawable-hdpi/foo.png, drawable-mdpi/foo.png,
-        //    drawable-hdpi-v11/foo.png and drawable-mdpi-v11/foo.png.
-        // In this case we don't want to compare across categories; we want to
-        // ensure that the drawable-large-{density} icons are consistent,
-        // that the drawable-{density}-v11 icons are consistent, and that
-        // the drawable-{density} icons are consistent.
-
-        // Map from name to list of map from parent folder to list of files
-        Map<String, Map<String, List<File>>> configMap =
-                new HashMap<String, Map<String,List<File>>>();
-        for (Map.Entry<String, List<File>> entry : nameToFiles.entrySet()) {
-            String name = entry.getKey();
-            List<File> files = entry.getValue();
-            for (File file : files) {
-                //noinspection ConstantConditions
-                String parentName = file.getParentFile().getName();
-                // Strip out the density part
-                int index = -1;
-                for (String qualifier : DENSITY_QUALIFIERS) {
-                    index = parentName.indexOf(qualifier);
-                    if (index != -1) {
-                        parentName = parentName.substring(0, index)
-                                + parentName.substring(index + qualifier.length());
-                        break;
-                    }
-                }
-                if (index == -1) {
-                    // No relevant qualifier found in the parent directory name,
-                    // e.g. it's just "drawable" or something like "drawable-nodpi".
-                    continue;
-                }
-
-                Map<String, List<File>> folderMap = configMap.get(name);
-                if (folderMap == null) {
-                    folderMap = new HashMap<String,List<File>>();
-                    configMap.put(name, folderMap);
-                }
-                // Map from name to a map from parent folder to files
-                List<File> list = folderMap.get(parentName);
-                if (list == null) {
-                    list = new ArrayList<File>();
-                    folderMap.put(parentName, list);
-                }
-                list.add(file);
-            }
-        }
-
-        for (String name : names) {
-            //List<File> files = nameToFiles.get(name);
-            Map<String, List<File>> configurations = configMap.get(name);
-            if (configurations == null) {
-                // Nothing in this configuration: probably only found in drawable/ or
-                // drawable-nodpi etc directories.
-                continue;
-            }
-
-            for (Map.Entry<String, List<File>> entry : configurations.entrySet()) {
-                List<File> files = entry.getValue();
-
-                // Ensure that all the dip sizes are *roughly* the same
-                Map<File, Dimension> dipSizes = new HashMap<File, Dimension>();
-                int dipWidthSum = 0; // Incremental computation of average
-                int dipHeightSum = 0; // Incremental computation of average
-                int count = 0;
-                for (File file : files) {
-                    //noinspection ConstantConditions
-                    String folderName = file.getParentFile().getName();
-                    float factor = getMdpiScalingFactor(folderName);
-                    if (factor > 0) {
-                        Dimension size = pixelSizes.get(file);
-                        if (size == null) {
-                            continue;
-                        }
-                        Dimension dip = new Dimension(
-                                Math.round(size.width / factor),
-                                Math.round(size.height / factor));
-                        dipWidthSum += dip.width;
-                        dipHeightSum += dip.height;
-                        dipSizes.put(file, dip);
-                        count++;
-
-                        String fileName = file.getName();
-                        Matcher matcher = DP_NAME_PATTERN.matcher(fileName);
-                        if (matcher.matches()) {
-                            String dpString = matcher.group(1);
-                            int dp = Integer.parseInt(dpString);
-                            // We're not sure whether the dp size refers to the width
-                            // or the height, so check both. Allow a little bit of rounding
-                            // slop.
-                            if (Math.abs(dip.width - dp) > 2 || Math.abs(dip.height - dp) > 2) {
-                                // Unicode 00D7 is the multiplication sign
-                                String message = String.format(""
-                                        + "Suspicious file name `%1$s`: The implied %2$s `dp` "
-                                        + "size does not match the actual `dp` size "
-                                        + "(pixel size %3$d\u00D7%4$d in a `%5$s` folder "
-                                        + "computes to %6$d\u00D7%7$d `dp`)",
-                                        fileName, dpString,
-                                        size.width, size.height,
-                                        folderName,
-                                        dip.width, dip.height);
-                                context.report(ICON_DIP_SIZE, Location.create(file), message);
-                            }
-                        }
-                    }
-                }
-                if (count == 0) {
-                    // Icons in drawable/ and drawable-nodpi/
-                    continue;
-                }
-                int meanWidth = dipWidthSum / count;
-                int meanHeight = dipHeightSum / count;
-
-                // Compute standard deviation?
-                int squareWidthSum = 0;
-                int squareHeightSum = 0;
-                for (Dimension size : dipSizes.values()) {
-                    squareWidthSum += (size.width - meanWidth) * (size.width - meanWidth);
-                    squareHeightSum += (size.height - meanHeight) * (size.height - meanHeight);
-                }
-                double widthStdDev = Math.sqrt(squareWidthSum / count);
-                double heightStdDev = Math.sqrt(squareHeightSum / count);
-
-                if (widthStdDev > meanWidth / 10 || heightStdDev > meanHeight) {
-                    Location location = null;
-                    StringBuilder sb = new StringBuilder(100);
-
-                    // Sort entries by decreasing dip size
-                    List<Map.Entry<File, Dimension>> entries =
-                            new ArrayList<Map.Entry<File,Dimension>>();
-                    for (Map.Entry<File, Dimension> entry2 : dipSizes.entrySet()) {
-                        entries.add(entry2);
-                    }
-                    Collections.sort(entries,
-                            new Comparator<Map.Entry<File, Dimension>>() {
-                        @Override
-                        public int compare(Entry<File, Dimension> e1,
-                                Entry<File, Dimension> e2) {
-                            Dimension d1 = e1.getValue();
-                            Dimension d2 = e2.getValue();
-                            if (d1.width != d2.width) {
-                                return d2.width - d1.width;
-                            }
-
-                            return d2.height - d1.height;
-                        }
-                    });
-                    for (Map.Entry<File, Dimension> entry2 : entries) {
-                        if (sb.length() > 0) {
-                            sb.append(", ");
-                        }
-                        File file = entry2.getKey();
-
-                        // Chain locations together
-                        Location linkedLocation = location;
-                        location = Location.create(file);
-                        location.setSecondary(linkedLocation);
-                        Dimension dip = entry2.getValue();
-                        Dimension px = pixelSizes.get(file);
-                        //noinspection ConstantConditions
-                        String fileName = file.getParentFile().getName() + File.separator
-                                + file.getName();
-                        sb.append(String.format("%1$s: %2$dx%3$d dp (%4$dx%5$d px)",
-                                fileName, dip.width, dip.height, px.width, px.height));
-                    }
-                    String message = String.format(
-                        "The image `%1$s` varies significantly in its density-independent (dip) " +
-                        "size across the various density versions: %2$s",
-                            name, sb.toString());
-                    if (location != null) {
-                        context.report(ICON_DIP_SIZE, location, message);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkDensities(Context context, File res,
-            Map<File, Set<String>> folderToNames,
-            Map<File, Set<String>> nonDpiFolderNames) {
-        // TODO: Is there a way to look at the manifest and figure out whether
-        // all densities are expected to be needed?
-        // Note: ldpi is probably not needed; it has very little usage
-        // (about 2%; http://developer.android.com/resources/dashboard/screens.html)
-        // TODO: Use the matrix to check out if we can eliminate densities based
-        // on the target screens?
-
-        Set<String> definedDensities = new HashSet<String>();
-        for (File f : folderToNames.keySet()) {
-            definedDensities.add(f.getName());
-        }
-
-        // Look for missing folders -- if you define say drawable-mdpi then you
-        // should also define -hdpi and -xhdpi.
-        if (context.isEnabled(ICON_MISSING_FOLDER)) {
-            List<String> missing = new ArrayList<String>();
-            for (String density : getRequiredDensityFolders(context)) {
-                if (!definedDensities.contains(density)) {
-                    missing.add(density);
-                }
-            }
-            if (!missing.isEmpty()) {
-                context.report(
-                    ICON_MISSING_FOLDER,
-                    Location.create(res),
-                    String.format("Missing density variation folders in `%1$s`: %2$s",
-                            context.getProject().getDisplayPath(res),
-                            LintUtils.formatList(missing, -1)));
-            }
-        }
-
-        if (context.isEnabled(ICON_NODPI)) {
-            Set<String> noDpiNames = new HashSet<String>();
-            for (Map.Entry<File, Set<String>> entry : folderToNames.entrySet()) {
-                if (isNoDpiFolder(entry.getKey())) {
-                    noDpiNames.addAll(entry.getValue());
-                }
-            }
-            if (!noDpiNames.isEmpty()) {
-                // Make sure that none of the nodpi names appear in a non-nodpi folder
-                Set<String> inBoth = new HashSet<String>();
-                List<File> files = new ArrayList<File>();
-                for (Map.Entry<File, Set<String>> entry : folderToNames.entrySet()) {
-                    File folder = entry.getKey();
-                    String folderName = folder.getName();
-                    if (!isNoDpiFolder(folder)) {
-                        assert DENSITY_PATTERN.matcher(folderName).matches();
-                        Set<String> overlap = nameIntersection(noDpiNames, entry.getValue());
-                        inBoth.addAll(overlap);
-                        for (String name : overlap) {
-                            files.add(new File(folder, name));
-                        }
-                    }
-                }
-
-                if (!inBoth.isEmpty()) {
-                    List<String> list = new ArrayList<String>(inBoth);
-                    Collections.sort(list);
-
-                    // Chain locations together
-                    Location location = chainLocations(files);
-
-                    context.report(ICON_NODPI, location,
-                        String.format(
-                            "The following images appear in both `-nodpi` and in a density folder: %1$s",
-                            LintUtils.formatList(list,
-                                    context.getDriver().isAbbreviating() ? 10 : -1)));
-                }
-            }
-        }
-
-        if (context.isEnabled(ICON_MIX_9PNG)) {
-            checkMixedNinePatches(context, folderToNames);
-        }
-
-        if (context.isEnabled(ICON_XML_AND_PNG)) {
-            Map<File, Set<String>> folderMap = Maps.newHashMap(folderToNames);
-            folderMap.putAll(nonDpiFolderNames);
-            Set<String> xmlNames = Sets.newHashSetWithExpectedSize(100);
-            Set<String> bitmapNames = Sets.newHashSetWithExpectedSize(100);
-
-            for (Map.Entry<File, Set<String>> entry : folderMap.entrySet()) {
-                Set<String> names = entry.getValue();
-                for (String name : names) {
-                    if (endsWith(name, DOT_XML)) {
-                        xmlNames.add(name);
-                    } else if (isDrawableFile(name)) {
-                        bitmapNames.add(name);
-                    }
-                }
-            }
-            if (!xmlNames.isEmpty() && !bitmapNames.isEmpty()) {
-                // Make sure that none of the nodpi names appear in a non-nodpi folder
-                Set<String> overlap = nameIntersection(xmlNames, bitmapNames);
-                if (!overlap.isEmpty()) {
-                    Multimap<String, File> map = ArrayListMultimap.create();
-                    Set<String> bases = Sets.newHashSetWithExpectedSize(overlap.size());
-                    for (String name : overlap) {
-                        bases.add(LintUtils.getBaseName(name));
-                    }
-
-                    for (String base : bases) {
-                        for (Map.Entry<File, Set<String>> entry : folderMap.entrySet()) {
-                            File folder = entry.getKey();
-                            for (String n : entry.getValue()) {
-                                if (base.equals(LintUtils.getBaseName(n))) {
-                                    map.put(base, new File(folder, n));
-                                }
-                            }
-                        }
-                    }
-                    List<String> sorted = new ArrayList<String>(map.keySet());
-                    Collections.sort(sorted);
-                    for (String name : sorted) {
-                        List<File> lists = Lists.newArrayList(map.get(name));
-                        Location location = chainLocations(lists);
-
-                        List<String> fileNames = Lists.newArrayList();
-                        boolean seenXml = false;
-                        boolean seenNonXml = false;
-                        for (File f : lists) {
-                            boolean isXml = endsWith(f.getPath(), DOT_XML);
-                            if (isXml && !seenXml) {
-                                fileNames.add(context.getProject().getDisplayPath(f));
-                                seenXml = true;
-                            } else if (!isXml && !seenNonXml) {
-                                fileNames.add(context.getProject().getDisplayPath(f));
-                                seenNonXml = true;
-                            }
-                        }
-
-                        context.report(ICON_XML_AND_PNG, location,
-                            String.format(
-                                "The following images appear both as density independent `.xml` files and as bitmap files: %1$s",
-                                LintUtils.formatList(fileNames,
-                                        context.getDriver().isAbbreviating() ? 10 : -1)));
-                    }
-                }
-            }
-        }
-
-        if (context.isEnabled(ICON_DENSITIES)) {
-            // Look for folders missing some of the specific assets
-            Set<String> allNames = new HashSet<String>();
-            for (Entry<File,Set<String>> entry : folderToNames.entrySet()) {
-                if (!isNoDpiFolder(entry.getKey())) {
-                    Set<String> names = entry.getValue();
-                    allNames.addAll(names);
-                }
-            }
-
-            for (Map.Entry<File, Set<String>> entry : folderToNames.entrySet()) {
-                File file = entry.getKey();
-                if (isNoDpiFolder(file)) {
-                    continue;
-                }
-                Set<String> names = entry.getValue();
-                if (names.size() != allNames.size()) {
-                    List<String> delta = new ArrayList<String>(nameDifferences(allNames,  names));
-                    if (delta.isEmpty()) {
-                        continue;
-                    }
-                    Collections.sort(delta);
-                    String foundIn = "";
-                    if (delta.size() == 1) {
-                        // Produce list of where the icon is actually defined
-                        List<String> defined = new ArrayList<String>();
-                        String name = delta.get(0);
-                        for (Map.Entry<File, Set<String>> e : folderToNames.entrySet()) {
-                            if (e.getValue().contains(name)) {
-                                defined.add(e.getKey().getName());
-                            }
-                        }
-                        if (!defined.isEmpty()) {
-                            foundIn = String.format(" (found in %1$s)",
-                                    LintUtils.formatList(defined,
-                                            context.getDriver().isAbbreviating() ? 5 : -1));
-                        }
-                    }
-
-                    // Irrelevant folder?
-                    String folder = file.getName();
-                    if (!getRequiredDensityFolders(context).contains(folder)) {
-                        continue;
-                    }
-
-                    context.report(ICON_DENSITIES, Location.create(file),
-                            String.format(
-                                    "Missing the following drawables in `%1$s`: %2$s%3$s",
-                                    folder,
-                                    LintUtils.formatList(delta,
-                                            context.getDriver().isAbbreviating() ? 5 : -1),
-                                    foundIn));
-                }
-            }
-        }
-    }
-
-    private List<String> getRequiredDensityFolders(@NonNull Context context) {
-        if (mCachedRequiredDensities == null
-                || context.getProject() != mCachedDensitiesForProject) {
-            mCachedDensitiesForProject = context.getProject();
-            mCachedRequiredDensities = Lists.newArrayListWithExpectedSize(10);
-
-            List<String> applicableDensities = context.getProject().getApplicableDensities();
-            if (applicableDensities != null) {
-                mCachedRequiredDensities.addAll(applicableDensities);
-            } else {
-                if (INCLUDE_LDPI) {
-                    mCachedRequiredDensities.add(DRAWABLE_LDPI);
-                }
-                mCachedRequiredDensities.add(DRAWABLE_MDPI);
-                mCachedRequiredDensities.add(DRAWABLE_HDPI);
-                mCachedRequiredDensities.add(DRAWABLE_XHDPI);
-                mCachedRequiredDensities.add(DRAWABLE_XXHDPI);
-                mCachedRequiredDensities.add(DRAWABLE_XXXHDPI);
-            }
-        }
-
-        return mCachedRequiredDensities;
-    }
-
-    /**
-     * Adds in the resConfig values specified by the given flavor container, assuming
-     * it's in one of the relevant variantFlavors, into the given set
-     */
-    private static void addResConfigsFromFlavor(@NonNull Set<String> relevantDensities,
-            @Nullable List<String> variantFlavors,
-            @NonNull ProductFlavorContainer container) {
-        ProductFlavor flavor = container.getProductFlavor();
-        if (variantFlavors == null || variantFlavors.contains(flavor.getName())) {
-            if (!flavor.getResourceConfigurations().isEmpty()) {
-                for (String densityName : flavor.getResourceConfigurations()) {
-                    Density density = Density.getEnum(densityName);
-                    if (density != null && density.isRecommended()
-                            && density != Density.NODPI && density != Density.ANYDPI) {
-                        relevantDensities.add(densityName);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Compute the difference in names between a and b. This is not just
-     * Sets.difference(a, b) because we want to make the comparisons <b>without
-     * file extensions</b> and return the result <b>with</b>..
-     */
-    private static Set<String> nameDifferences(Set<String> a, Set<String> b) {
-        Set<String> names1 = new HashSet<String>(a.size());
-        for (String s : a) {
-            names1.add(LintUtils.getBaseName(s));
-        }
-        Set<String> names2 = new HashSet<String>(b.size());
-        for (String s : b) {
-            names2.add(LintUtils.getBaseName(s));
-        }
-
-        names1.removeAll(names2);
-
-        if (!names1.isEmpty()) {
-            // Map filenames back to original filenames with extensions
-            Set<String> result = new HashSet<String>(names1.size());
-            for (String s : a) {
-                if (names1.contains(LintUtils.getBaseName(s))) {
-                    result.add(s);
-                }
-            }
-            for (String s : b) {
-                if (names1.contains(LintUtils.getBaseName(s))) {
-                    result.add(s);
-                }
-            }
-
-            return result;
-        }
-
-        return Collections.emptySet();
-    }
-
-    /**
-     * Compute the intersection in names between a and b. This is not just
-     * Sets.intersection(a, b) because we want to make the comparisons <b>without
-     * file extensions</b> and return the result <b>with</b>.
-     */
-    private static Set<String> nameIntersection(Set<String> a, Set<String> b) {
-        Set<String> names1 = new HashSet<String>(a.size());
-        for (String s : a) {
-            names1.add(LintUtils.getBaseName(s));
-        }
-        Set<String> names2 = new HashSet<String>(b.size());
-        for (String s : b) {
-            names2.add(LintUtils.getBaseName(s));
-        }
-
-        names1.retainAll(names2);
-
-        if (!names1.isEmpty()) {
-            // Map filenames back to original filenames with extensions
-            Set<String> result = new HashSet<String>(names1.size());
-            for (String s : a) {
-                if (names1.contains(LintUtils.getBaseName(s))) {
-                    result.add(s);
-                }
-            }
-            for (String s : b) {
-                if (names1.contains(LintUtils.getBaseName(s))) {
-                    result.add(s);
-                }
-            }
-
-            return result;
-        }
-
-        return Collections.emptySet();
-    }
-
-    private static boolean isNoDpiFolder(File file) {
-        return file.getName().contains("-nodpi");
-    }
-
-    private Map<File, BufferedImage> mImageCache;
-
-    @Nullable
-    private BufferedImage getImage(@Nullable File file) throws IOException {
-        if (file == null) {
-            return null;
-        }
-        if (mImageCache == null) {
-            mImageCache = Maps.newHashMap();
-        } else {
-            BufferedImage image = mImageCache.get(file);
-            if (image != null) {
-                return image;
-            }
-        }
-
-        BufferedImage image = ImageIO.read(file);
-        mImageCache.put(file, image);
-
-        return image;
-    }
-
-    private void checkDrawableDir(Context context, File folder, File[] files,
-            Map<File, Dimension> pixelSizes, Map<File, Long> fileSizes) {
-        if (folder.getName().equals(DRAWABLE_FOLDER)
-                && context.isEnabled(ICON_LOCATION) &&
-                // If supporting older versions than Android 1.6, it's not an error
-                // to include bitmaps in drawable/
-                context.getProject().getMinSdk() >= 4) {
-            for (File file : files) {
-                String name = file.getName();
-                //noinspection StatementWithEmptyBody
-                if (name.endsWith(DOT_XML)) {
-                    // pass - most common case, avoids checking other extensions
-                } else if (endsWith(name, DOT_PNG)
-                        || endsWith(name, DOT_JPG)
-                        || endsWith(name, DOT_JPEG)
-                        || endsWith(name, DOT_GIF)) {
-                    context.report(ICON_LOCATION,
-                        Location.create(file),
-                        String.format("Found bitmap drawable `res/drawable/%1$s` in " +
-                                "densityless folder",
-                                file.getName()));
-                }
-            }
-        }
-
-        if (context.isEnabled(GIF_USAGE)) {
-            for (File file : files) {
-                String name = file.getName();
-                if (endsWith(name, DOT_GIF)) {
-                    context.report(GIF_USAGE, Location.create(file),
-                            "Using the `.gif` format for bitmaps is discouraged");
-                }
-            }
-        }
-
-        if (context.isEnabled(ICON_EXTENSION)) {
-            for (File file : files) {
-                String path = file.getPath();
-                if (isDrawableFile(path) && !endsWith(path, DOT_XML)) {
-                    checkExtension(context, file);
-                }
-            }
-        }
-
-        if (context.isEnabled(ICON_COLORS)) {
-            for (File file : files) {
-                String name = file.getName();
-
-                if (isDrawableFile(name)
-                        && !endsWith(name, DOT_XML)
-                        && !endsWith(name, DOT_9PNG)) {
-                    String baseName = getBaseName(name);
-                    boolean isActionBarIcon = isActionBarIcon(context, baseName, file);
-                    if (isActionBarIcon || isNotificationIcon(baseName)) {
-                        Dimension size = checkColor(context, file, isActionBarIcon);
-
-                        // Store dimension for size check if we went to the trouble of reading image
-                        if (size != null && pixelSizes != null) {
-                            pixelSizes.put(file, size);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (context.isEnabled(ICON_LAUNCHER_SHAPE)) {
-            // Look up launcher icon name
-            for (File file : files) {
-                String name = file.getName();
-                if (isLauncherIcon(getBaseName(name))
-                        && !endsWith(name, DOT_XML)
-                        && !endsWith(name, DOT_9PNG)) {
-                    checkLauncherShape(context, file);
-                }
-            }
-        }
-
-        // Check icon sizes
-        if (context.isEnabled(ICON_EXPECTED_SIZE)) {
-            checkExpectedSizes(context, folder, files);
-        }
-
-        if (pixelSizes != null || fileSizes != null) {
-            for (File file : files) {
-                // TODO: Combine this check with the check for expected sizes such that
-                // I don't check file sizes twice!
-                String fileName = file.getName();
-
-                if (endsWith(fileName, DOT_PNG) || endsWith(fileName, DOT_JPG)
-                        || endsWith(fileName, DOT_JPEG)) {
-                    // Only scan .png files (except 9-patch png's) and jpg files for
-                    // dip sizes. Duplicate checks can also be performed on ninepatch files.
-                    if (pixelSizes != null && !endsWith(fileName, DOT_9PNG)
-                            && !pixelSizes.containsKey(file)) { // already read by checkColor?
-                        Dimension size = getSize(file);
-                        pixelSizes.put(file, size);
-                    }
-                    if (fileSizes != null) {
-                        fileSizes.put(file, file.length());
-                    }
-                }
-            }
-        }
-
-        mImageCache = null;
-    }
-
-    /**
-     * Check that launcher icons do not fill every pixel in the image
-     */
-    private void checkLauncherShape(Context context, File file) {
-        try {
-            BufferedImage image = getImage(file);
-            if (image != null) {
-                // TODO: see if the shape is rectangular but inset from outer rectangle; if so
-                // that's probably not right either!
-                for (int y = 0, height = image.getHeight(); y < height; y++) {
-                    for (int x = 0, width = image.getWidth(); x < width; x++) {
-                        int rgb = image.getRGB(x, y);
-                        if ((rgb & 0xFF000000) == 0) {
-                            return;
-                        }
-                    }
-                }
-
-                String message = "Launcher icons should not fill every pixel of their square " +
-                                 "region; see the design guide for details";
-                context.report(ICON_LAUNCHER_SHAPE, Location.create(file),
-                        message);
-            }
-        } catch (IOException e) {
-            // Pass: ignore files we can't read
-        }
-    }
-
-    /**
-     * Check whether the icons in the file are okay. Also return the image size
-     * if known (for use by other checks)
-     */
-    private Dimension checkColor(Context context, File file, boolean isActionBarIcon) {
-        int folderVersion = context.getDriver().getResourceFolderVersion(file);
-        if (isActionBarIcon) {
-            if (folderVersion != -1 && folderVersion < 11
-                    || !isAndroid30(context, folderVersion)) {
-                return null;
-            }
-        } else {
-            if (folderVersion != -1 && folderVersion < 9
-                    || !isAndroid23(context, folderVersion)
-                        && !isAndroid30(context, folderVersion)) {
-                return null;
-            }
-        }
-
-        // TODO: This only checks icons that are known to be using the Holo style.
-        // However, if the user has minSdk < 11 as well as targetSdk > 11, we should
-        // also check that they actually include a -v11 or -v14 folder with proper
-        // icons, since the below won't flag the older icons.
-        try {
-            BufferedImage image = getImage(file);
-            if (image != null) {
-                if (isActionBarIcon) {
-                    checkPixels:
-                    for (int y = 0, height = image.getHeight(); y < height; y++) {
-                        for (int x = 0, width = image.getWidth(); x < width; x++) {
-                            int rgb = image.getRGB(x, y);
-                            if ((rgb & 0xFF000000) != 0) { // else: transparent
-                                int r = (rgb & 0xFF0000) >>> 16;
-                                int g = (rgb & 0x00FF00) >>> 8;
-                                int b = (rgb & 0x0000FF);
-                                if (r != g || r != b) {
-                                    String message = "Action Bar icons should use a single gray "
-                                        + "color (`#333333` for light themes (with 60%/30% "
-                                        + "opacity for enabled/disabled), and `#FFFFFF` with "
-                                        + "opacity 80%/30% for dark themes";
-                                    context.report(ICON_COLORS, Location.create(file),
-                                            message);
-                                    break checkPixels;
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    if (folderVersion >= 11 || isAndroid30(context, folderVersion)) {
-                        // Notification icons. Should be white as of API 14
-                        checkPixels:
-                        for (int y = 0, height = image.getHeight(); y < height; y++) {
-                            for (int x = 0, width = image.getWidth(); x < width; x++) {
-                                int rgb = image.getRGB(x, y);
-                                // If the pixel is not completely transparent, insist that
-                                // its RGB channel must be white (with any alpha value)
-                                if ((rgb & 0xFF000000) != 0 && (rgb & 0xFFFFFF) != 0xFFFFFF) {
-                                    int r = (rgb & 0xFF0000) >>> 16;
-                                    int g = (rgb & 0x00FF00) >>> 8;
-                                    int b = (rgb & 0x0000FF);
-                                    if (r == g && r == b) {
-                                        // If the pixel is not white, it might be because of
-                                        // anti-aliasing. In that case, at least one neighbor
-                                        // should be of a different color
-                                        if (x < width - 1 && rgb != image.getRGB(x + 1, y)) {
-                                            continue;
-                                        }
-                                        if (x > 0 && rgb != image.getRGB(x - 1, y)) {
-                                            continue;
-                                        }
-                                        if (y < height - 1 && rgb != image.getRGB(x, y + 1)) {
-                                            continue;
-                                        }
-                                        if (y > 0 && rgb != image.getRGB(x, y - 1)) {
-                                            continue;
-                                        }
-                                    }
-
-                                    String message = "Notification icons must be entirely white";
-                                    context.report(ICON_COLORS, Location.create(file),
-                                            message);
-                                    break checkPixels;
-                                }
-                            }
-                        }
-                    } else {
-                        // As of API 9, should be gray.
-                        checkPixels:
-                            for (int y = 0, height = image.getHeight(); y < height; y++) {
-                                for (int x = 0, width = image.getWidth(); x < width; x++) {
-                                    int rgb = image.getRGB(x, y);
-                                    if ((rgb & 0xFF000000) != 0) { // else: transparent
-                                        int r = (rgb & 0xFF0000) >>> 16;
-                                        int g = (rgb & 0x00FF00) >>> 8;
-                                        int b = (rgb & 0x0000FF);
-                                        if (r != g || r != b) {
-                                            String message = "Notification icons should not use "
-                                                    + "colors";
-                                            context.report(ICON_COLORS, Location.create(file),
-                                                    message);
-                                            break checkPixels;
-                                        }
-                                    }
-                                }
-                            }
-                    }
-                }
-
-                return new Dimension(image.getWidth(), image.getHeight());
-            }
-        } catch (IOException e) {
-            // Pass: ignore files we can't read
-        }
-
-        return null;
-    }
-
-    private static void checkExtension(Context context, File file) {
-        try {
-            ImageInputStream input = ImageIO.createImageInputStream(file);
-            if (input != null) {
-                try {
-                    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
-                    while (readers.hasNext()) {
-                        ImageReader reader = readers.next();
-                        try {
-                            reader.setInput(input);
-
-                            // Check file extension
-                            String formatName = reader.getFormatName();
-                            if (formatName != null && !formatName.isEmpty()) {
-                                String path = file.getPath();
-                                int index = path.lastIndexOf('.');
-                                String extension = path.substring(index+1).toLowerCase(Locale.US);
-
-                                if (!formatName.equalsIgnoreCase(extension)) {
-                                    if (endsWith(path, DOT_JPG)
-                                            && formatName.equals("JPEG")) { //$NON-NLS-1$
-                                        return;
-                                    }
-                                    String message = String.format(
-                                            "Misleading file extension; named `.%1$s` but the " +
-                                            "file format is `%2$s`", extension, formatName);
-                                    Location location = Location.create(file);
-                                    context.report(ICON_EXTENSION, location, message);
-                                }
-                                break;
-                            }
-                        } finally {
-                            reader.dispose();
-                        }
-                    }
-                } finally {
-                    input.close();
-                }
-            }
-        } catch (IOException e) {
-            // Pass -- we can't handle all image types, warn about those we can
-        }
-    }
-
-    // Like LintUtils.getBaseName, but for files like .svn it returns "" rather than ".svn"
-    private static String getBaseName(String name) {
-        String baseName = name;
-        int index = baseName.indexOf('.');
-        if (index != -1) {
-            baseName = baseName.substring(0, index);
-        }
-
-        return baseName;
-    }
-
-    private static void checkMixedNinePatches(Context context,
-            Map<File, Set<String>> folderToNames) {
-        Set<String> conflictSet = null;
-
-        for (Entry<File, Set<String>> entry : folderToNames.entrySet()) {
-            Set<String> baseNames = new HashSet<String>();
-            Set<String> names = entry.getValue();
-            for (String name : names) {
-                assert isDrawableFile(name) : name;
-                String base = getBaseName(name);
-                if (baseNames.contains(base)) {
-                    String ninepatch = base + DOT_9PNG;
-                    String png = base + DOT_PNG;
-                    if (names.contains(ninepatch) && names.contains(png)) {
-                        if (conflictSet == null) {
-                            conflictSet = Sets.newHashSet();
-                        }
-                        conflictSet.add(base);
-                    }
-                } else {
-                    baseNames.add(base);
-                }
-            }
-        }
-
-        if (conflictSet == null || conflictSet.isEmpty()) {
-            return;
-        }
-
-        Map<String, List<File>> conflicts = null;
-        for (Entry<File, Set<String>> entry : folderToNames.entrySet()) {
-            File dir = entry.getKey();
-            Set<String> names = entry.getValue();
-            for (String name : names) {
-                assert isDrawableFile(name) : name;
-                String base = getBaseName(name);
-                if (conflictSet.contains(base)) {
-                    if (conflicts == null) {
-                        conflicts = Maps.newHashMap();
-                    }
-                    List<File> files = conflicts.get(base);
-                    if (files == null) {
-                        files = Lists.newArrayList();
-                        conflicts.put(base, files);
-                    }
-                    files.add(new File(dir, name));
-                }
-            }
-        }
-
-        assert conflicts != null && !conflicts.isEmpty() : conflictSet;
-        List<String> names = new ArrayList<String>(conflicts.keySet());
-        Collections.sort(names);
-        for (String name : names) {
-            List<File> files = conflicts.get(name);
-            assert files != null : name;
-            Location location = chainLocations(files);
-
-            String message = String.format(
-                    "The files `%1$s.png` and `%1$s.9.png` clash; both "
-                    + "will map to `@drawable/%1$s`", name);
-            context.report(ICON_MIX_9PNG, location, message);
-        }
-    }
-
-    private static Location chainLocations(List<File> files) {
-        // Chain locations together
-        Collections.sort(files);
-        Location location = null;
-        for (File file : files) {
-            Location linkedLocation = location;
-            location = Location.create(file);
-            location.setSecondary(linkedLocation);
-        }
-        return location;
-    }
-
-    private void checkExpectedSizes(Context context, File folder, File[] files) {
-        if (files == null || files.length == 0) {
-            return;
-        }
-
-        String folderName = folder.getName();
-        int folderVersion = context.getDriver().getResourceFolderVersion(files[0]);
-
-        for (File file : files) {
-            String name = file.getName();
-
-            // TODO: Look up exact app icon from the manifest rather than simply relying on
-            // the naming conventions described here:
-            //  http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#design-tips
-            // See if we can figure out other types of icons from usage too.
-
-            String baseName = getBaseName(name);
-
-            if (isLauncherIcon(baseName)) {
-                // Launcher icons
-                checkSize(context, folderName, file, 48, 48, true /*exact*/);
-            } else if (isActionBarIcon(baseName)) {
-                checkSize(context, folderName, file, 32, 32, true /*exact*/);
-            } else if (name.startsWith("ic_dialog_")) { //$NON-NLS-1$
-                // Dialog
-                checkSize(context, folderName, file, 32, 32, true /*exact*/);
-            } else if (name.startsWith("ic_tab_")) { //$NON-NLS-1$
-                // Tab icons
-                checkSize(context, folderName, file, 32, 32, true /*exact*/);
-            } else if (isNotificationIcon(baseName)) {
-                // Notification icons
-                if (isAndroid30(context, folderVersion)) {
-                    checkSize(context, folderName, file, 24, 24, true /*exact*/);
-                } else if (isAndroid23(context, folderVersion)) {
-                    checkSize(context, folderName, file, 16, 25, false /*exact*/);
-                } else {
-                    // Android 2.2 or earlier
-                    // TODO: Should this be done for each folder size?
-                    checkSize(context, folderName, file, 25, 25, true /*exact*/);
-                }
-            } else if (name.startsWith("ic_menu_")) { //$NON-NLS-1$
-                if (isAndroid30(context, folderVersion)) {
-                 // Menu icons (<=2.3 only: Replaced by action bar icons (ic_action_ in 3.0).
-                 // However the table halfway down the page on
-                 // http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
-                 // and the README in the icon template download says that convention is ic_menu
-                    checkSize(context, folderName, file, 32, 32, true);
-                } else if (isAndroid23(context, folderVersion)) {
-                    // The icon should be 32x32 inside the transparent image; should
-                    // we check that this is mostly the case (a few pixels are allowed to
-                    // overlap for anti-aliasing etc)
-                    checkSize(context, folderName, file, 48, 48, true /*exact*/);
-                } else {
-                    // Android 2.2 or earlier
-                    // TODO: Should this be done for each folder size?
-                    checkSize(context, folderName, file, 48, 48, true /*exact*/);
-                }
-            }
-            // TODO: ListView icons?
-        }
-    }
-
-    /**
-     * Is this drawable folder for an Android 3.0 drawable? This will be the
-     * case if it specifies -v11+, or if the minimum SDK version declared in the
-     * manifest is at least 11.
-     */
-    private static boolean isAndroid30(Context context, int folderVersion) {
-        return folderVersion >= 11 || context.getMainProject().getMinSdk() >= 11;
-    }
-
-    /**
-     * Is this drawable folder for an Android 2.3 drawable? This will be the
-     * case if it specifies -v9 or -v10, or if the minimum SDK version declared in the
-     * manifest is 9 or 10 (and it does not specify some higher version like -v11
-     */
-    private static boolean isAndroid23(Context context, int folderVersion) {
-        if (isAndroid30(context, folderVersion)) {
-            return false;
-        }
-
-        if (folderVersion == 9 || folderVersion == 10) {
-            return true;
-        }
-
-        int minSdk = context.getMainProject().getMinSdk();
-
-        return minSdk == 9 || minSdk == 10;
-    }
-
-    private static float getMdpiScalingFactor(String folderName) {
-        // Can't do startsWith(DRAWABLE_MDPI) because the folder could
-        // be something like "drawable-sw600dp-mdpi".
-        if (folderName.contains("-mdpi")) {            //$NON-NLS-1$
-            return 1.0f;
-        } else if (folderName.contains("-hdpi")) {     //$NON-NLS-1$
-            return 1.5f;
-        } else if (folderName.contains("-xhdpi")) {    //$NON-NLS-1$
-            return 2.0f;
-        } else if (folderName.contains("-xxhdpi")) {   //$NON-NLS-1$
-            return 3.0f;
-        } else if (folderName.contains("-xxxhdpi")) {   //$NON-NLS-1$
-            return 4.0f;
-        } else if (folderName.contains("-ldpi")) {     //$NON-NLS-1$
-            return 0.75f;
-        } else {
-            return 0f;
-        }
-    }
-
-    private static void checkSize(Context context, String folderName, File file,
-            int mdpiWidth, int mdpiHeight, boolean exactMatch) {
-        String fileName = file.getName();
-        // Only scan .png files (except 9-patch png's) and jpg files
-        if (!((endsWith(fileName, DOT_PNG) && !endsWith(fileName, DOT_9PNG)) ||
-                endsWith(fileName, DOT_JPG) || endsWith(fileName, DOT_JPEG))) {
-            return;
-        }
-
-        int width;
-        int height;
-        // Use 3:4:6:8 scaling ratio to look up the other expected sizes
-        if (folderName.startsWith(DRAWABLE_MDPI)) {
-            width = mdpiWidth;
-            height = mdpiHeight;
-        } else if (folderName.startsWith(DRAWABLE_HDPI)) {
-            // Perform math using floating point; if we just do
-            //   width = mdpiWidth * 3 / 2;
-            // then for mdpiWidth = 25 (as in notification icons on pre-GB) we end up
-            // with width = 37, instead of 38 (with floating point rounding we get 37.5 = 38)
-            width = Math.round(mdpiWidth * 3.f / 2);
-            height = Math.round(mdpiHeight * 3f / 2);
-        } else if (folderName.startsWith(DRAWABLE_XHDPI)) {
-            width = mdpiWidth * 2;
-            height = mdpiHeight * 2;
-        } else if (folderName.startsWith(DRAWABLE_XXHDPI)) {
-            width = mdpiWidth * 3;
-            height = mdpiWidth * 3;
-        } else if (folderName.startsWith(DRAWABLE_LDPI)) {
-            width = Math.round(mdpiWidth * 3f / 4);
-            height = Math.round(mdpiHeight * 3f / 4);
-        } else {
-            return;
-        }
-
-        Dimension size = getSize(file);
-        if (size != null) {
-            if (exactMatch && (size.width != width || size.height != height)) {
-                context.report(
-                        ICON_EXPECTED_SIZE,
-                    Location.create(file),
-                    String.format(
-                        "Incorrect icon size for `%1$s`: expected %2$dx%3$d, but was %4$dx%5$d",
-                        folderName + File.separator + file.getName(),
-                        width, height, size.width, size.height));
-            } else if (!exactMatch && (size.width > width || size.height > height)) {
-                context.report(
-                        ICON_EXPECTED_SIZE,
-                    Location.create(file),
-                    String.format(
-                        "Incorrect icon size for `%1$s`: icon size should be at most %2$dx%3$d, but was %4$dx%5$d",
-                        folderName + File.separator + file.getName(),
-                        width, height, size.width, size.height));
-            }
-        }
-    }
-
-    private static Dimension getSize(File file) {
-        try {
-            ImageInputStream input = ImageIO.createImageInputStream(file);
-            if (input != null) {
-                try {
-                    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
-                    if (readers.hasNext()) {
-                        ImageReader reader = readers.next();
-                        try {
-                            reader.setInput(input);
-                            return new Dimension(reader.getWidth(0), reader.getHeight(0));
-                        } finally {
-                            reader.dispose();
-                        }
-                    }
-                } finally {
-                    input.close();
-                }
-            }
-
-            // Fallback: read the image using the normal means
-            BufferedImage image = ImageIO.read(file);
-            if (image != null) {
-                return new Dimension(image.getWidth(), image.getHeight());
-            } else {
-                return null;
-            }
-        } catch (IOException e) {
-            // Pass -- we can't handle all image types, warn about those we can
-            return null;
-        }
-    }
-
-
-    private Set<String> mActionBarIcons;
-    private Set<String> mNotificationIcons;
-    private Set<String> mLauncherIcons;
-    private Multimap<String, String> mMenuToIcons;
-
-    private boolean isLauncherIcon(String name) {
-        assert name.indexOf('.') == -1 : name; // Should supply base name
-
-        // Naming convention
-        //noinspection SimplifiableIfStatement
-        if (name.startsWith("ic_launcher")) { //$NON-NLS-1$
-            return true;
-        }
-        return mLauncherIcons != null && mLauncherIcons.contains(name);
-    }
-
-    private boolean isNotificationIcon(String name) {
-        assert name.indexOf('.') == -1; // Should supply base name
-
-        // Naming convention
-        //noinspection SimplifiableIfStatement
-        if (name.startsWith("ic_stat_")) { //$NON-NLS-1$
-            return true;
-        }
-
-        return mNotificationIcons != null && mNotificationIcons.contains(name);
-    }
-
-    private boolean isActionBarIcon(String name) {
-        assert name.indexOf('.') == -1; // Should supply base name
-
-        // Naming convention
-        //noinspection SimplifiableIfStatement
-        if (name.startsWith("ic_action_")) { //$NON-NLS-1$
-            return true;
-        }
-
-        // Naming convention
-
-        return mActionBarIcons != null && mActionBarIcons.contains(name);
-    }
-
-    private boolean isActionBarIcon(Context context, String name, File file) {
-        if (isActionBarIcon(name)) {
-            return true;
-        }
-
-        // As of Android 3.0 ic_menu_ are action icons
-        //noinspection SimplifiableIfStatement,RedundantIfStatement
-        if (file != null && name.startsWith("ic_menu_") //$NON-NLS-1$
-                && isAndroid30(context, context.getDriver().getResourceFolderVersion(file))) {
-            // Naming convention
-            return true;
-        }
-
-        return false;
-    }
-
-    // XML detector: Skim manifest and menu files
-
-    @Override
-    public boolean appliesTo(@NonNull Context context, @NonNull File file) {
-        return file.getName().equals(ANDROID_MANIFEST_XML);
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.MENU;
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(
-                // Manifest
-                TAG_APPLICATION,
-                TAG_ACTIVITY,
-                TAG_SERVICE,
-                TAG_PROVIDER,
-                TAG_RECEIVER,
-
-                // Menu
-                TAG_ITEM
-        );
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        String icon = element.getAttributeNS(ANDROID_URI, ATTR_ICON);
-        if (icon != null && icon.startsWith(DRAWABLE_PREFIX)) {
-            icon = icon.substring(DRAWABLE_PREFIX.length());
-
-            String tagName = element.getTagName();
-            if (tagName.equals(TAG_ITEM)) {
-                if (mMenuToIcons == null) {
-                    mMenuToIcons = ArrayListMultimap.create();
-                }
-                String menu = getBaseName(context.file.getName());
-                mMenuToIcons.put(menu, icon);
-            } else {
-                // Manifest tags: launcher icons
-                if (mLauncherIcons == null) {
-                    mLauncherIcons = Sets.newHashSet();
-                }
-                mLauncherIcons.add(icon);
-            }
-        }
-    }
-
-    // ---- Implements UastScanner ----
-
-    private static final String NOTIFICATION_CLASS = "android.app.Notification";
-    private static final String NOTIFICATION_BUILDER_CLASS = "android.app.Notification.Builder";
-    private static final String NOTIFICATION_COMPAT_BUILDER_CLASS =
-            "android.support.v4.app.NotificationCompat.Builder";
-    private static final String SET_SMALL_ICON = "setSmallIcon";
-    private static final String ON_CREATE_OPTIONS_MENU = "onCreateOptionsMenu";
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        List<Class<? extends UElement>> types = new ArrayList<Class<? extends UElement>>(2);
-        types.add(UCallExpression.class);
-        types.add(UMethod.class);
-        return types;
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new NotificationFinder(context);
-    }
-
-    private final class NotificationFinder extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private NotificationFinder(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitMethod(UMethod method) {
-            if (ON_CREATE_OPTIONS_MENU.equals(method.getName())) {
-                // Gather any R.menu references found in this method
-                method.accept(new MenuFinder());
-            }
-            return super.visitMethod(method);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (UastExpressionUtils.isConstructorCall(node)) {
-                visitConstructorCall(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void visitConstructorCall(UCallExpression node) {
-            UReferenceExpression classReference = node.getClassReference();
-            if (classReference == null) {
-                return;
-            }
-            PsiElement resolved = classReference.resolve();
-            if (!(resolved instanceof PsiClass)) {
-                return;
-            }
-            String typeName = ((PsiClass) resolved).getQualifiedName();
-            if (NOTIFICATION_CLASS.equals(typeName)) {
-                List<UExpression> args = node.getValueArguments();
-                if (args.size() == 3) {
-                    if (args.get(0) instanceof UReferenceExpression && handleSelect(args.get(0))) {
-                        return;
-                    }
-
-                    ResourceUrl url = ResourceEvaluator.getResource(mContext, args.get(0));
-                    if (url != null
-                            && (url.type == ResourceType.DRAWABLE
-                            || url.type == ResourceType.COLOR
-                            || url.type == ResourceType.MIPMAP)) {
-                        if (mNotificationIcons == null) {
-                            mNotificationIcons = Sets.newHashSet();
-                        }
-                        mNotificationIcons.add(url.name);
-                    }
-                }
-            } else if (NOTIFICATION_BUILDER_CLASS.equals(typeName)
-                    || NOTIFICATION_COMPAT_BUILDER_CLASS.equals(typeName)) {
-                UMethod method = UastUtils.getParentOfType(node, UMethod.class, true);
-                if (method != null) {
-                    SetIconFinder finder = new SetIconFinder();
-                    method.accept(finder);
-                }
-            }
-        }
-    }
-
-    private boolean handleSelect(UElement select) {
-        ResourceUrl url = ResourceEvaluator.getResourceConstant(select);
-        if (url != null && url.type == ResourceType.DRAWABLE && !url.framework) {
-            if (mNotificationIcons == null) {
-                mNotificationIcons = Sets.newHashSet();
-            }
-            mNotificationIcons.add(url.name);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    private final class SetIconFinder extends AbstractUastVisitor {
-
-        @Override
-        public boolean visitCallExpression(UCallExpression expression) {
-            if (UastExpressionUtils.isMethodCall(expression)) {
-                if (SET_SMALL_ICON.equals(expression.getMethodName())) {
-                    List<UExpression> arguments = expression.getValueArguments();
-                    if (arguments.size() == 1 && arguments.get(0) instanceof UReferenceExpression) {
-                        handleSelect(arguments.get(0));
-                    }
-                }
-            }
-            return super.visitCallExpression(expression);
-        }
-
-        @Override
-        public boolean visitClass(UClass node) {
-            if (node instanceof UAnonymousClass) {
-                return true;
-            }
-            return super.visitClass(node);
-        }
-    }
-
-    private final class MenuFinder extends AbstractUastVisitor {
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            ResourceUrl url = ResourceEvaluator.getResourceConstant(node);
-            if (url != null && url.type == ResourceType.MENU && !url.framework) {
-                // Reclassify icons in the given menu as action bar icons
-                if (mMenuToIcons != null) {
-                    Collection<String> icons = mMenuToIcons.get(url.name);
-                    if (icons != null) {
-                        if (mActionBarIcons == null) {
-                            mActionBarIcons = Sets.newHashSet();
-                        }
-                        mActionBarIcons.addAll(icons);
-                    }
-                }
-            }
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java
deleted file mode 100644
index b9581cb..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiType;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-
-import static com.android.SdkConstants.SUPPORT_LIB_ARTIFACT;
-import static com.android.tools.klint.client.api.JavaParser.*;
-import static com.android.tools.klint.detector.api.LintUtils.skipParentheses;
-
-/**
- * Looks for performance issues in Java files, such as memory allocations during
- * drawing operations and using HashMap instead of SparseArray.
- */
-public class JavaPerformanceDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            JavaPerformanceDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Allocating objects during a paint method */
-    public static final Issue PAINT_ALLOC = Issue.create(
-            "DrawAllocation", //$NON-NLS-1$
-            "Memory allocations within drawing code",
-
-            "You should avoid allocating objects during a drawing or layout operation. These " +
-            "are called frequently, so a smooth UI can be interrupted by garbage collection " +
-            "pauses caused by the object allocations.\n" +
-            "\n" +
-            "The way this is generally handled is to allocate the needed objects up front " +
-            "and to reuse them for each drawing operation.\n" +
-            "\n" +
-            "Some methods allocate memory on your behalf (such as `Bitmap.create`), and these " +
-            "should be handled in the same way.",
-
-            Category.PERFORMANCE,
-            9,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Using HashMaps where SparseArray would be better */
-    public static final Issue USE_SPARSE_ARRAY = Issue.create(
-            "UseSparseArrays", //$NON-NLS-1$
-            "HashMap can be replaced with SparseArray",
-
-            "For maps where the keys are of type integer, it's typically more efficient to " +
-            "use the Android `SparseArray` API. This check identifies scenarios where you might " +
-            "want to consider using `SparseArray` instead of `HashMap` for better performance.\n" +
-            "\n" +
-            "This is *particularly* useful when the value types are primitives like ints, " +
-            "where you can use `SparseIntArray` and avoid auto-boxing the values from `int` to " +
-            "`Integer`.\n" +
-            "\n" +
-            "If you need to construct a `HashMap` because you need to call an API outside of " +
-            "your control which requires a `Map`, you can suppress this warning using for " +
-            "example the `@SuppressLint` annotation.",
-
-            Category.PERFORMANCE,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Using {@code new Integer()} instead of the more efficient {@code Integer.valueOf} */
-    public static final Issue USE_VALUE_OF = Issue.create(
-            "UseValueOf", //$NON-NLS-1$
-            "Should use `valueOf` instead of `new`",
-
-            "You should not call the constructor for wrapper classes directly, such as" +
-            "`new Integer(42)`. Instead, call the `valueOf` factory method, such as " +
-            "`Integer.valueOf(42)`. This will typically use less memory because common integers " +
-            "such as 0 and 1 will share a single instance.",
-
-            Category.PERFORMANCE,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    static final String ON_MEASURE = "onMeasure";
-    static final String ON_DRAW = "onDraw";
-    static final String ON_LAYOUT = "onLayout";
-    private static final String LAYOUT = "layout";
-    private static final String HASH_MAP = "java.util.HashMap";
-    private static final String SPARSE_ARRAY = "android.util.SparseArray";
-    public static final String CLASS_CANVAS = "android.graphics.Canvas";
-
-    /** Constructs a new {@link JavaPerformanceDetector} check */
-    public JavaPerformanceDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        List<Class<? extends UElement>> types = new ArrayList<Class<? extends UElement>>(3);
-        types.add(UCallExpression.class);
-        types.add(UMethod.class);
-        return types;
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new PerformanceVisitor(context);
-    }
-
-    private static class PerformanceVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-        private final boolean mCheckMaps;
-        private final boolean mCheckAllocations;
-        private final boolean mCheckValueOf;
-        /** Whether allocations should be "flagged" in the current method */
-        private boolean mFlagAllocations;
-
-        public PerformanceVisitor(JavaContext context) {
-            mContext = context;
-
-            mCheckAllocations = context.isEnabled(PAINT_ALLOC);
-            mCheckMaps = context.isEnabled(USE_SPARSE_ARRAY);
-            mCheckValueOf = context.isEnabled(USE_VALUE_OF);
-        }
-
-        @Override
-        public boolean visitMethod(UMethod node) {
-            mFlagAllocations = isBlockedAllocationMethod(node);
-            return super.visitMethod(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (UastExpressionUtils.isConstructorCall(node)) {
-                visitConstructorCallExpression(node);
-            } else if (UastExpressionUtils.isMethodCall(node)) {
-                visitMethodCallExpression(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void visitConstructorCallExpression(UCallExpression node) {
-            String typeName = null;
-            UReferenceExpression classReference = node.getClassReference();
-            if (mCheckMaps || mCheckValueOf) {
-                if (classReference != null) {
-                    typeName = UastUtils.getQualifiedName(classReference);
-                }
-            }
-
-            if (mCheckMaps) {
-                // TODO: Should we handle factory method constructions of HashMaps as well,
-                // e.g. via Guava? This is a bit trickier since we need to infer the type
-                // arguments from the calling context.
-                if (HASH_MAP.equals(typeName)) {
-                    checkHashMap(node);
-                } else if (SPARSE_ARRAY.equals(typeName)) {
-                    checkSparseArray(node);
-                }
-            }
-
-            if (mCheckValueOf) {
-                if (typeName != null
-                        && (typeName.equals(TYPE_INTEGER_WRAPPER)
-                        || typeName.equals(TYPE_BOOLEAN_WRAPPER)
-                        || typeName.equals(TYPE_FLOAT_WRAPPER)
-                        || typeName.equals(TYPE_CHARACTER_WRAPPER)
-                        || typeName.equals(TYPE_LONG_WRAPPER)
-                        || typeName.equals(TYPE_DOUBLE_WRAPPER)
-                        || typeName.equals(TYPE_BYTE_WRAPPER))
-                        //&& node.astTypeReference().astParts().size() == 1
-                        && node.getValueArgumentCount() == 1) {
-                    String argument = node.getValueArguments().get(0).asSourceString();
-                    mContext.report(USE_VALUE_OF, node, mContext.getUastLocation(node), getUseValueOfErrorMessage(
-                            typeName, argument));
-                }
-            }
-
-            if (mFlagAllocations
-                    && !(skipParentheses(node.getUastParent()) instanceof UThrowExpression)
-                    && mCheckAllocations) {
-                // Make sure we're still inside the method declaration that marked
-                // mInDraw as true, in case we've left it and we're in a static
-                // block or something:
-                PsiMethod method = UastUtils.getParentOfType(node, UMethod.class);
-                if (method != null && isBlockedAllocationMethod(method)
-                        && !isLazilyInitialized(node)) {
-                    reportAllocation(node);
-                }
-            }
-        }
-
-        private void reportAllocation(UElement node) {
-            mContext.report(PAINT_ALLOC, node, mContext.getUastLocation(node),
-                "Avoid object allocations during draw/layout operations (preallocate and " +
-                "reuse instead)");
-        }
-
-        private void visitMethodCallExpression(UCallExpression node) {
-            if (!mFlagAllocations) {
-                return;
-            }
-            UExpression receiver = node.getReceiver();
-            if (receiver == null) {
-                return;
-            }
-
-            String functionName = node.getMethodName();
-            if (functionName == null) {
-                return;
-            }
-
-            // Look for forbidden methods
-            if (functionName.equals("createBitmap")                              //$NON-NLS-1$
-                    || functionName.equals("createScaledBitmap")) {              //$NON-NLS-1$
-                PsiMethod method = node.resolve();
-                if (method != null && JavaEvaluator.isMemberInClass(method,
-                        "android.graphics.Bitmap") && !isLazilyInitialized(node)) {
-                    reportAllocation(node);
-                }
-            } else if (functionName.startsWith("decode")) {                      //$NON-NLS-1$
-                // decodeFile, decodeByteArray, ...
-                PsiMethod method = node.resolve();
-                if (method != null && JavaEvaluator.isMemberInClass(method,
-                        "android.graphics.BitmapFactory") && !isLazilyInitialized(node)) {
-                    reportAllocation(node);
-                }
-            } else if (functionName.equals("getClipBounds")) {                   //$NON-NLS-1$
-                if (node.getValueArguments().isEmpty()) {
-                    mContext.report(PAINT_ALLOC, node, mContext.getUastLocation(node),
-                            "Avoid object allocations during draw operations: Use " +
-                                    "`Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` " +
-                                    "which allocates a temporary `Rect`");
-                }
-            }
-        }
-
-        /**
-         * Check whether the given invocation is done as a lazy initialization,
-         * e.g. {@code if (foo == null) foo = new Foo();}.
-         * <p>
-         * This tries to also handle the scenario where the check is on some
-         * <b>other</b> variable - e.g.
-         * <pre>
-         *    if (foo == null) {
-         *        foo == init1();
-         *        bar = new Bar();
-         *    }
-         * </pre>
-         * or
-         * <pre>
-         *    if (!initialized) {
-         *        initialized = true;
-         *        bar = new Bar();
-         *    }
-         * </pre>
-         */
-        private static boolean isLazilyInitialized(UElement node) {
-            UElement curr = node.getUastParent();
-            while (curr != null) {
-                if (curr instanceof UMethod) {
-                    return false;
-                } else if (curr instanceof UIfExpression) {
-                    UIfExpression ifNode = (UIfExpression) curr;
-                    // See if the if block represents a lazy initialization:
-                    // compute all variable names seen in the condition
-                    // (e.g. for "if (foo == null || bar != foo)" the result is "foo,bar"),
-                    // and then compute all variables assigned to in the if body,
-                    // and if there is an overlap, we'll consider the whole if block
-                    // guarded (so lazily initialized and an allocation we won't complain
-                    // about.)
-                    List<String> assignments = new ArrayList<String>();
-                    AssignmentTracker visitor = new AssignmentTracker(assignments);
-                    if (ifNode.getThenExpression() != null) {
-                        ifNode.getThenExpression().accept(visitor);
-                    }
-                    if (!assignments.isEmpty()) {
-                        List<String> references = new ArrayList<String>();
-                        addReferencedVariables(references, ifNode.getCondition());
-                        if (!references.isEmpty()) {
-                            SetView<String> intersection = Sets.intersection(
-                                    new HashSet<String>(assignments),
-                                    new HashSet<String>(references));
-                            return !intersection.isEmpty();
-                        }
-                    }
-                    return false;
-
-                }
-                curr = curr.getUastParent();
-            }
-
-            return false;
-        }
-
-        /** Adds any variables referenced in the given expression into the given list */
-        private static void addReferencedVariables(
-                @NonNull Collection<String> variables,
-                @Nullable UExpression expression) {
-            if (expression instanceof UBinaryExpression) {
-                UBinaryExpression binary = (UBinaryExpression) expression;
-                addReferencedVariables(variables, binary.getLeftOperand());
-                addReferencedVariables(variables, binary.getRightOperand());
-            } else if (expression instanceof UPrefixExpression) {
-                UPrefixExpression unary = (UPrefixExpression) expression;
-                addReferencedVariables(variables, unary.getOperand());
-            } else if (expression instanceof UParenthesizedExpression) {
-                UParenthesizedExpression exp = (UParenthesizedExpression) expression;
-                addReferencedVariables(variables, exp.getExpression());
-            } else if (expression instanceof USimpleNameReferenceExpression) {
-                USimpleNameReferenceExpression reference = (USimpleNameReferenceExpression) expression;
-                variables.add(reference.getIdentifier());
-            } else if (expression instanceof UQualifiedReferenceExpression) {
-                UQualifiedReferenceExpression ref = (UQualifiedReferenceExpression) expression;
-                UExpression receiver = ref.getReceiver();
-                UExpression selector = ref.getSelector();
-                if (receiver instanceof UThisExpression || receiver instanceof USuperExpression) {
-                    String identifier = (selector instanceof USimpleNameReferenceExpression)
-                            ? ((USimpleNameReferenceExpression) selector).getIdentifier()
-                            : null;
-                    if (identifier != null) {
-                        variables.add(identifier);
-                    }
-                }
-            }
-        }
-
-        /**
-         * Returns whether the given method declaration represents a method
-         * where allocating objects is not allowed for performance reasons
-         */
-        private boolean isBlockedAllocationMethod(
-                @NonNull PsiMethod node) {
-            JavaEvaluator evaluator = mContext.getEvaluator();
-            return isOnDrawMethod(evaluator, node)
-                    || isOnMeasureMethod(evaluator, node)
-                    || isOnLayoutMethod(evaluator, node)
-                    || isLayoutMethod(evaluator, node);
-        }
-
-        /**
-         * Returns true if this method looks like it's overriding android.view.View's
-         * {@code protected void onDraw(Canvas canvas)}
-         */
-        private static boolean isOnDrawMethod(
-                @NonNull JavaEvaluator evaluator,
-                @NonNull PsiMethod node) {
-            return ON_DRAW.equals(node.getName()) && evaluator.parametersMatch(node, CLASS_CANVAS);
-        }
-
-        /**
-         * Returns true if this method looks like it's overriding
-         * android.view.View's
-         * {@code protected void onLayout(boolean changed, int left, int top,
-         *      int right, int bottom)}
-         */
-        private static boolean isOnLayoutMethod(
-                @NonNull JavaEvaluator evaluator,
-                @NonNull PsiMethod node) {
-            return ON_LAYOUT.equals(node.getName()) && evaluator.parametersMatch(node,
-                    TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT);
-        }
-
-        /**
-         * Returns true if this method looks like it's overriding android.view.View's
-         * {@code protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)}
-         */
-        private static boolean isOnMeasureMethod(
-                @NonNull JavaEvaluator evaluator,
-                @NonNull PsiMethod node) {
-            return ON_MEASURE.equals(node.getName()) && evaluator.parametersMatch(node,
-                    TYPE_INT, TYPE_INT);
-        }
-
-        /**
-         * Returns true if this method looks like it's overriding android.view.View's
-         * {@code public void layout(int l, int t, int r, int b)}
-         */
-        private static boolean isLayoutMethod(
-                @NonNull JavaEvaluator evaluator,
-                @NonNull PsiMethod node) {
-            return LAYOUT.equals(node.getName()) && evaluator.parametersMatch(node,
-                    TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT);
-        }
-
-        /**
-         * Checks whether the given constructor call and type reference refers
-         * to a HashMap constructor call that is eligible for replacement by a
-         * SparseArray call instead
-         */
-        private void checkHashMap(@NonNull UCallExpression node) {
-            List<PsiType> types = node.getTypeArguments();
-            if (types.size() == 2) {
-                PsiType first = types.get(0);
-                String typeName = first.getCanonicalText();
-                int minSdk = mContext.getMainProject().getMinSdk();
-                if (TYPE_INTEGER_WRAPPER.equals(typeName) || TYPE_BYTE_WRAPPER.equals(typeName)) {
-                    String valueType = types.get(1).getCanonicalText();
-                    if (valueType.equals(TYPE_INTEGER_WRAPPER)) {
-                        mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                            "Use new `SparseIntArray(...)` instead for better performance");
-                    } else if (valueType.equals(TYPE_LONG_WRAPPER) && minSdk >= 18) {
-                        mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                                "Use `new SparseLongArray(...)` instead for better performance");
-                    } else if (valueType.equals(TYPE_BOOLEAN_WRAPPER)) {
-                        mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                                "Use `new SparseBooleanArray(...)` instead for better performance");
-                    } else {
-                        mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                            String.format(
-                                "Use `new SparseArray<%1$s>(...)` instead for better performance",
-                              valueType.substring(valueType.lastIndexOf('.') + 1)));
-                    }
-                } else if (TYPE_LONG_WRAPPER.equals(typeName) && (minSdk >= 16 ||
-                        Boolean.TRUE == mContext.getMainProject().dependsOn(
-                                SUPPORT_LIB_ARTIFACT))) {
-                    boolean useBuiltin = minSdk >= 16;
-                    String message = useBuiltin ?
-                            "Use `new LongSparseArray(...)` instead for better performance" :
-                            "Use `new android.support.v4.util.LongSparseArray(...)` instead for better performance";
-                    mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                            message);
-                }
-            }
-        }
-
-        private void checkSparseArray(@NonNull UCallExpression node) {
-            List<PsiType> types = node.getTypeArguments();
-            if (types.size() == 1) {
-                String valueType = types.get(0).getCanonicalText();
-                if (valueType.equals(TYPE_INTEGER_WRAPPER)) {
-                    mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                        "Use `new SparseIntArray(...)` instead for better performance");
-                } else if (valueType.equals(TYPE_BOOLEAN_WRAPPER)) {
-                    mContext.report(USE_SPARSE_ARRAY, node, mContext.getUastLocation(node),
-                            "Use `new SparseBooleanArray(...)` instead for better performance");
-                }
-            }
-        }
-    }
-    
-    private static String getUseValueOfErrorMessage(String typeName, String argument) {
-        // Keep in sync with {@link #getReplacedType} below
-        return String.format("Use `%1$s.valueOf(%2$s)` instead",
-                typeName.substring(typeName.lastIndexOf('.') + 1), argument);
-    }
-
-    /**
-     * For an error message for an {@link #USE_VALUE_OF} issue reported by this detector,
-     * returns the type being replaced. Intended to use for IDE quickfix implementations.
-     */
-    @SuppressWarnings("unused") // Used by the IDE
-    @Nullable
-    public static String getReplacedType(@NonNull String message, @NonNull TextFormat format) {
-        message = format.toText(message);
-        int index = message.indexOf('.');
-        if (index != -1 && message.startsWith("Use ")) {
-            return message.substring(4, index);
-        }
-        return null;
-    }
-
-    /** Visitor which records variable names assigned into */
-    private static class AssignmentTracker extends AbstractUastVisitor {
-        private final Collection<String> mVariables;
-
-        public AssignmentTracker(Collection<String> variables) {
-            mVariables = variables;
-        }
-
-        @Override
-        public boolean visitBinaryExpression(UBinaryExpression node) {
-            if (UastExpressionUtils.isAssignment(node)) {
-                UExpression left = node.getLeftOperand();
-                if (left instanceof UQualifiedReferenceExpression) {
-                    UQualifiedReferenceExpression ref = (UQualifiedReferenceExpression) left;
-                    if (ref.getReceiver() instanceof UThisExpression ||
-                            ref.getReceiver() instanceof USuperExpression) {
-                        PsiElement resolved = ref.resolve();
-                        if (resolved instanceof PsiField) {
-                            mVariables.add(((PsiField) resolved).getName());
-                        }
-                    } else {
-                        PsiElement resolved = ref.resolve();
-                        if (resolved instanceof PsiField) {
-                            mVariables.add(((PsiField) resolved).getName());
-                        }
-                    }
-                } else if (left instanceof USimpleNameReferenceExpression) {
-                    mVariables.add(((USimpleNameReferenceExpression) left).getIdentifier());
-                }
-            }
-            
-            return super.visitBinaryExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java
deleted file mode 100644
index b4f9369..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TypeEvaluator;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiModifierList;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for addJavascriptInterface calls on interfaces have been properly annotated
- * with {@code @JavaScriptInterface}
- */
-public class JavaScriptInterfaceDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "JavascriptInterface", //$NON-NLS-1$
-            "Missing @JavascriptInterface on methods",
-
-            "As of API 17, you must annotate methods in objects registered with the " +
-            "`addJavascriptInterface` method with a `@JavascriptInterface` annotation.",
-
-            Category.SECURITY,
-            8,
-            Severity.ERROR,
-            new Implementation(
-                    JavaScriptInterfaceDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo(
-            "http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)"); //$NON-NLS-1$
-
-    private static final String ADD_JAVASCRIPT_INTERFACE = "addJavascriptInterface"; //$NON-NLS-1$
-    private static final String JAVASCRIPT_INTERFACE_CLS = "android.webkit.JavascriptInterface"; //$NON-NLS-1$
-    private static final String WEB_VIEW_CLS = "android.webkit.WebView"; //$NON-NLS-1$
-
-    /** Constructs a new {@link JavaScriptInterfaceDetector} check */
-    public JavaScriptInterfaceDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(ADD_JAVASCRIPT_INTERFACE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        if (context.getMainProject().getTargetSdk() < 17) {
-            return;
-        }
-
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.size() != 2) {
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!JavaEvaluator.isMemberInClass(method, WEB_VIEW_CLS)) {
-            return;
-        }
-
-        UExpression first = arguments.get(0);
-        PsiType evaluated = TypeEvaluator.evaluate(context, first);
-        if (evaluated instanceof PsiClassType) {
-            PsiClassType classType = (PsiClassType) evaluated;
-            PsiClass cls = classType.resolve();
-            if (cls == null) {
-                return;
-            }
-            if (isJavaScriptAnnotated(cls)) {
-                return;
-            }
-
-            Location location = context.getUastNameLocation(call);
-            String message = String.format(
-                    "None of the methods in the added interface (%1$s) have been annotated " +
-                            "with `@android.webkit.JavascriptInterface`; they will not " +
-                            "be visible in API 17", cls.getName());
-            context.report(ISSUE, call, location, message);
-        }
-    }
-
-    private static boolean isJavaScriptAnnotated(PsiClass clz) {
-        while (clz != null) {
-            PsiModifierList modifierList = clz.getModifierList();
-            if (modifierList != null
-                    && modifierList.findAnnotation(JAVASCRIPT_INTERFACE_CLS) != null) {
-                return true;
-            }
-
-            for (PsiMethod method : clz.getMethods()) {
-                if (method.getModifierList().findAnnotation(JAVASCRIPT_INTERFACE_CLS) != null) {
-                    return true;
-                }
-            }
-
-            clz = clz.getSuperClass();
-        }
-
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutConsistencyDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutConsistencyDetector.java
deleted file mode 100644
index ddc1a69..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutConsistencyDetector.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_PREFIX;
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_ID;
-import static com.android.tools.klint.detector.api.LintUtils.stripIdPrefix;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.android.utils.Pair;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.psi.JavaElementVisitor;
-import com.intellij.psi.PsiElement;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Checks for consistency in layouts across different resource folders
- */
-public class LayoutConsistencyDetector extends LayoutDetector implements Detector.UastScanner {
-
-    /** Map from layout resource names to a list of files defining that resource,
-     * and within each file the value is a map from string ids to the widget type
-     * used by that id in this file */
-    private final Map<String, List<Pair<File, Map<String, String>>>> mMap =
-            Maps.newHashMapWithExpectedSize(64);
-
-    /** Ids referenced from .java files. Only ids referenced from code are considered
-     * vital to be consistent among the layout variations (others could just have ids
-     * assigned to them in the layout either automatically by the layout editor or there
-     * in order to support RelativeLayout constraints etc, but not be problematic
-     * in findViewById calls.)
-     */
-    private final Set<String> mRelevantIds = Sets.newLinkedHashSetWithExpectedSize(64);
-
-    /** Map from layout to id name to a list of locations */
-    private Map<String, Map<String, List<Location>>> mLocations;
-
-    /** Map from layout to id name to the error message to display for each */
-    private Map<String, Map<String, String>> mErrorMessages;
-
-    /** Inconsistent widget types */
-    public static final Issue INCONSISTENT_IDS = Issue.create(
-            "InconsistentLayout", //$NON-NLS-1$
-            "Inconsistent Layouts",
-
-            "This check ensures that a layout resource which is defined in multiple "
-            + "resource folders, specifies the same set of widgets.\n"
-            + "\n"
-            + "This finds cases where you have accidentally forgotten to add "
-            + "a widget to all variations of the layout, which could result "
-            + "in a runtime crash for some resource configurations when a "
-            + "`findViewById()` fails.\n"
-            + "\n"
-            + "There *are* cases where this is intentional. For example, you "
-            + "may have a dedicated large tablet layout which adds some extra "
-            + "widgets that are not present in the phone version of the layout. "
-            + "As long as the code accessing the layout resource is careful to "
-            + "handle this properly, it is valid. In that case, you can suppress "
-            + "this lint check for the given extra or missing views, or the whole "
-            + "layout",
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    LayoutConsistencyDetector.class,
-                    Scope.JAVA_AND_RESOURCE_FILES));
-
-    /** Constructs a consistency check */
-    public LayoutConsistencyDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.LAYOUT;
-    }
-
-    @Override
-    public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
-        Element root = document.getDocumentElement();
-        if (root != null) {
-            if (context.getPhase() == 1) {
-                // Map from ids to types
-                Map<String,String> fileMap = Maps.newHashMapWithExpectedSize(10);
-                addIds(root, fileMap);
-
-                getFileMapList(context).add(Pair.of(context.file, fileMap));
-            } else {
-                String name = LintUtils.getLayoutName(context.file);
-                Map<String, List<Location>> map = mLocations.get(name);
-                if (map != null) {
-                    lookupLocations(context, root, map);
-                }
-            }
-        }
-    }
-
-    @NonNull
-    private List<Pair<File, Map<String, String>>> getFileMapList(
-            @NonNull XmlContext context) {
-        String name = LintUtils.getLayoutName(context.file);
-        List<Pair<File, Map<String, String>>> list = mMap.get(name);
-        if (list == null) {
-            list = Lists.newArrayListWithCapacity(4);
-            mMap.put(name, list);
-        }
-        return list;
-    }
-
-    @Nullable
-    private static String getId(@NonNull Element element) {
-        String id = element.getAttributeNS(ANDROID_URI, ATTR_ID);
-        if (id != null && !id.isEmpty() && !id.startsWith(ANDROID_PREFIX)) {
-            return stripIdPrefix(id);
-        }
-        return null;
-    }
-
-    private static void addIds(Element element, Map<String,String> map) {
-        String id = getId(element);
-        if (id != null) {
-            String s = stripIdPrefix(id);
-            map.put(s, element.getTagName());
-        }
-
-        NodeList childNodes = element.getChildNodes();
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                addIds((Element) child, map);
-            }
-        }
-    }
-
-    private static void lookupLocations(
-            @NonNull XmlContext context,
-            @NonNull Element element,
-            @NonNull Map<String, List<Location>> map) {
-        String id = getId(element);
-        if (id != null) {
-            if (map.containsKey(id)) {
-                if (context.getDriver().isSuppressed(context, INCONSISTENT_IDS, element)) {
-                    map.remove(id);
-                    return;
-                }
-
-                List<Location> locations = map.get(id);
-                if (locations == null) {
-                    locations = Lists.newArrayList();
-                    map.put(id, locations);
-                }
-                Attr attr = element.getAttributeNodeNS(ANDROID_URI, ATTR_ID);
-                assert attr != null;
-                Location location = context.getLocation(attr);
-                String folder = context.file.getParentFile().getName();
-                location.setMessage(String.format("Occurrence in %1$s", folder));
-                locations.add(location);
-            }
-        }
-
-        NodeList childNodes = element.getChildNodes();
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                lookupLocations(context, (Element) child, map);
-            }
-        }
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        LintDriver driver = context.getDriver();
-        if (driver.getPhase() == 1) {
-            // First phase: gather all the ids and look for consistency issues.
-            // If any are found, request location computation in phase 2 by
-            // writing the ids needed for each layout in the {@link #mLocations} map.
-            for (Map.Entry<String,List<Pair<File,Map<String,String>>>> entry : mMap.entrySet()) {
-                String layout = entry.getKey();
-                List<Pair<File, Map<String, String>>> files = entry.getValue();
-                if (files.size() < 2) {
-                    // No consistency problems for files that don't have resource variations
-                    continue;
-                }
-
-                checkConsistentIds(layout, files);
-            }
-
-            if (mLocations != null) {
-                driver.requestRepeat(this, Scope.ALL_RESOURCES_SCOPE);
-            }
-        } else {
-            // Collect results and print
-            if (!mLocations.isEmpty()) {
-                reportErrors(context);
-            }
-        }
-    }
-
-    @NonNull
-    private Set<String> stripIrrelevantIds(@NonNull Set<String> ids) {
-        if (!mRelevantIds.isEmpty()) {
-            Set<String> stripped = new HashSet<String>(ids);
-            stripped.retainAll(mRelevantIds);
-            return stripped;
-        }
-
-        return Collections.emptySet();
-    }
-
-    private void checkConsistentIds(
-            @NonNull String layout,
-            @NonNull List<Pair<File, Map<String, String>>> files) {
-        int layoutCount = files.size();
-        assert layoutCount >= 2;
-
-        Map<File, Set<String>> idMap = getIdMap(files, layoutCount);
-        Set<String> inconsistent = getInconsistentIds(idMap);
-        if (inconsistent.isEmpty()) {
-            return;
-        }
-
-        if (mLocations == null) {
-            mLocations = Maps.newHashMap();
-        }
-        if (mErrorMessages == null) {
-            mErrorMessages = Maps.newHashMap();
-        }
-
-        // Map from each id, to a list of layout folders it is present in
-        int idCount = inconsistent.size();
-        Map<String, List<String>> presence = Maps.newHashMapWithExpectedSize(idCount);
-        Set<String> allLayouts = Sets.newHashSetWithExpectedSize(layoutCount);
-        for (Map.Entry<File, Set<String>> entry : idMap.entrySet()) {
-            File file = entry.getKey();
-            String folder = file.getParentFile().getName();
-            allLayouts.add(folder);
-            Set<String> ids = entry.getValue();
-            for (String id : ids) {
-                List<String> list = presence.get(id);
-                if (list == null) {
-                    list = Lists.newArrayListWithExpectedSize(layoutCount);
-                    presence.put(id, list);
-                }
-                list.add(folder);
-            }
-        }
-
-        // Compute lookup maps which will be used in phase 2 to initialize actual
-        // locations for the id references
-
-        Map<String, List<Location>> map = Maps.newHashMapWithExpectedSize(idCount);
-        mLocations.put(layout, map);
-        Map<String, String> messages = Maps.newHashMapWithExpectedSize(idCount);
-        mErrorMessages.put(layout, messages);
-        for (String id : inconsistent) {
-            map.put(id, null); // The locations will be filled in during the second phase
-
-            // Determine presence description for this id
-            String message;
-            List<String> layouts = presence.get(id);
-            Collections.sort(layouts);
-
-            Set<String> missingSet = new HashSet<String>(allLayouts);
-            missingSet.removeAll(layouts);
-            List<String> missing = new ArrayList<String>(missingSet);
-            Collections.sort(missing);
-
-            if (layouts.size() < layoutCount / 2) {
-                message = String.format(
-                        "The id \"%1$s\" in layout \"%2$s\" is only present in the following "
-                                + "layout configurations: %3$s (missing from %4$s)",
-                        id, layout,
-                        LintUtils.formatList(layouts, Integer.MAX_VALUE),
-                        LintUtils.formatList(missing, Integer.MAX_VALUE));
-            } else {
-                message = String.format(
-                        "The id \"%1$s\" in layout \"%2$s\" is missing from the following layout "
-                                + "configurations: %3$s (present in %4$s)",
-                        id, layout, LintUtils.formatList(missing, Integer.MAX_VALUE),
-                        LintUtils.formatList(layouts, Integer.MAX_VALUE));
-            }
-            messages.put(id, message);
-        }
-    }
-
-    private static Set<String> getInconsistentIds(Map<File, Set<String>> idMap) {
-        Set<String> union = getAllIds(idMap);
-        Set<String> inconsistent = new HashSet<String>();
-        for (Map.Entry<File, Set<String>> entry : idMap.entrySet()) {
-            Set<String> ids = entry.getValue();
-            if (ids.size() < union.size()) {
-                Set<String> missing = new HashSet<String>(union);
-                missing.removeAll(ids);
-                inconsistent.addAll(missing);
-            }
-        }
-        return inconsistent;
-    }
-
-    private static Set<String> getAllIds(Map<File, Set<String>> idMap) {
-        Iterator<Set<String>> iterator = idMap.values().iterator();
-        assert iterator.hasNext();
-        Set<String> union = new HashSet<String>(iterator.next());
-        while (iterator.hasNext()) {
-            union.addAll(iterator.next());
-        }
-        return union;
-    }
-
-    private Map<File, Set<String>> getIdMap(List<Pair<File, Map<String, String>>> files,
-            int layoutCount) {
-        Map<File, Set<String>> idMap = new HashMap<File, Set<String>>(layoutCount);
-        for (Pair<File, Map<String, String>> pair : files) {
-            File file = pair.getFirst();
-            Map<String, String> typeMap = pair.getSecond();
-            Set<String> ids = typeMap.keySet();
-            idMap.put(file, stripIrrelevantIds(ids));
-        }
-        return idMap;
-    }
-
-    private void reportErrors(Context context) {
-        List<String> layouts = new ArrayList<String>(mLocations.keySet());
-        Collections.sort(layouts);
-
-        for (String layout : layouts) {
-            Map<String, List<Location>> locationMap = mLocations.get(layout);
-            Map<String, String> messageMap = mErrorMessages.get(layout);
-            assert locationMap != null;
-            assert messageMap != null;
-
-            List<String> ids = new ArrayList<String>(locationMap.keySet());
-            Collections.sort(ids);
-            for (String id : ids) {
-                String message = messageMap.get(id);
-                List<Location> locations = locationMap.get(id);
-                if (locations != null) {
-                    Location location = chainLocations(locations);
-
-                    context.report(INCONSISTENT_IDS, location, message);
-                }
-            }
-        }
-    }
-
-    @NonNull
-    private static Location chainLocations(@NonNull List<Location> locations) {
-        assert !locations.isEmpty();
-
-        // Sort locations by the file parent folders
-        if (locations.size() > 1) {
-            Collections.sort(locations, new Comparator<Location>() {
-                @Override
-                public int compare(Location location1, Location location2) {
-                    File file1 = location1.getFile();
-                    File file2 = location2.getFile();
-                    String folder1 = file1.getParentFile().getName();
-                    String folder2 = file2.getParentFile().getName();
-                    return folder1.compareTo(folder2);
-                }
-            });
-            // Chain locations together
-            Iterator<Location> iterator = locations.iterator();
-            assert iterator.hasNext();
-            Location prev = iterator.next();
-            while (iterator.hasNext()) {
-                Location next = iterator.next();
-                prev.setSecondary(next);
-                prev = next;
-            }
-        }
-
-        return locations.get(0);
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public boolean appliesToResourceRefs() {
-        return true;
-    }
-
-    @Override
-    public void visitResourceReference(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UElement node, @NonNull ResourceType type, @NonNull String name,
-            boolean isFramework) {
-        if (!isFramework && type == ResourceType.ID) {
-            mRelevantIds.add(name);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutInflationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutInflationDetector.java
deleted file mode 100644
index c66853f..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LayoutInflationDetector.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
-import static com.android.tools.klint.checks.ViewHolderDetector.INFLATE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceFile;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.AndroidReference;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.android.utils.Pair;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastLiteralUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.kxml2.io.KXmlParser;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Looks for layout inflation calls passing null as the view root
- */
-public class LayoutInflationDetector extends LayoutDetector implements Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            LayoutInflationDetector.class,
-            Scope.JAVA_AND_RESOURCE_FILES,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Passing in a null parent to a layout inflater */
-    public static final Issue ISSUE = Issue.create(
-            "InflateParams", //$NON-NLS-1$
-            "Layout Inflation without a Parent",
-
-            "When inflating a layout, avoid passing in null as the parent view, since " +
-            "otherwise any layout parameters on the root of the inflated layout will be ignored.",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo("http://www.doubleencore.com/2013/05/layout-inflation-as-intended");
-
-    private static final String ERROR_MESSAGE =
-            "Avoid passing `null` as the view root (needed to resolve "
-            + "layout parameters on the inflated layout's root element)";
-
-    /** Constructs a new {@link LayoutInflationDetector} check */
-    public LayoutInflationDetector() {
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mPendingErrors != null) {
-            for (Pair<String,Location> pair : mPendingErrors) {
-                String inflatedLayout = pair.getFirst();
-                if (mLayoutsWithRootLayoutParams == null ||
-                        !mLayoutsWithRootLayoutParams.contains(inflatedLayout)) {
-                    // No root layout parameters on the inflated layout: no need to complain
-                    continue;
-                }
-                Location location = pair.getSecond();
-                context.report(ISSUE, location, ERROR_MESSAGE);
-            }
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-
-    private Set<String> mLayoutsWithRootLayoutParams;
-    private List<Pair<String,Location>> mPendingErrors;
-
-    @Override
-    public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
-        Element root = document.getDocumentElement();
-        if (root != null) {
-            NamedNodeMap attributes = root.getAttributes();
-            for (int i = 0, n = attributes.getLength(); i < n; i++) {
-                Attr attribute = (Attr) attributes.item(i);
-                if (attribute.getLocalName() != null
-                        && attribute.getLocalName().startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) {
-                    if (mLayoutsWithRootLayoutParams == null) {
-                        mLayoutsWithRootLayoutParams = Sets.newHashSetWithExpectedSize(20);
-                    }
-                    mLayoutsWithRootLayoutParams.add(LintUtils.getBaseName(context.file.getName()));
-                    break;
-                }
-            }
-        }
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(INFLATE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        assert method.getName().equals(INFLATE);
-        if (call.getReceiver() == null) {
-            return;
-        }
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.size() < 2) {
-            return;
-        }
-
-        UExpression second = arguments.get(1);
-        if (!UastLiteralUtils.isNullLiteral(second)) {
-            return;
-        }
-
-        UExpression first = arguments.get(0);
-        AndroidReference androidReference = UastLintUtils.toAndroidReferenceViaResolve(first);
-        if (androidReference == null) {
-            return;
-        }
-
-        String layoutName = androidReference.getName();
-        if (context.getScope().contains(Scope.RESOURCE_FILE)) {
-            // We're doing a full analysis run: we can gather this information
-            // incrementally
-            if (!context.getDriver().isSuppressed(context, ISSUE, call)) {
-                if (mPendingErrors == null) {
-                    mPendingErrors = Lists.newArrayList();
-                }
-                Location location = context.getUastLocation(second);
-                mPendingErrors.add(Pair.of(layoutName, location));
-            }
-        } else if (hasLayoutParams(context, layoutName)) {
-            context.report(ISSUE, call, context.getUastLocation(second), ERROR_MESSAGE);
-        }
-    }
-
-    private static boolean hasLayoutParams(@NonNull JavaContext context, String name) {
-        LintClient client = context.getClient();
-        if (!client.supportsProjectResources()) {
-            return true; // not certain
-        }
-
-        Project project = context.getProject();
-        AbstractResourceRepository resources = client.getProjectResources(project, true);
-        if (resources == null) {
-            return true; // not certain
-        }
-
-        List<ResourceItem> items = resources.getResourceItem(ResourceType.LAYOUT, name);
-        if (items == null || items.isEmpty()) {
-            return false;
-        }
-
-        for (ResourceItem item : items) {
-            ResourceFile source = item.getSource();
-            if (source == null) {
-                return true; // not certain
-            }
-            File file = source.getFile();
-            if (file.exists()) {
-                try {
-                    String s = context.getClient().readFile(file);
-                    if (hasLayoutParams(new StringReader(s))) {
-                        return true;
-                    }
-                } catch (Exception e) {
-                    context.log(e, "Could not read/parse inflated layout");
-                    return true; // not certain
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @VisibleForTesting
-    static boolean hasLayoutParams(@NonNull Reader reader)
-            throws XmlPullParserException, IOException {
-        KXmlParser parser = new KXmlParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(reader);
-
-        while (true) {
-            int event = parser.next();
-            if (event == XmlPullParser.START_TAG) {
-                for (int i = 0; i < parser.getAttributeCount(); i++) {
-                    if (parser.getAttributeName(i).startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) {
-                        String prefix = parser.getAttributePrefix(i);
-                        if (prefix != null && !prefix.isEmpty() &&
-                                ANDROID_URI.equals(parser.getNamespace(prefix))) {
-                            return true;
-                        }
-                    }
-                }
-
-                return false;
-            } else if (event == XmlPullParser.END_DOCUMENT) {
-                return false;
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LeakDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LeakDetector.java
deleted file mode 100644
index d900484..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LeakDetector.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.SdkConstants.CLASS_FRAGMENT;
-import static com.android.SdkConstants.CLASS_VIEW;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiModifier;
-import com.intellij.psi.PsiModifierList;
-import com.intellij.psi.PsiType;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UField;
-import org.jetbrains.uast.UVariable;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for leaks via static fields
- */
-public class LeakDetector extends Detector implements Detector.UastScanner {
-    /** Leaking data via static fields */
-    public static final Issue ISSUE = Issue.create(
-            "StaticFieldLeak", //$NON-NLS-1$
-            "Static Field Leaks",
-
-            "A static field will leak contexts.",
-
-            Category.PERFORMANCE,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    LeakDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link LeakDetector} check */
-    public LeakDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<Class<? extends PsiElement>> getApplicablePsiTypes() {
-        return Collections.<Class<? extends PsiElement>>singletonList(PsiField.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new FieldChecker(context);
-    }
-
-    private static class FieldChecker extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private FieldChecker(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitClass(@NotNull UClass node) {
-            return super.visitClass(node);
-        }
-
-        @Override
-        public boolean visitVariable(UVariable node) {
-            if (node instanceof UField) {
-                checkField((UField) node);
-            }
-            return super.visitVariable(node);
-        }
-
-        private void checkField(UField field) {
-            PsiModifierList modifierList = field.getModifierList();
-            if (modifierList == null || !modifierList.hasModifierProperty(PsiModifier.STATIC)) {
-                return;
-            }
-
-            PsiType type = field.getType();
-            if (!(type instanceof PsiClassType)) {
-                return;
-            }
-
-            String fqn = type.getCanonicalText();
-            if (fqn.startsWith("java.")) {
-                return;
-            }
-            PsiClass cls = ((PsiClassType) type).resolve();
-            if (cls == null) {
-                return;
-            }
-            if (fqn.startsWith("android.")) {
-                if (isLeakCandidate(cls)) {
-                    String message = "Do not place Android context classes in static fields; "
-                            + "this is a memory leak (and also breaks Instant Run)";
-                    report(field, message);
-                }
-            } else {
-                // User application object -- look to see if that one itself has
-                // static fields?
-                // We only check *one* level of indirection here
-                int count = 0;
-                for (PsiField referenced : cls.getAllFields()) {
-                    // Only check a few; avoid getting bogged down on large classes
-                    if (count++ == 20) {
-                        break;
-                    }
-
-                    PsiType innerType = referenced.getType();
-                    if (!(innerType instanceof PsiClassType)) {
-                        continue;
-                    }
-
-                    fqn = innerType.getCanonicalText();
-                    if (fqn.startsWith("java.")) {
-                        continue;
-                    }
-                    PsiClass innerCls = ((PsiClassType) innerType).resolve();
-                    if (innerCls == null) {
-                        continue;
-                    }
-                    if (fqn.startsWith("android.")) {
-                        if (isLeakCandidate(innerCls)) {
-                            String message =
-                                    "Do not place Android context classes in static fields "
-                                            + "(static reference to `"
-                                            + cls.getName() + "` which has field "
-                                            + "`" + referenced.getName() + "` pointing to `"
-                                            + innerCls.getName() + "`); "
-                                        + "this is a memory leak (and also breaks Instant Run)";
-                            report(field, message);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        private void report(@NonNull UElement element, @NonNull String message) {
-            mContext.report(ISSUE, element, mContext.getUastLocation(element), message);
-        }
-    }
-
-    private static boolean isLeakCandidate(@NonNull PsiClass cls) {
-        return InheritanceUtil.isInheritor(cls, false, CLASS_CONTEXT)
-                               || InheritanceUtil.isInheritor(cls, false, CLASS_VIEW)
-                               || InheritanceUtil.isInheritor(cls, false, CLASS_FRAGMENT);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LocaleDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LocaleDetector.java
deleted file mode 100644
index 98dd50b..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LocaleDetector.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.FORMAT_METHOD;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for errors related to locale handling
- */
-public class LocaleDetector extends Detector implements Detector.UastScanner {
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            LocaleDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Calling risky convenience methods */
-    public static final Issue STRING_LOCALE = Issue.create(
-            "DefaultLocale", //$NON-NLS-1$
-            "Implied default locale in case conversion",
-
-            "Calling `String#toLowerCase()` or `#toUpperCase()` *without specifying an " +
-            "explicit locale* is a common source of bugs. The reason for that is that those " +
-            "methods will use the current locale on the user's device, and even though the " +
-            "code appears to work correctly when you are developing the app, it will fail " +
-            "in some locales. For example, in the Turkish locale, the uppercase replacement " +
-            "for `i` is *not* `I`.\n" +
-            "\n" +
-            "If you want the methods to just perform ASCII replacement, for example to convert " +
-            "an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to " +
-            "use the current locale, call `String#toUpperCase(Locale.getDefault())` instead.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo(
-            "http://developer.android.com/reference/java/util/Locale.html#default_locale"); //$NON-NLS-1$
-
-    /** Constructs a new {@link LocaleDetector} */
-    public LocaleDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        if (LintClient.isStudio()) {
-            // In the IDE, don't flag toUpperCase/toLowerCase; these
-            // are already flagged by built-in IDE inspections, so we don't
-            // want duplicate warnings.
-            return Collections.singletonList(FORMAT_METHOD);
-        } else {
-            return Arrays.asList(
-                    // Only when not running in the IDE
-                    "toLowerCase", //$NON-NLS-1$
-                    "toUpperCase", //$NON-NLS-1$
-                    FORMAT_METHOD
-            );
-        }
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        if (JavaEvaluator.isMemberInClass(method, TYPE_STRING)) {
-            String name = method.getName();
-            if (name.equals(FORMAT_METHOD)) {
-                checkFormat(context, method, call);
-            } else if (method.getParameterList().getParametersCount() == 0) {
-                Location location = context.getUastNameLocation(call);
-                String message = String.format(
-                        "Implicitly using the default locale is a common source of bugs: " +
-                                "Use `%1$s(Locale)` instead", name);
-                context.report(STRING_LOCALE, call, location, message);
-            }
-        }
-    }
-
-    /** Returns true if the given node is a parameter to a Logging call */
-    private static boolean isLoggingParameter(@NonNull UCallExpression node) {
-        UCallExpression parentCall =
-                UastUtils.getParentOfType(node, UCallExpression.class, true);
-        if (parentCall != null) {
-            String name = parentCall.getMethodName();
-            if (name != null && name.length() == 1) { // "d", "i", "e" etc in Log
-                PsiMethod method = parentCall.resolve();
-                return JavaEvaluator.isMemberInClass(method, LogDetector.LOG_CLS);
-            }
-        }
-
-        return false;
-    }
-
-    private static void checkFormat(
-            @NonNull JavaContext context,
-            @NonNull PsiMethod method,
-            @NonNull UCallExpression call) {
-        // Only check the non-locale version of String.format
-        if (method.getParameterList().getParametersCount() == 0
-                || !context.getEvaluator().parameterHasType(method, 0, TYPE_STRING)) {
-            return;
-        }
-        List<UExpression> expressions = call.getValueArguments();
-        if (expressions.isEmpty()) {
-            return;
-        }
-
-        // Find the formatting string
-        UExpression first = expressions.get(0);
-        Object value = ConstantEvaluator.evaluate(context, first);
-        if (!(value instanceof String)) {
-            return;
-        }
-
-        String format = (String) value;
-        if (StringFormatDetector.isLocaleSpecific(format)) {
-            if (isLoggingParameter(call)) {
-                return;
-            }
-            Location location = context.getUastLocation(call);
-            String message =
-                    "Implicitly using the default locale is a common source of bugs: " +
-                            "Use `String.format(Locale, ...)` instead";
-            context.report(STRING_LOCALE, call, location, message);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LogDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LogDetector.java
deleted file mode 100644
index 2bebea10..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/LogDetector.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.*;
-import com.intellij.psi.*;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.*;
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-/**
- * Detector for finding inefficiencies and errors in logging calls.
- */
-public class LogDetector extends Detector implements Detector.UastScanner {
-    private static final Implementation IMPLEMENTATION = new Implementation(
-          LogDetector.class, Scope.JAVA_FILE_SCOPE);
-
-
-    /** Log call missing surrounding if */
-    public static final Issue CONDITIONAL = Issue.create(
-            "LogConditional", //$NON-NLS-1$
-            "Unconditional Logging Calls",
-            "The BuildConfig class (available in Tools 17) provides a constant, \"DEBUG\", " +
-            "which indicates whether the code is being built in release mode or in debug " +
-            "mode. In release mode, you typically want to strip out all the logging calls. " +
-            "Since the compiler will automatically remove all code which is inside a " +
-            "\"if (false)\" check, surrounding your logging calls with a check for " +
-            "BuildConfig.DEBUG is a good idea.\n" +
-            "\n" +
-            "If you *really* intend for the logging to be present in release mode, you can " +
-            "suppress this warning with a @SuppressLint annotation for the intentional " +
-            "logging calls.",
-
-            Category.PERFORMANCE,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION).setEnabledByDefault(false);
-
-    /** Mismatched tags between isLogging and log calls within it */
-    public static final Issue WRONG_TAG = Issue.create(
-            "LogTagMismatch", //$NON-NLS-1$
-            "Mismatched Log Tags",
-            "When guarding a `Log.v(tag, ...)` call with `Log.isLoggable(tag)`, the " +
-            "tag passed to both calls should be the same. Similarly, the level passed " +
-            "in to `Log.isLoggable` should typically match the type of `Log` call, e.g. " +
-            "if checking level `Log.DEBUG`, the corresponding `Log` call should be `Log.d`, " +
-            "not `Log.i`.",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** Log tag is too long */
-    public static final Issue LONG_TAG = Issue.create(
-            "LongLogTag", //$NON-NLS-1$
-            "Too Long Log Tags",
-            "Log tags are only allowed to be at most 23 tag characters long.",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    @SuppressWarnings("SpellCheckingInspection")
-    private static final String IS_LOGGABLE = "isLoggable";       //$NON-NLS-1$
-    public static final String LOG_CLS = "android.util.Log";     //$NON-NLS-1$
-    private static final String PRINTLN = "println";              //$NON-NLS-1$
-
-    private static final Map<String, String> TAG_PAIRS;
-
-    static {
-        Map<String, String> pairs = new HashMap<String, String>();
-        pairs.put("d", "DEBUG");
-        pairs.put("e", "ERROR");
-        pairs.put("i", "INFO");
-        pairs.put("v", "VERBOSE");
-        pairs.put("w", "WARN");
-        TAG_PAIRS = Collections.unmodifiableMap(pairs);
-    }
-
-    // ---- Implements Detector.UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                "d",           //$NON-NLS-1$
-                "e",           //$NON-NLS-1$
-                "i",           //$NON-NLS-1$
-                "v",           //$NON-NLS-1$
-                "w",           //$NON-NLS-1$
-                PRINTLN,
-                IS_LOGGABLE);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!JavaEvaluator.isMemberInClass(method, LOG_CLS)) {
-            return;
-        }
-
-        String name = method.getName();
-        boolean withinConditional = IS_LOGGABLE.equals(name) ||
-                checkWithinConditional(context, node.getUastParent(), node);
-
-        // See if it's surrounded by an if statement (and it's one of the non-error, spammy
-        // log methods (info, verbose, etc))
-        if (("i".equals(name) || "d".equals(name) || "v".equals(name) || PRINTLN.equals(name))
-                && !withinConditional
-                && performsWork(node)
-                && context.isEnabled(CONDITIONAL)) {
-            String message = String.format("The log call Log.%1$s(...) should be " +
-                            "conditional: surround with `if (Log.isLoggable(...))` or " +
-                            "`if (BuildConfig.DEBUG) { ... }`",
-                    name);
-            context.report(CONDITIONAL, node, context.getUastLocation(node), message);
-        }
-
-        // Check tag length
-        if (context.isEnabled(LONG_TAG)) {
-            int tagArgumentIndex = PRINTLN.equals(name) ? 1 : 0;
-            PsiParameterList parameterList = method.getParameterList();
-            List<UExpression> argumentList = node.getValueArguments();
-            if (evaluator.parameterHasType(method, tagArgumentIndex, TYPE_STRING)
-                    && parameterList.getParametersCount() == argumentList.size()) {
-                UExpression argument = argumentList.get(tagArgumentIndex);
-                String tag = ConstantEvaluator.evaluateString(context, argument, true);
-                if (tag != null && tag.length() > 23) {
-                    String message = String.format(
-                            "The logging tag can be at most 23 characters, was %1$d (%2$s)",
-                            tag.length(), tag);
-                    context.report(LONG_TAG, node, context.getUastLocation(node), message);
-                }
-            }
-        }
-
-    }
-
-    /** Returns true if the given logging call performs "work" to compute the message */
-    private static boolean performsWork(@NonNull UCallExpression node) {
-        String referenceName = node.getMethodName();
-        if (referenceName == null) {
-            return false;
-        }
-        int messageArgumentIndex = PRINTLN.equals(referenceName) ? 2 : 1;
-        List<UExpression> arguments = node.getValueArguments();
-        if (arguments.size() > messageArgumentIndex) {
-            UExpression argument = arguments.get(messageArgumentIndex);
-            if (argument == null) {
-                return false;
-            }
-            if (argument instanceof ULiteralExpression) {
-                return false;
-            }
-            if (argument instanceof UBinaryExpression) {
-                String string = UastUtils.evaluateString(argument);
-                //noinspection VariableNotUsedInsideIf
-                if (string != null) { // does it resolve to a constant?
-                    return false;
-                }
-            } else if (argument instanceof USimpleNameReferenceExpression) {
-                // Just a simple local variable/field reference
-                return false;
-            } else if (argument instanceof UQualifiedReferenceExpression) {
-                String string = UastUtils.evaluateString(argument);
-                //noinspection VariableNotUsedInsideIf
-                if (string != null) {
-                    return false;
-                }
-                PsiElement resolved = ((UQualifiedReferenceExpression) argument).resolve();
-                if (resolved instanceof PsiVariable) {
-                    // Just a reference to a property/field, parameter or variable
-                    return false;
-                }
-            }
-
-            // Method invocations etc
-            return true;
-        }
-
-        return false;
-    }
-
-    private static boolean checkWithinConditional(
-            @NonNull JavaContext context,
-            @Nullable UElement curr,
-            @NonNull UCallExpression logCall) {
-        while (curr != null) {
-            if (curr instanceof UIfExpression) {
-
-                UExpression condition = ((UIfExpression) curr).getCondition();
-                if (condition instanceof UQualifiedReferenceExpression) {
-                    condition = getLastInQualifiedChain((UQualifiedReferenceExpression) condition);
-                }
-
-                if (condition instanceof UCallExpression) {
-                    UCallExpression call = (UCallExpression) condition;
-                    if (IS_LOGGABLE.equals(call.getMethodName())) {
-                        checkTagConsistent(context, logCall, call);
-                    }
-                }
-
-                return true;
-            } else if (curr instanceof UCallExpression
-                       || curr instanceof UMethod
-                       || curr instanceof UClassInitializer
-                       || curr instanceof UField
-                       || curr instanceof UClass) { // static block
-                break;
-            }
-            curr = curr.getUastParent();
-        }
-        return false;
-    }
-
-    /** Checks that the tag passed to Log.s and Log.isLoggable match */
-    private static void checkTagConsistent(JavaContext context, UCallExpression logCall,
-            UCallExpression isLoggableCall) {
-        List<UExpression> isLoggableArguments = isLoggableCall.getValueArguments();
-        List<UExpression> logArguments = logCall.getValueArguments();
-        if (isLoggableArguments.isEmpty() || logArguments.isEmpty()) {
-            return;
-        }
-        UExpression isLoggableTag = isLoggableArguments.get(0);
-        UExpression logTag = logArguments.get(0);
-
-        String logCallName = logCall.getMethodName();
-        if (logCallName == null) {
-            return;
-        }
-        boolean isPrintln = PRINTLN.equals(logCallName);
-        if (isPrintln && logArguments.size() > 1) {
-            logTag = logArguments.get(1);
-        }
-
-        if (logTag != null) {
-            if (!areLiteralsEqual(isLoggableTag, logTag) &&
-                !UastLintUtils.areIdentifiersEqual(isLoggableTag, logTag)) {
-                PsiNamedElement resolved1 = UastUtils.tryResolveNamed(isLoggableTag);
-                PsiNamedElement resolved2 = UastUtils.tryResolveNamed(logTag);
-                if ((resolved1 == null || resolved2 == null || !resolved1.equals(resolved2))
-                        && context.isEnabled(WRONG_TAG)) {
-                    Location location = context.getUastLocation(logTag);
-                    Location alternate = context.getUastLocation(isLoggableTag);
-                    alternate.setMessage("Conflicting tag");
-                    location.setSecondary(alternate);
-                    String isLoggableDescription = resolved1 != null
-                            ? resolved1.getName()
-                            : isLoggableTag.asRenderString();
-                    String logCallDescription = resolved2 != null
-                            ? resolved2.getName()
-                            : logTag.asRenderString();
-                    String message = String.format(
-                            "Mismatched tags: the `%1$s()` and `isLoggable()` calls typically " +
-                                    "should pass the same tag: `%2$s` versus `%3$s`",
-                            logCallName,
-                            isLoggableDescription,
-                            logCallDescription);
-                    context.report(WRONG_TAG, isLoggableCall, location, message);
-                }
-            }
-        }
-
-        // Check log level versus the actual log call type (e.g. flag
-        //    if (Log.isLoggable(TAG, Log.DEBUG) Log.info(TAG, "something")
-
-        if (logCallName.length() != 1 || isLoggableArguments.size() < 2) { // e.g. println
-            return;
-        }
-        UExpression isLoggableLevel = isLoggableArguments.get(1);
-        if (isLoggableLevel == null) {
-            return;
-        }
-
-        PsiNamedElement resolved = UastUtils.tryResolveNamed(isLoggableLevel);
-        if (resolved == null) {
-            return;
-        }
-
-        if (resolved instanceof PsiVariable) {
-            PsiClass containingClass = UastUtils.getContainingClass(resolved);
-            if (containingClass == null 
-                    || !"android.util.Log".equals(containingClass.getQualifiedName())
-                    || resolved.getName() == null
-                    || resolved.getName().equals(TAG_PAIRS.get(logCallName))) {
-                return;
-            }
-            
-            String expectedCall = resolved.getName().substring(0, 1)
-                    .toLowerCase(Locale.getDefault());
-
-            String message = String.format(
-                    "Mismatched logging levels: when checking `isLoggable` level `%1$s`, the " +
-                            "corresponding log call should be `Log.%2$s`, not `Log.%3$s`",
-                    resolved.getName(), expectedCall, logCallName);
-            Location location = context.getUastLocation(logCall.getMethodIdentifier());
-            Location alternate = context.getUastLocation(isLoggableLevel);
-            alternate.setMessage("Conflicting tag");
-            location.setSecondary(alternate);
-            context.report(WRONG_TAG, isLoggableCall, location, message);
-        }
-    }
-
-    @NonNull
-    private static UExpression getLastInQualifiedChain(@NonNull UQualifiedReferenceExpression node) {
-        UExpression last = node.getSelector();
-        while (last instanceof UQualifiedReferenceExpression) {
-            last = ((UQualifiedReferenceExpression) last).getSelector();
-        }
-        return last;
-    }
-
-    private static boolean areLiteralsEqual(UExpression first, UExpression second) {
-        if (!(first instanceof ULiteralExpression)) {
-            return false;
-        }
-
-        if (!(second instanceof ULiteralExpression)) {
-            return false;
-        }
-
-        Object firstValue = ((ULiteralExpression) first).getValue();
-        Object secondValue = ((ULiteralExpression) second).getValue();
-
-        if (firstValue == null) {
-            return secondValue == null;
-        }
-
-        return firstValue.equals(secondValue);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MathDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MathDetector.java
deleted file mode 100644
index bc6a2ca..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MathDetector.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Looks for usages of {@link Math} methods which can be replaced with
- * {@code android.util.FloatMath} methods to avoid casting.
- */
-public class MathDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "FloatMath", //$NON-NLS-1$
-            "Using `FloatMath` instead of `Math`",
-
-            "In older versions of Android, using `android.util.FloatMath` was recommended " +
-            "for performance reasons when operating on floats. However, on modern hardware " +
-            "doubles are just as fast as float (though they take more memory), and in " +
-            "recent versions of Android, `FloatMath` is actually slower than using `java.lang.Math` " +
-            "due to the way the JIT optimizes `java.lang.Math`. Therefore, you should use " +
-            "`Math` instead of `FloatMath` if you are only targeting Froyo and above.",
-
-            Category.PERFORMANCE,
-            3,
-            Severity.WARNING,
-            new Implementation(
-                    MathDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo(
-            "http://developer.android.com/guide/practices/design/performance.html#avoidfloat"); //$NON-NLS-1$
-
-    /** Constructs a new {@link MathDetector} check */
-    public MathDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                "sin",   //$NON-NLS-1$
-                "cos",   //$NON-NLS-1$
-                "ceil",  //$NON-NLS-1$
-                "sqrt",  //$NON-NLS-1$
-                "floor"  //$NON-NLS-1$
-        );
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        if (context.getEvaluator().isMemberInClass(method, "android.util.FloatMath")
-                && context.getProject().getMinSdk() >= 8) {
-            String message = String.format(
-                    "Use `java.lang.Math#%1$s` instead of `android.util.FloatMath#%1$s()` " +
-                            "since it is faster as of API 8", method.getName());
-            
-            Location location = context.getUastLocation(call.getMethodIdentifier());
-            context.report(ISSUE, call, location, message);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MergeRootFrameLayoutDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MergeRootFrameLayoutDetector.java
deleted file mode 100644
index 7bc51b3..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/MergeRootFrameLayoutDetector.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.AndroidReference;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.*;
-import com.android.tools.klint.detector.api.Location.Handle;
-import com.android.utils.Pair;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import java.util.*;
-
-import static com.android.SdkConstants.*;
-
-/**
- * Checks whether a root FrameLayout can be replaced with a {@code <merge>} tag.
- */
-public class MergeRootFrameLayoutDetector extends LayoutDetector implements Detector.UastScanner {
-    /**
-     * Set of layouts that we want to enable the warning for. We only warn for
-     * {@code <FrameLayout>}'s that are the root of a layout included from
-     * another layout, or directly referenced via a {@code setContentView} call.
-     */
-    private Set<String> mWhitelistedLayouts;
-
-    /**
-     * Set of pending [layout, location] pairs where the given layout is a
-     * FrameLayout that perhaps should be replaced by a {@code <merge>} tag (if
-     * the layout is included or set as the content view. This must be processed
-     * after the whole project has been scanned since the set of includes etc
-     * can be encountered after the included layout.
-     */
-    private List<Pair<String, Location.Handle>> mPending;
-
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "MergeRootFrame", //$NON-NLS-1$
-            "FrameLayout can be replaced with `<merge>` tag",
-
-            "If a `<FrameLayout>` is the root of a layout and does not provide background " +
-            "or padding etc, it can often be replaced with a `<merge>` tag which is slightly " +
-            "more efficient. Note that this depends on context, so make sure you understand " +
-            "how the `<merge>` tag works before proceeding.",
-            Category.PERFORMANCE,
-            4,
-            Severity.WARNING,
-            new Implementation(
-                    MergeRootFrameLayoutDetector.class,
-                    EnumSet.of(Scope.ALL_RESOURCE_FILES, Scope.JAVA_FILE)))
-            .addMoreInfo(
-            "http://android-developers.blogspot.com/2009/03/android-layout-tricks-3-optimize-by.html"); //$NON-NLS-1$
-
-    /** Constructs a new {@link MergeRootFrameLayoutDetector} */
-    public MergeRootFrameLayoutDetector() {
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mPending != null && mWhitelistedLayouts != null) {
-            // Process all the root FrameLayouts that are eligible, and generate
-            // suggestions for <merge> replacements for any layouts that are included
-            // from other layouts
-            for (Pair<String, Handle> pair : mPending) {
-                String layout = pair.getFirst();
-                if (mWhitelistedLayouts.contains(layout)) {
-                    Handle handle = pair.getSecond();
-
-                    Object clientData = handle.getClientData();
-                    if (clientData instanceof Node) {
-                        if (context.getDriver().isSuppressed(null, ISSUE, (Node) clientData)) {
-                            return;
-                        }
-                    }
-
-                    Location location = handle.resolve();
-                    context.report(ISSUE, location,
-                            "This `<FrameLayout>` can be replaced with a `<merge>` tag");
-                }
-            }
-        }
-    }
-
-    // Implements XmlScanner
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(VIEW_INCLUDE, FRAME_LAYOUT);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        String tag = element.getTagName();
-        if (tag.equals(VIEW_INCLUDE)) {
-            String layout = element.getAttribute(ATTR_LAYOUT); // NOTE: Not in android: namespace
-            if (layout.startsWith(LAYOUT_RESOURCE_PREFIX)) { // Ignore @android:layout/ layouts
-                layout = layout.substring(LAYOUT_RESOURCE_PREFIX.length());
-                whiteListLayout(layout);
-            }
-        } else {
-            assert tag.equals(FRAME_LAYOUT);
-            if (LintUtils.isRootElement(element) &&
-                ((isWidthFillParent(element) && isHeightFillParent(element)) ||
-                        !element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY))
-                    && !element.hasAttributeNS(ANDROID_URI, ATTR_BACKGROUND)
-                    && !element.hasAttributeNS(ANDROID_URI, ATTR_FOREGROUND)
-                    && !hasPadding(element)) {
-                String layout = LintUtils.getLayoutName(context.file);
-                Handle handle = context.createLocationHandle(element);
-                handle.setClientData(element);
-
-                if (!context.getProject().getReportIssues()) {
-                    // If this is a library project not being analyzed, ignore it
-                    return;
-                }
-
-                if (mPending == null) {
-                    mPending = new ArrayList<Pair<String,Handle>>();
-                }
-                mPending.add(Pair.of(layout, handle));
-            }
-        }
-    }
-
-    private void whiteListLayout(String layout) {
-        if (mWhitelistedLayouts == null) {
-            mWhitelistedLayouts = new HashSet<String>();
-        }
-        mWhitelistedLayouts.add(layout);
-    }
-
-    // Implements JavaScanner
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("setContentView"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        List<UExpression> expressions = call.getValueArguments();
-        
-        if (expressions.size() == 1) {
-            AndroidReference androidReference =
-                    UastLintUtils.toAndroidReferenceViaResolve(expressions.get(0));
-
-            if (androidReference != null && androidReference.getType() == ResourceType.LAYOUT) {
-                whiteListLayout(androidReference.getName());
-            }
-        }
-
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/NonInternationalizedSmsDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/NonInternationalizedSmsDetector.java
deleted file mode 100644
index 4781d1e..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/NonInternationalizedSmsDetector.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Detector looking for text messages sent to an unlocalized phone number. */
-public class NonInternationalizedSmsDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "UnlocalizedSms", //$NON-NLS-1$
-            "SMS phone number missing country code",
-
-            "SMS destination numbers must start with a country code or the application code " +
-            "must ensure that the SMS is only sent when the user is in the same country as " +
-            "the receiver.",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.WARNING,
-            new Implementation(
-                    NonInternationalizedSmsDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-
-    /** Constructs a new {@link NonInternationalizedSmsDetector} check */
-    public NonInternationalizedSmsDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-      List<String> methodNames = new ArrayList<String>(2);
-      methodNames.add("sendTextMessage");  //$NON-NLS-1$
-      methodNames.add("sendMultipartTextMessage");  //$NON-NLS-1$
-      return methodNames;
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        if (call.getReceiver() == null) {
-            // "sendTextMessage"/"sendMultipartTextMessage" in the code with no operand
-            return;
-        }
-
-        List<UExpression> args = call.getValueArguments();
-        if (args.size() != 5) {
-            return;
-        }
-        UExpression destinationAddress = args.get(0);
-        if (!(destinationAddress instanceof ULiteralExpression)) {
-            return;
-        }
-        Object literal = ((ULiteralExpression) destinationAddress).getValue();
-        if (!(literal instanceof String)) {
-            return;
-        }
-        String number = (String) literal;
-        if (number.startsWith("+")) {  //$NON-NLS-1$
-            return;
-        }
-        context.report(ISSUE, call, context.getUastLocation(destinationAddress),
-                "To make sure the SMS can be sent by all users, please start the SMS number " +
-                        "with a + and a country code or restrict the code invocation to people in the " +
-                        "country you are targeting.");
-    }
-}
\ No newline at end of file
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java
deleted file mode 100644
index 7f5cc93..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_BACKGROUND;
-import static com.android.SdkConstants.ATTR_CONTEXT;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_PARENT;
-import static com.android.SdkConstants.ATTR_THEME;
-import static com.android.SdkConstants.ATTR_TILE_MODE;
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.SdkConstants.DRAWABLE_PREFIX;
-import static com.android.SdkConstants.NULL_RESOURCE;
-import static com.android.SdkConstants.R_CLASS;
-import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
-import static com.android.SdkConstants.TAG_ACTIVITY;
-import static com.android.SdkConstants.TAG_APPLICATION;
-import static com.android.SdkConstants.TAG_BITMAP;
-import static com.android.SdkConstants.TAG_STYLE;
-import static com.android.SdkConstants.TOOLS_URI;
-import static com.android.SdkConstants.TRANSPARENT_COLOR;
-import static com.android.SdkConstants.VALUE_DISABLED;
-import static com.android.tools.klint.detector.api.LintUtils.endsWith;
-import static com.android.utils.SdkUtils.getResourceFieldName;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.AndroidReference;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.android.utils.Pair;
-import com.intellij.psi.JavaRecursiveElementVisitor;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiReferenceExpression;
-
-import org.jetbrains.uast.UAnonymousClass;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UQualifiedReferenceExpression;
-import org.jetbrains.uast.USimpleNameReferenceExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Check which looks for overdraw problems where view areas are painted and then
- * painted over, meaning that the bottom paint operation is a waste of time.
- */
-public class OverdrawDetector extends LayoutDetector implements Detector.UastScanner {
-    private static final String SET_THEME = "setTheme";         //$NON-NLS-1$
-
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "Overdraw", //$NON-NLS-1$
-            "Overdraw: Painting regions more than once",
-
-            "If you set a background drawable on a root view, then you should use a " +
-            "custom theme where the theme background is null. Otherwise, the theme background " +
-            "will be painted first, only to have your custom background completely cover it; " +
-            "this is called \"overdraw\".\n" +
-            "\n" +
-            "NOTE: This detector relies on figuring out which layouts are associated with " +
-            "which activities based on scanning the Java code, and it's currently doing that " +
-            "using an inexact pattern matching algorithm. Therefore, it can incorrectly " +
-            "conclude which activity the layout is associated with and then wrongly complain " +
-            "that a background-theme is hidden.\n" +
-            "\n" +
-            "If you want your custom background on multiple pages, then you should consider " +
-            "making a custom theme with your custom background and just using that theme " +
-            "instead of a root element background.\n" +
-            "\n" +
-            "Of course it's possible that your custom drawable is translucent and you want " +
-            "it to be mixed with the background. However, you will get better performance " +
-            "if you pre-mix the background with your drawable and use that resulting image or " +
-            "color as a custom theme background instead.\n",
-
-            Category.PERFORMANCE,
-            3,
-            Severity.WARNING,
-            new Implementation(
-                    OverdrawDetector.class,
-                    EnumSet.of(Scope.MANIFEST, Scope.JAVA_FILE, Scope.ALL_RESOURCE_FILES)));
-
-    /** Mapping from FQN activity names to theme names registered in the manifest */
-    private Map<String, String> mActivityToTheme;
-
-    /** The default theme declared in the manifest, or null */
-    private String mManifestTheme;
-
-    /** Mapping from layout name (not including {@code @layout/} prefix) to activity FQN */
-    private Map<String, List<String>> mLayoutToActivity;
-
-    /** List of theme names registered in the project which have blank backgrounds */
-    private List<String> mBlankThemes;
-
-    /** List of drawable resources that are not flagged for overdraw (XML drawables
-     * except for {@code <bitmap>} drawables without tiling) */
-    private List<String> mValidDrawables;
-
-    /**
-     * List of pairs of (location, background drawable) corresponding to root elements
-     * in layouts that define a given background drawable. These should be checked to
-     * see if they are painting on top of a non-transparent theme.
-     */
-    private List<Pair<Location, String>> mRootAttributes;
-
-    /** Constructs a new {@link OverdrawDetector} */
-    public OverdrawDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        // Look in layouts for drawable resources
-        return super.appliesTo(folderType)
-                // and in resource files for theme definitions
-                || folderType == ResourceFolderType.VALUES
-                // and in drawable files for bitmap tiling modes
-                || folderType == ResourceFolderType.DRAWABLE;
-    }
-
-    /** Is the given theme a "blank" theme (one not painting its background) */
-    private boolean isBlankTheme(String name) {
-        if (name.startsWith("@android:style/Theme_")) {               //$NON-NLS-1$
-            if (name.contains("NoFrame")                              //$NON-NLS-1$
-                    || name.contains("Theme_Wallpaper")               //$NON-NLS-1$
-                    || name.contains("Theme_Holo_Wallpaper")          //$NON-NLS-1$
-                    || name.contains("Theme_Translucent")             //$NON-NLS-1$
-                    || name.contains("Theme_Dialog_NoFrame")          //$NON-NLS-1$
-                    || name.contains("Theme_Holo_Dialog_Alert")       //$NON-NLS-1$
-                    || name.contains("Theme_Holo_Light_Dialog_Alert") //$NON-NLS-1$
-                    || name.contains("Theme_Dialog_Alert")            //$NON-NLS-1$
-                    || name.contains("Theme_Panel")                   //$NON-NLS-1$
-                    || name.contains("Theme_Light_Panel")             //$NON-NLS-1$
-                    || name.contains("Theme_Holo_Panel")              //$NON-NLS-1$
-                    || name.contains("Theme_Holo_Light_Panel")) {     //$NON-NLS-1$
-                return true;
-            }
-        }
-
-        return mBlankThemes != null && mBlankThemes.contains(name);
-
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mRootAttributes != null) {
-            for (Pair<Location, String> pair : mRootAttributes) {
-                Location location = pair.getFirst();
-
-                Object clientData = location.getClientData();
-                if (clientData instanceof Node) {
-                    if (context.getDriver().isSuppressed(null, ISSUE, (Node) clientData)) {
-                        return;
-                    }
-                }
-
-                String layoutName = location.getFile().getName();
-                if (endsWith(layoutName, DOT_XML)) {
-                    layoutName = layoutName.substring(0, layoutName.length() - DOT_XML.length());
-                }
-
-                String theme = getTheme(context, layoutName);
-                if (theme == null || !isBlankTheme(theme)) {
-                    String drawable = pair.getSecond();
-                    String message = String.format(
-                            "Possible overdraw: Root element paints background `%1$s` with " +
-                            "a theme that also paints a background (inferred theme is `%2$s`)",
-                            drawable, theme);
-                    // TODO: Compute applicable scope node
-                    context.report(ISSUE, location, message);
-                }
-            }
-        }
-    }
-
-    /** Return the theme to be used for the given layout */
-    private String getTheme(Context context, String layoutName) {
-        if (mActivityToTheme != null && mLayoutToActivity != null) {
-            List<String> activities = mLayoutToActivity.get(layoutName);
-            if (activities != null) {
-                for (String activity : activities) {
-                   String theme = mActivityToTheme.get(activity);
-                    if (theme != null) {
-                        return theme;
-                    }
-                }
-            }
-        }
-
-        if (mManifestTheme != null) {
-            return mManifestTheme;
-        }
-
-        Project project = context.getMainProject();
-        int apiLevel = project.getTargetSdk();
-        if (apiLevel == -1) {
-            apiLevel = project.getMinSdk();
-        }
-
-        if (apiLevel >= 11) {
-            return "@android:style/Theme.Holo"; //$NON-NLS-1$
-        } else {
-            return "@android:style/Theme"; //$NON-NLS-1$
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        // Ignore tools:background and any other custom attribute that isn't actually the
-        // android View background attribute
-        if (!ANDROID_URI.equals(attribute.getNamespaceURI())) {
-            return;
-        }
-
-        // Only consider the root element's background
-        Element documentElement = attribute.getOwnerDocument().getDocumentElement();
-        if (documentElement == attribute.getOwnerElement()) {
-            // If the drawable is a non-repeated pattern then the overdraw might be
-            // intentional since the image isn't covering the whole screen
-            String background = attribute.getValue();
-            if (mValidDrawables != null && mValidDrawables.contains(background)) {
-                return;
-            }
-
-            if (background.equals(TRANSPARENT_COLOR) || background.equals(NULL_RESOURCE)) {
-                return;
-            }
-
-            if (background.startsWith("@android:drawable/")) { //$NON-NLS-1$
-                // We haven't had a chance to study the builtin drawables the way we
-                // check the project local ones in scanBitmap() and beforeCheckFile(),
-                // but many of these are not bitmaps, so ignore these
-                return;
-            }
-
-            String name = context.file.getName();
-            if (name.contains("list_") || name.contains("_item")) { //$NON-NLS-1$ //$NON-NLS-2$
-                // Canonical list_item layout name: don't warn about these, it's
-                // pretty common to want to paint custom list item backgrounds
-                return;
-            }
-
-            if (!context.getProject().getReportIssues()) {
-                // If this is a library project not being analyzed, ignore it
-                return;
-            }
-
-            Location location = context.getLocation(attribute);
-            location.setClientData(attribute);
-            if (mRootAttributes == null) {
-                mRootAttributes = new ArrayList<Pair<Location,String>>();
-            }
-            mRootAttributes.add(Pair.of(location, attribute.getValue()));
-
-            String activity = documentElement.getAttributeNS(TOOLS_URI, ATTR_CONTEXT);
-            if (activity != null && !activity.isEmpty()) {
-                if (activity.startsWith(".")) { //$NON-NLS-1$
-                    activity = context.getProject().getPackage() + activity;
-                }
-                registerLayoutActivity(LintUtils.getLayoutName(context.file), activity);
-            }
-        }
-    }
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        return Collections.singletonList(
-                // Layouts: Look for background attributes on root elements for possible overdraw
-                ATTR_BACKGROUND
-        );
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(
-                // Manifest: Look at theme registrations
-                TAG_ACTIVITY,
-                TAG_APPLICATION,
-
-                // Resource files: Look at theme definitions
-                TAG_STYLE,
-
-                // Bitmaps
-                TAG_BITMAP
-        );
-    }
-
-    @Override
-    public void beforeCheckFile(@NonNull Context context) {
-        if (endsWith(context.file.getName(), DOT_XML)) {
-            // Drawable XML files should not be considered for overdraw, except for <bitmap>'s.
-            // The bitmap elements are handled in the scanBitmap() method; it will clear
-            // out anything added by this method.
-            File parent = context.file.getParentFile();
-            ResourceFolderType type = ResourceFolderType.getFolderType(parent.getName());
-            if (type == ResourceFolderType.DRAWABLE) {
-                if (mValidDrawables == null) {
-                    mValidDrawables = new ArrayList<String>();
-                }
-                String resource = getDrawableResource(context.file);
-                mValidDrawables.add(resource);
-            }
-        }
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        String tag = element.getTagName();
-        if (tag.equals(TAG_STYLE)) {
-            scanTheme(element);
-        } else if (tag.equals(TAG_ACTIVITY)) {
-            scanActivity(context, element);
-        } else if (tag.equals(TAG_APPLICATION)) {
-            if (element.hasAttributeNS(ANDROID_URI, ATTR_THEME)) {
-                mManifestTheme = element.getAttributeNS(ANDROID_URI, ATTR_THEME);
-            }
-        } else if (tag.equals(TAG_BITMAP)) {
-            scanBitmap(context, element);
-        }
-    }
-
-    private static String getDrawableResource(File drawableFile) {
-        String resource = drawableFile.getName();
-        if (endsWith(resource, DOT_XML)) {
-            resource = resource.substring(0, resource.length() - DOT_XML.length());
-        }
-        return DRAWABLE_PREFIX + resource;
-    }
-
-    private void scanBitmap(Context context, Element element) {
-        String tileMode = element.getAttributeNS(ANDROID_URI, ATTR_TILE_MODE);
-        if (!(tileMode.equals(VALUE_DISABLED) || tileMode.isEmpty())) {
-            if (mValidDrawables != null) {
-                String resource = getDrawableResource(context.file);
-                mValidDrawables.remove(resource);
-            }
-        }
-    }
-
-    private void scanActivity(Context context, Element element) {
-        String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-        if (name.indexOf('$') != -1) {
-            name = name.replace('$', '.');
-        }
-        if (name.startsWith(".")) {  //$NON-NLS-1$
-            String pkg = context.getProject().getPackage();
-            if (pkg != null && !pkg.isEmpty()) {
-                name = pkg + name;
-            }
-        }
-
-        String theme = element.getAttributeNS(ANDROID_URI, ATTR_THEME);
-        if (theme != null && !theme.isEmpty()) {
-            if (mActivityToTheme == null) {
-                mActivityToTheme = new HashMap<String, String>();
-            }
-            mActivityToTheme.put(name, getResourceFieldName(theme));
-        }
-    }
-
-    private void scanTheme(Element element) {
-        // Look for theme definitions, and record themes that provide a null background.
-        String styleName = element.getAttribute(ATTR_NAME);
-        String parent = element.getAttribute(ATTR_PARENT);
-        if (parent == null) {
-            // Eclipse DOM workaround
-            parent = "";
-        }
-
-        if (parent.isEmpty()) {
-            int index = styleName.lastIndexOf('.');
-            if (index != -1) {
-                parent = styleName.substring(0, index);
-            }
-        }
-        parent = parent.replace('.', '_');
-
-        String resource = STYLE_RESOURCE_PREFIX + getResourceFieldName(styleName);
-
-        NodeList items = element.getChildNodes();
-        for (int i = 0, n = items.getLength(); i < n; i++) {
-            if (items.item(i).getNodeType() == Node.ELEMENT_NODE) {
-                Element item = (Element) items.item(i);
-                String name = item.getAttribute(ATTR_NAME);
-                if (name.equals("android:windowBackground")) {      //$NON-NLS-1$
-                    NodeList textNodes = item.getChildNodes();
-                    for (int j = 0, m = textNodes.getLength(); j < m; j++) {
-                        Node textNode = textNodes.item(j);
-                        if (textNode.getNodeType() == Node.TEXT_NODE) {
-                            String text = textNode.getNodeValue();
-                            String trim = text.trim();
-                            if (!trim.isEmpty()) {
-                                if (trim.equals(NULL_RESOURCE)
-                                        || trim.equals(TRANSPARENT_COLOR)
-                                        || mValidDrawables != null
-                                            && mValidDrawables.contains(trim)) {
-                                    if (mBlankThemes == null) {
-                                        mBlankThemes = new ArrayList<String>();
-                                    }
-                                    mBlankThemes.add(resource);
-                                }
-                            }
-                        }
-                    }
-
-                    return;
-                }
-            }
-        }
-
-        if (isBlankTheme(parent)) {
-            if (mBlankThemes == null) {
-                mBlankThemes = new ArrayList<String>();
-            }
-            mBlankThemes.add(resource);
-        }
-    }
-
-    private void registerLayoutActivity(String layout, String classFqn) {
-        if (mLayoutToActivity == null) {
-            mLayoutToActivity = new HashMap<String, List<String>>();
-        }
-        List<String> list = mLayoutToActivity.get(layout);
-        if (list == null) {
-            list = new ArrayList<String>();
-            mLayoutToActivity.put(layout, list);
-        }
-        list.add(classFqn);
-    }
-
-    // ---- Implements UastScanner ----
-
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList("android.app.Activity");
-    }
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(UClass.class);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        if (!context.getProject().getReportIssues()) {
-            return;
-        }
-        String name = declaration.getQualifiedName();
-        if (name != null) {
-            declaration.accept(new OverdrawVisitor(name, declaration));
-        }
-    }
-
-    private class OverdrawVisitor extends AbstractUastVisitor {
-        private final String mName;
-        private final PsiClass mCls;
-
-        public OverdrawVisitor(String name, PsiClass cls) {
-            mName = name;
-            mCls = cls;
-        }
-
-        @Override
-        public boolean visitClass(UClass node) {
-            // Don't go into inner classes
-            if (mCls.equals(node.getPsi())) {
-                return true;
-            }
-            
-            return super.visitClass(node);
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            AndroidReference androidReference = UastLintUtils.toAndroidReferenceViaResolve(node);
-            if (androidReference != null && androidReference.getType() == ResourceType.LAYOUT) {
-                registerLayoutActivity(androidReference.getName(), mName);
-            }
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (SET_THEME.equals(node.getMethodName()) && node.getValueArgumentCount() == 1) {
-                // Look at argument
-                UExpression arg = node.getValueArguments().get(0);
-                AndroidReference androidReference = UastLintUtils.toAndroidReferenceViaResolve(arg);
-                if (androidReference != null && androidReference.getType() == ResourceType.STYLE) {
-                    String style = androidReference.getName();
-                    if (mActivityToTheme == null) {
-                        mActivityToTheme = new HashMap<String, String>();
-                    }
-                    mActivityToTheme.put(mName, STYLE_RESOURCE_PREFIX + style);
-                }
-            }
-
-            return super.visitCallExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverrideConcreteDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverrideConcreteDetector.java
deleted file mode 100644
index a1c9074..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverrideConcreteDetector.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.util.PsiTreeUtil;
-
-import org.jetbrains.uast.UClass;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks that subclasses of certain APIs are overriding all methods that were abstract
- * in one or more earlier API levels that are still targeted by the minSdkVersion
- * of this project.
- */
-public class OverrideConcreteDetector extends Detector implements Detector.UastScanner {
-    /** Are previously-abstract methods all overridden? */
-    public static final Issue ISSUE = Issue.create(
-        "OverrideAbstract", //$NON-NLS-1$
-        "Not overriding abstract methods on older platforms",
-
-        "To improve the usability of some APIs, some methods that used to be `abstract` have " +
-        "been made concrete by adding default implementations. This means that when compiling " +
-        "with new versions of the SDK, your code does not have to override these methods.\n" +
-        "\n" +
-        "However, if your code is also targeting older versions of the platform where these " +
-        "methods were still `abstract`, the code will crash. You must override all methods " +
-        "that used to be abstract in any versions targeted by your application's " +
-        "`minSdkVersion`.",
-
-        Category.CORRECTNESS,
-        6,
-        Severity.FATAL,
-        new Implementation(
-                OverrideConcreteDetector.class,
-                Scope.JAVA_FILE_SCOPE)
-    );
-
-    // This check is currently hardcoded for the specific case of the
-    // NotificationListenerService change in API 21. We should consider
-    // attempting to infer this information automatically from changes in
-    // the API current.txt file and making this detector more database driven,
-    // like the API detector.
-
-    private static final String NOTIFICATION_LISTENER_SERVICE_FQN
-            = "android.service.notification.NotificationListenerService";
-    public static final String STATUS_BAR_NOTIFICATION_FQN
-            = "android.service.notification.StatusBarNotification";
-    private static final String ON_NOTIFICATION_POSTED = "onNotificationPosted";
-    private static final String ON_NOTIFICATION_REMOVED = "onNotificationRemoved";
-    private static final int CONCRETE_IN = 21;
-
-    /** Constructs a new {@link OverrideConcreteDetector} */
-    public OverrideConcreteDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(NOTIFICATION_LISTENER_SERVICE_FQN);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isAbstract(declaration)) {
-            return;
-        }
-
-        int minSdk = Math.max(context.getProject().getMinSdk(), getTargetApi(declaration));
-        if (minSdk >= CONCRETE_IN) {
-            return;
-        }
-
-        String[] methodNames = {ON_NOTIFICATION_POSTED, ON_NOTIFICATION_REMOVED};
-        for (String methodName : methodNames) {
-            boolean found = false;
-            for (PsiMethod method : declaration.findMethodsByName(methodName, true)) {
-                // Make sure it's not the base method, but that it's been defined
-                // in a subclass, concretely
-                PsiClass containingClass = method.getContainingClass();
-                if (containingClass == null) {
-                    continue;
-                }
-                if (NOTIFICATION_LISTENER_SERVICE_FQN.equals(containingClass.getQualifiedName())) {
-                    continue;
-                }
-                // Make sure subclass isn't just defining another abstract definition
-                // of the method
-                if (evaluator.isAbstract(method)) {
-                    continue;
-                }
-                // Make sure it has the exact right signature
-                if (method.getParameterList().getParametersCount() != 1) {
-                    continue; // Wrong signature
-                }
-                if (!evaluator.parameterHasType(method, 0, STATUS_BAR_NOTIFICATION_FQN)) {
-                    continue;
-                }
-
-                found = true;
-                break;
-            }
-
-            if (!found) {
-                String message = String.format(
-                        "Must override `%1$s.%2$s(%3$s)`: Method was abstract until %4$d, and your `minSdkVersion` is %5$d",
-                        NOTIFICATION_LISTENER_SERVICE_FQN, methodName,
-                        STATUS_BAR_NOTIFICATION_FQN, CONCRETE_IN, minSdk);
-                context.reportUast(ISSUE, declaration, context.getUastNameLocation(declaration), message);
-                break;
-            }
-
-        }
-    }
-
-    private static int getTargetApi(@NonNull PsiClass node) {
-        while (node != null) {
-            int targetApi = ApiDetector.getTargetApi(node.getModifierList());
-            if (targetApi != -1) {
-                return targetApi;
-            }
-
-            node = PsiTreeUtil.getParentOfType(node, PsiClass.class, true);
-        }
-
-        return -1;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java
deleted file mode 100644
index 72c5136..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_PARCELABLE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiModifier;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UAnonymousClass;
-import org.jetbrains.uast.UClass;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for Parcelable classes that are missing a CREATOR field
- */
-public class ParcelDetector extends Detector implements Detector.UastScanner {
-
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "ParcelCreator", //$NON-NLS-1$
-            "Missing Parcelable `CREATOR` field",
-
-            "According to the `Parcelable` interface documentation, " +
-            "\"Classes implementing the Parcelable interface must also have a " +
-            "static field called `CREATOR`, which is an object implementing the " +
-            "`Parcelable.Creator` interface.\"",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.ERROR,
-            new Implementation(
-                    ParcelDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo("http://developer.android.com/reference/android/os/Parcelable.html");
-
-    /** Constructs a new {@link ParcelDetector} check */
-    public ParcelDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(CLASS_PARCELABLE);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        if (declaration instanceof UAnonymousClass) {
-            // Anonymous classes aren't parcelable
-            return;
-        }
-
-        // Only applies to concrete classes
-        if (declaration.isInterface()) {
-            return;
-        }
-        if (declaration.hasModifierProperty(PsiModifier.ABSTRACT)) {
-            return;
-        }
-
-        // Parceling spans is handled in TextUtils#CHAR_SEQUENCE_CREATOR
-        if (InheritanceUtil.isInheritor(declaration, false, "android.text.ParcelableSpan")) {
-            return;
-        }
-
-        PsiField field = declaration.findFieldByName("CREATOR", false);
-        if (field == null) {
-            Location location = context.getUastNameLocation(declaration);
-            context.reportUast(ISSUE, declaration, location,
-                    "This class implements `Parcelable` but does not "
-                            + "provide a `CREATOR` field");
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionFinder.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionFinder.java
deleted file mode 100644
index c95c3bf..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionFinder.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_INTENT;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION_READ;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION_WRITE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-import com.intellij.psi.PsiVariable;
-
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-
-import java.util.List;
-
-/**
- * Utility for locating permissions required by an intent or content resolver
- */
-public class PermissionFinder {
-    /**
-     * Operation that has a permission requirement -- such as a method call,
-     * a content resolver read or write operation, an intent, etc.
-     */
-    public enum Operation {
-        CALL, ACTION, READ, WRITE;
-
-        /** Prefix to use when describing a name with a permission requirement */
-        public String prefix() {
-            switch (this) {
-                case ACTION:
-                    return "by intent";
-                case READ:
-                    return "to read";
-                case WRITE:
-                    return "to write";
-                case CALL:
-                default:
-                    return "by";
-            }
-        }
-    }
-
-    /** A permission requirement given a name and operation */
-    public static class Result {
-        @NonNull public final PermissionRequirement requirement;
-        @NonNull public final String name;
-        @NonNull public final Operation operation;
-
-        public Result(
-                @NonNull Operation operation,
-                @NonNull PermissionRequirement requirement,
-                @NonNull String name) {
-            this.operation = operation;
-            this.requirement = requirement;
-            this.name = name;
-        }
-    }
-    
-    /**
-     * Searches for a permission requirement for the given parameter in the given call
-     *
-     * @param operation the operation to look up
-     * @param context   the context to use for lookup
-     * @param parameter the parameter which contains the value which implies the permission
-     * @return the result with the permission requirement, or null if nothing is found
-     */
-    @Nullable
-    public static Result findRequiredPermissions(
-            @NonNull Operation operation,
-            @NonNull JavaContext context,
-            @NonNull UElement parameter) {
-
-        // To find the permission required by an intent, we proceed in 3 steps:
-        // (1) Locate the parameter in the start call that corresponds to
-        //     the Intent
-        //
-        // (2) Find the place where the intent is initialized, and figure
-        //     out the action name being passed to it.
-        //
-        // (3) Find the place where the action is defined, and look for permission
-        //     annotations on that action declaration!
-
-        return new PermissionFinder(context, operation).search(parameter);
-    }
-
-    private PermissionFinder(@NonNull JavaContext context, @NonNull Operation operation) {
-        mContext = context;
-        mOperation = operation;
-    }
-
-    @NonNull private final JavaContext mContext;
-    @NonNull private final Operation mOperation;
-    
-    @Nullable
-    public Result search(@NonNull UElement node) {
-        if (UastLiteralUtils.isNullLiteral(node)) {
-            return null;
-        } else if (node instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) node;
-            if (expression.getThenExpression() != null) {
-                Result result = search(expression.getThenExpression());
-                if (result != null) {
-                    return result;
-                }
-            }
-            if (expression.getElseExpression() != null) {
-                Result result = search(expression.getElseExpression());
-                if (result != null) {
-                    return result;
-                }
-            }
-        } else if (UastExpressionUtils.isTypeCast(node)) {
-            UBinaryExpressionWithType cast = (UBinaryExpressionWithType) node;
-            UExpression operand = cast.getOperand();
-            return search(operand);
-        } else if (node instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parens = (UParenthesizedExpression) node;
-            UExpression expression = parens.getExpression();
-            if (expression != null) {
-                return search(expression);
-            }
-        } else if (UastExpressionUtils.isConstructorCall(node) && mOperation == Operation.ACTION) {
-            // Identifies "new Intent(argument)" calls and, if found, continues
-            // resolving the argument instead looking for the action definition
-            UCallExpression call = (UCallExpression) node;
-            UReferenceExpression classReference = call.getClassReference();
-            String type = classReference != null ? UastUtils.getQualifiedName(classReference) : null;
-            if (CLASS_INTENT.equals(type)) {
-                List<UExpression> expressions = call.getValueArguments();
-                if (!expressions.isEmpty()) {
-                    UExpression action = expressions.get(0);
-                    if (action != null) {
-                        return search(action);
-                    }
-                }
-            }
-            return null;
-        } else if (node instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) node).resolve();
-            if (resolved instanceof PsiField) {
-                UField field = (UField) mContext.getUastContext().convertElementWithParent(resolved, UField.class);
-                if (field == null) {
-                    return null;
-                }
-                if (mOperation == Operation.ACTION) {
-                    UAnnotation annotation = field.findAnnotation(PERMISSION_ANNOTATION);
-                    if (annotation != null) {
-                        return getPermissionRequirement(field, annotation);
-                    }
-                } else if (mOperation == Operation.READ || mOperation == Operation.WRITE) {
-                    String fqn = mOperation == Operation.READ
-                            ? PERMISSION_ANNOTATION_READ : PERMISSION_ANNOTATION_WRITE;
-                    UAnnotation annotation = field.findAnnotation(fqn);
-                    if (annotation != null) {
-                        List<UNamedExpression> attributes = annotation.getAttributeValues();
-                        UNamedExpression o = attributes.size() == 1 ? attributes.get(0) : null;
-                        if (o != null && o.getExpression() instanceof UAnnotation) {
-                            annotation = (UAnnotation) o.getExpression();
-                            if (PERMISSION_ANNOTATION.equals(annotation.getQualifiedName())) {
-                                return getPermissionRequirement(field, annotation);
-                            }
-                        } else {
-                            // The complex annotations used for read/write cannot be
-                            // expressed in the external annotations format, so they're inlined.
-                            // (See Extractor.AnnotationData#write).
-                            //
-                            // Instead we've inlined the fields of the annotation on the
-                            // outer one:
-                            return getPermissionRequirement(field, annotation);
-                        }
-                    }
-                } else {
-                    assert false : mOperation;
-                }
-            }
-            
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                UExpression lastAssignment =
-                        UastLintUtils.findLastAssignment(variable, node, mContext);
-
-                if (lastAssignment != null) {
-                    return search(lastAssignment);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @NonNull
-    private Result getPermissionRequirement(
-            @NonNull PsiField field,
-            @NonNull UAnnotation annotation) {
-        PermissionRequirement requirement = PermissionRequirement.create(annotation);
-        PsiClass containingClass = field.getContainingClass();
-        String name = containingClass != null
-                ? containingClass.getName() + "." + field.getName()
-                : field.getName();
-        assert name != null;
-        return new Result(mOperation, requirement, name);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionHolder.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionHolder.java
deleted file mode 100644
index 32ff92d..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionHolder.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.sdklib.AndroidVersion;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * A {@linkplain PermissionHolder} knows which permissions are held/granted and can look up
- * individual permissions and respond to queries about whether they are held or not.
- */
-public interface PermissionHolder {
-
-    /** Returns true if the permission holder has been granted the given permission */
-    boolean hasPermission(@NonNull String permission);
-
-    /** Returns true if the given permission is known to be revocable for targetSdkVersion &ge; M */
-    boolean isRevocable(@NonNull String permission);
-
-    @NonNull
-    AndroidVersion getMinSdkVersion();
-
-    @NonNull
-    AndroidVersion getTargetSdkVersion();
-
-    /**
-     * A convenience implementation of {@link PermissionHolder} backed by a set
-     */
-    class SetPermissionLookup implements PermissionHolder {
-        private final Set<String> mGrantedPermissions;
-        private final Set<String> mRevocablePermissions;
-        private final AndroidVersion mMinSdkVersion;
-        private final AndroidVersion mTargetSdkVersion;
-
-        public SetPermissionLookup(
-                @NonNull Set<String> grantedPermissions,
-                @NonNull Set<String> revocablePermissions,
-                @NonNull AndroidVersion minSdkVersion,
-                @NonNull AndroidVersion targetSdkVersion) {
-            mGrantedPermissions = grantedPermissions;
-            mRevocablePermissions = revocablePermissions;
-            mMinSdkVersion = minSdkVersion;
-            mTargetSdkVersion = targetSdkVersion;
-        }
-
-        @VisibleForTesting
-        public SetPermissionLookup(@NonNull Set<String> grantedPermissions,
-                @NonNull Set<String> revocablePermissions) {
-            this(grantedPermissions, revocablePermissions, AndroidVersion.DEFAULT,
-                    AndroidVersion.DEFAULT);
-        }
-
-        @VisibleForTesting
-        public SetPermissionLookup(@NonNull Set<String> grantedPermissions) {
-            this(grantedPermissions, Collections.<String>emptySet());
-        }
-
-        @Override
-        public boolean hasPermission(@NonNull String permission) {
-            return mGrantedPermissions.contains(permission);
-        }
-
-        @Override
-        public boolean isRevocable(@NonNull String permission) {
-            return mRevocablePermissions.contains(permission);
-        }
-
-        @NonNull
-        @Override
-        public AndroidVersion getMinSdkVersion() {
-            return mMinSdkVersion;
-        }
-
-        @NonNull
-        @Override
-        public AndroidVersion getTargetSdkVersion() {
-            return mTargetSdkVersion;
-        }
-
-        /**
-         * Creates a {@linkplain PermissionHolder} which combines the permissions
-         * held by the given holder, with the permissions implied by the given
-         * {@link PermissionRequirement}
-         */
-        @NonNull
-        public static PermissionHolder join(@NonNull PermissionHolder lookup,
-                                            @NonNull PermissionRequirement requirement) {
-            SetPermissionLookup empty = new SetPermissionLookup(Collections.<String>emptySet(),
-                    Collections.<String>emptySet(), lookup.getMinSdkVersion(),
-                    lookup.getTargetSdkVersion());
-            return join(lookup, requirement.getMissingPermissions(empty));
-        }
-
-        /**
-         * Creates a {@linkplain PermissionHolder} which combines the permissions
-         * held by the given holder, along with a set of additional permission names
-         */
-        @NonNull
-        public static PermissionHolder join(@NonNull final PermissionHolder lookup,
-                @Nullable final Set<String> permissions) {
-            if (permissions != null && !permissions.isEmpty()) {
-                return new PermissionHolder() {
-                    @Override
-                    public boolean hasPermission(@NonNull String permission) {
-                        return lookup.hasPermission(permission)
-                                || permissions.contains(permission);
-                    }
-
-                    @Override
-                    public boolean isRevocable(@NonNull String permission) {
-                        return lookup.isRevocable(permission);
-                    }
-
-                    @NonNull
-                    @Override
-                    public AndroidVersion getMinSdkVersion() {
-                        return lookup.getMinSdkVersion();
-                    }
-
-                    @NonNull
-                    @Override
-                    public AndroidVersion getTargetSdkVersion() {
-                        return lookup.getTargetSdkVersion();
-                    }
-                };
-            }
-            return lookup;
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java
deleted file mode 100644
index ef5ba74..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.sdklib.AndroidVersion;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.tree.IElementType;
-import org.jetbrains.uast.UAnnotation;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import static com.android.SdkConstants.ATTR_VALUE;
-import static com.android.tools.klint.checks.SupportAnnotationDetector.*;
-
-/**
- * A permission requirement is a boolean expression of permission names that a
- * caller must satisfy for a given Android API.
- */
-public abstract class PermissionRequirement {
-    public static final String ATTR_PROTECTION_LEVEL = "protectionLevel"; //$NON-NLS-1$
-    public static final String VALUE_DANGEROUS = "dangerous"; //$NON-NLS-1$
-
-    protected final UAnnotation annotation;
-    private int firstApi;
-    private int lastApi;
-
-    @SuppressWarnings("ConstantConditions")
-    public static final PermissionRequirement NONE = new PermissionRequirement(null) {
-        @Override
-        public boolean isSatisfied(@NonNull PermissionHolder available) {
-            return true;
-        }
-
-        @Override
-        public boolean appliesTo(@NonNull PermissionHolder available) {
-            return false;
-        }
-
-        @Override
-        public boolean isConditional() {
-            return false;
-        }
-
-        @Override
-        public boolean isRevocable(@NonNull PermissionHolder revocable) {
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "None";
-        }
-
-        @Override
-        protected void addMissingPermissions(@NonNull PermissionHolder available,
-          @NonNull Set<String> result) {
-        }
-
-        @Override
-        protected void addRevocablePermissions(@NonNull Set<String> result,
-                @NonNull PermissionHolder revocable) {
-        }
-
-        @Nullable
-        @Override
-        public IElementType getOperator() {
-            return null;
-        }
-
-        @NonNull
-        @Override
-        public Iterable<PermissionRequirement> getChildren() {
-            return Collections.emptyList();
-        }
-    };
-
-    private PermissionRequirement(@NonNull UAnnotation annotation) {
-        this.annotation = annotation;
-    }
-
-    @NonNull
-    public static PermissionRequirement create(@NonNull UAnnotation annotation) {
-        String value = getAnnotationStringValue(annotation, ATTR_VALUE);
-        if (value != null && !value.isEmpty()) {
-            return new Single(annotation, value);
-        }
-
-        String[] anyOf = getAnnotationStringValues(annotation, ATTR_ANY_OF);
-        if (anyOf != null) {
-            if (anyOf.length > 1) {
-                return new Many(annotation, JavaTokenType.OROR, anyOf);
-            } else if (anyOf.length == 1) {
-                return new Single(annotation, anyOf[0]);
-            }
-        }
-
-        String[] allOf = getAnnotationStringValues(annotation, ATTR_ALL_OF);
-        if (allOf != null) {
-            if (allOf.length > 1) {
-                return new Many(annotation, JavaTokenType.ANDAND, allOf);
-            } else if (allOf.length == 1) {
-                return new Single(annotation, allOf[0]);
-            }
-        }
-
-        return NONE;
-    }
-
-    @Nullable
-    public static Boolean getAnnotationBooleanValue(@Nullable UAnnotation annotation,
-            @NonNull String name) {
-        if (annotation != null) {
-            UExpression attributeValue = annotation.findDeclaredAttributeValue(name);
-            if (attributeValue == null && ATTR_VALUE.equals(name)) {
-                attributeValue = annotation.findDeclaredAttributeValue(null);
-            }
-            // Use constant evaluator since we want to resolve field references as well
-            if (attributeValue != null) {
-                Object o = ConstantEvaluator.evaluate(null, attributeValue);
-                if (o instanceof Boolean) {
-                    return (Boolean) o;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static Long getAnnotationLongValue(@Nullable UAnnotation annotation,
-            @NonNull String name) {
-        if (annotation != null) {
-            UExpression attributeValue = annotation.findDeclaredAttributeValue(name);
-            if (attributeValue == null && ATTR_VALUE.equals(name)) {
-                attributeValue = annotation.findDeclaredAttributeValue(null);
-            }
-            // Use constant evaluator since we want to resolve field references as well
-            if (attributeValue != null) {
-                Object o = ConstantEvaluator.evaluate(null, attributeValue);
-                if (o instanceof Number) {
-                    return ((Number)o).longValue();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static Double getAnnotationDoubleValue(@Nullable UAnnotation annotation,
-            @NonNull String name) {
-        if (annotation != null) {
-            UExpression attributeValue = annotation.findDeclaredAttributeValue(name);
-            if (attributeValue == null && ATTR_VALUE.equals(name)) {
-                attributeValue = annotation.findDeclaredAttributeValue(null);
-            }
-            // Use constant evaluator since we want to resolve field references as well
-            if (attributeValue != null) {
-                Object o = ConstantEvaluator.evaluate(null, attributeValue);
-                if (o instanceof Number) {
-                    return ((Number)o).doubleValue();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static String getAnnotationStringValue(@Nullable UAnnotation annotation,
-            @NonNull String name) {
-        if (annotation != null) {
-            UExpression attributeValue = annotation.findDeclaredAttributeValue(name);
-            if (attributeValue == null && ATTR_VALUE.equals(name)) {
-                attributeValue = annotation.findDeclaredAttributeValue(null);
-            }
-            // Use constant evaluator since we want to resolve field references as well
-            if (attributeValue != null) {
-                Object o = ConstantEvaluator.evaluate(null, attributeValue);
-                if (o instanceof String) {
-                    return (String) o;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    public static String[] getAnnotationStringValues(@Nullable UAnnotation annotation,
-            @NonNull String name) {
-        if (annotation != null) {
-            UExpression attributeValue = annotation.findDeclaredAttributeValue(name);
-            if (attributeValue == null && ATTR_VALUE.equals(name)) {
-                attributeValue = annotation.findDeclaredAttributeValue(null);
-            }
-            if (attributeValue == null) {
-                return null;
-            }
-            if (UastExpressionUtils.isArrayInitializer(attributeValue)) {
-                List<UExpression> initializers =
-                        ((UCallExpression) attributeValue).getValueArguments();
-                List<String> result = Lists.newArrayListWithCapacity(initializers.size());
-                ConstantEvaluator constantEvaluator = new ConstantEvaluator(null);
-                for (UExpression element : initializers) {
-                    Object o = constantEvaluator.evaluate(element);
-                    if (o instanceof String) {
-                        result.add((String)o);
-                    }
-                }
-                if (result.isEmpty()) {
-                    return null;
-                } else {
-                    return result.toArray(new String[0]);
-                }
-            } else {
-                // Use constant evaluator since we want to resolve field references as well
-                Object o = ConstantEvaluator.evaluate(null, attributeValue);
-                if (o instanceof String) {
-                    return new String[]{(String) o};
-                } else if (o instanceof String[]) {
-                    return (String[])o;
-                } else if (o instanceof Object[]) {
-                    Object[] array = (Object[]) o;
-                    List<String> strings = Lists.newArrayListWithCapacity(array.length);
-                    for (Object element : array) {
-                        if (element instanceof String) {
-                            strings.add((String) element);
-                        }
-                    }
-                    return strings.toArray(new String[0]);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns false if this permission does not apply given the specified minimum and
-     * target sdk versions
-     *
-     * @param minSdkVersion the minimum SDK version
-     * @param targetSdkVersion the target SDK version
-     * @return true if this permission requirement applies for the given versions
-     */
-    /**
-     * Returns false if this permission does not apply given the specified minimum and target
-     * sdk versions
-     *
-     * @param available   the permission holder which also knows the min and target versions
-     * @return true if this permission requirement applies for the given versions
-     */
-    protected boolean appliesTo(@NonNull PermissionHolder available) {
-        if (firstApi == 0) { // initialized?
-            firstApi = -1; // initialized, not specified
-
-            // Not initialized
-            String range = getAnnotationStringValue(annotation, "apis");
-            if (range != null) {
-                // Currently only support the syntax "a..b" where a and b are inclusive end points
-                // and where "a" and "b" are optional
-                int index = range.indexOf("..");
-                if (index != -1) {
-                    try {
-                        if (index > 0) {
-                            firstApi = Integer.parseInt(range.substring(0, index));
-                        } else {
-                            firstApi = 1;
-                        }
-                        if (index + 2 < range.length()) {
-                            lastApi = Integer.parseInt(range.substring(index + 2));
-                        } else {
-                            lastApi = Integer.MAX_VALUE;
-                        }
-                    } catch (NumberFormatException ignore) {
-                    }
-                }
-            }
-        }
-
-        if (firstApi != -1) {
-            AndroidVersion minSdkVersion = available.getMinSdkVersion();
-            if (minSdkVersion.getFeatureLevel() > lastApi) {
-                return false;
-            }
-
-            AndroidVersion targetSdkVersion = available.getTargetSdkVersion();
-            if (targetSdkVersion.getFeatureLevel() < firstApi) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns whether this requirement is conditional, meaning that there are
-     * some circumstances in which the requirement is not necessary. For
-     * example, consider
-     * {@code android.app.backup.BackupManager.dataChanged(java.lang.String)} .
-     * Here the {@code android.permission.BACKUP} is required but only if the
-     * argument is not your own package.
-     * <p>
-     * This is used to handle permissions differently between the "missing" and
-     * "unused" checks. When checking for missing permissions, we err on the
-     * side of caution: if you are missing a permission, but the permission is
-     * conditional, you may not need it so we may not want to complain. However,
-     * when looking for unused permissions, we don't want to flag the
-     * conditional permissions as unused since they may be required.
-     *
-     * @return true if this requirement is conditional
-     */
-    public boolean isConditional() {
-        Boolean o = getAnnotationBooleanValue(annotation, ATTR_CONDITIONAL);
-        if (o != null) {
-            return o;
-        }
-        return false;
-    }
-
-    /**
-     * Returns whether this requirement is for a single permission (rather than
-     * a boolean expression such as one permission or another.)
-     *
-     * @return true if this requirement is just a simple permission name
-     */
-    public boolean isSingle() {
-        return true;
-    }
-
-    /**
-     * Whether the permission requirement is satisfied given the set of granted permissions
-     *
-     * @param available the available permissions
-     * @return true if all permissions specified by this requirement are available
-     */
-    public abstract boolean isSatisfied(@NonNull PermissionHolder available);
-
-    /** Describes the missing permissions (e.g. "P1, P2 and P3") */
-    public String describeMissingPermissions(@NonNull PermissionHolder available) {
-        return "";
-    }
-
-    /** Returns the missing permissions (e.g. {"P1", "P2", "P3"} */
-    public Set<String> getMissingPermissions(@NonNull PermissionHolder available) {
-        Set<String> result = Sets.newHashSet();
-        addMissingPermissions(available, result);
-        return result;
-    }
-
-    protected abstract void addMissingPermissions(@NonNull PermissionHolder available,
-        @NonNull Set<String> result);
-
-    /** Returns the permissions in the requirement that are revocable */
-    public Set<String> getRevocablePermissions(@NonNull PermissionHolder revocable) {
-        Set<String> result = Sets.newHashSet();
-        addRevocablePermissions(result, revocable);
-        return result;
-    }
-
-    protected abstract void addRevocablePermissions(@NonNull Set<String> result,
-            @NonNull PermissionHolder revocable);
-
-    /**
-     * Returns whether this permission is revocable
-     *
-     * @param revocable the set of revocable permissions
-     * @return true if a user can revoke the permission
-     */
-    public abstract boolean isRevocable(@NonNull PermissionHolder revocable);
-
-    /**
-     * For permission requirements that combine children, the operator to combine them with; null
-     * for leaf nodes
-     */
-    @Nullable
-    public abstract IElementType getOperator();
-
-    /**
-     * Returns nested requirements, combined via {@link #getOperator()}
-     */
-    @NonNull
-    public abstract Iterable<PermissionRequirement> getChildren();
-
-    /** Require a single permission */
-    private static class Single extends PermissionRequirement {
-        public final String name;
-
-        public Single(@NonNull UAnnotation annotation, @NonNull String name) {
-            super(annotation);
-            this.name = name;
-        }
-
-        @Override
-        public boolean isRevocable(@NonNull PermissionHolder revocable) {
-            return revocable.isRevocable(name) || isRevocableSystemPermission(name);
-        }
-
-        @Nullable
-        @Override
-        public IElementType getOperator() {
-            return null;
-        }
-
-        @NonNull
-        @Override
-        public Iterable<PermissionRequirement> getChildren() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public boolean isSingle() {
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            return name;
-        }
-
-        @Override
-        public boolean isSatisfied(@NonNull PermissionHolder available) {
-            return available.hasPermission(name) || !appliesTo(available);
-        }
-
-        @Override
-        public String describeMissingPermissions(@NonNull PermissionHolder available) {
-            return isSatisfied(available) ? "" : name;
-        }
-
-        @Override
-        protected void addMissingPermissions(@NonNull PermissionHolder available,
-            @NonNull Set<String> missing) {
-            if (!isSatisfied(available)) {
-                missing.add(name);
-            }
-        }
-
-        @Override
-        protected void addRevocablePermissions(@NonNull Set<String> result,
-                @NonNull PermissionHolder revocable) {
-            if (isRevocable(revocable)) {
-                result.add(name);
-            }
-        }
-    }
-
-    protected static void appendOperator(StringBuilder sb, IElementType operator) {
-        sb.append(' ');
-        if (operator == JavaTokenType.ANDAND) {
-            sb.append("and");
-        } else if (operator == JavaTokenType.OROR) {
-            sb.append("or");
-        } else {
-            assert operator == JavaTokenType.XOR : operator;
-            sb.append("xor");
-        }
-        sb.append(' ');
-    }
-
-    /**
-     * Require a series of permissions, all with the same operator.
-     */
-    private static class Many extends PermissionRequirement {
-        public final IElementType operator;
-        public final List<PermissionRequirement> permissions;
-
-        public Many(
-                @NonNull UAnnotation annotation,
-                IElementType operator,
-                String[] names) {
-            super(annotation);
-            assert operator == JavaTokenType.OROR
-                    || operator == JavaTokenType.ANDAND : operator;
-            assert names.length >= 2;
-            this.operator = operator;
-            this.permissions = Lists.newArrayListWithExpectedSize(names.length);
-            for (String name : names) {
-                permissions.add(new Single(annotation, name));
-            }
-        }
-
-        @Override
-        public boolean isSingle() {
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-
-            sb.append(permissions.get(0));
-
-            for (int i = 1; i < permissions.size(); i++) {
-                appendOperator(sb, operator);
-                sb.append(permissions.get(i));
-            }
-
-            return sb.toString();
-        }
-
-        @Override
-        public boolean isSatisfied(@NonNull PermissionHolder available) {
-            if (operator == JavaTokenType.ANDAND) {
-                for (PermissionRequirement requirement : permissions) {
-                    if (!requirement.isSatisfied(available) && requirement.appliesTo(available)) {
-                        return false;
-                    }
-                }
-                return true;
-            } else {
-                assert operator == JavaTokenType.OROR : operator;
-                for (PermissionRequirement requirement : permissions) {
-                    if (requirement.isSatisfied(available) || !requirement.appliesTo(available)) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-
-        @Override
-        public String describeMissingPermissions(@NonNull PermissionHolder available) {
-            StringBuilder sb = new StringBuilder();
-            boolean first = true;
-            for (PermissionRequirement requirement : permissions) {
-                if (!requirement.isSatisfied(available)) {
-                    if (first) {
-                        first = false;
-                    } else {
-                        appendOperator(sb, operator);
-                    }
-                    sb.append(requirement.describeMissingPermissions(available));
-                }
-            }
-            return sb.toString();
-        }
-
-        @Override
-        protected void addMissingPermissions(@NonNull PermissionHolder available,
-          @NonNull Set<String> missing) {
-            for (PermissionRequirement requirement : permissions) {
-                if (!requirement.isSatisfied(available)) {
-                    requirement.addMissingPermissions(available, missing);
-                }
-            }
-        }
-
-        @Override
-        protected void addRevocablePermissions(@NonNull Set<String> result,
-                @NonNull PermissionHolder revocable) {
-            for (PermissionRequirement requirement : permissions) {
-                requirement.addRevocablePermissions(result, revocable);
-            }
-        }
-
-        @Override
-        public boolean isRevocable(@NonNull PermissionHolder revocable) {
-            // TODO: Pass in the available set of permissions here, and if
-            // the operator is JavaTokenType.OROR, only return revocable=true
-            // if an unsatisfied permission is also revocable. In other words,
-            // if multiple permissions are allowed, and some of them are satisfied and
-            // not revocable the overall permission requirement is not revocable.
-            for (PermissionRequirement requirement : permissions) {
-                if (requirement.isRevocable(revocable)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Nullable
-        @Override
-        public IElementType getOperator() {
-            return operator;
-        }
-
-        @NonNull
-        @Override
-        public Iterable<PermissionRequirement> getChildren() {
-            return permissions;
-        }
-    }
-
-    /**
-     * Returns true if the given permission name is a revocable permission for
-     * targetSdkVersion &ge; 23
-     *
-     * @param name permission name
-     * @return true if this is a revocable permission
-     */
-    public static boolean isRevocableSystemPermission(@NonNull String name) {
-        return Arrays.binarySearch(REVOCABLE_PERMISSION_NAMES, name) >= 0;
-    }
-
-    @VisibleForTesting
-    static final String[] REVOCABLE_PERMISSION_NAMES = new String[] {
-            "android.permission.ACCESS_COARSE_LOCATION",
-            "android.permission.ACCESS_FINE_LOCATION",
-            "android.permission.BODY_SENSORS",
-            "android.permission.CALL_PHONE",
-            "android.permission.CAMERA",
-            "android.permission.PROCESS_OUTGOING_CALLS",
-            "android.permission.READ_CALENDAR",
-            "android.permission.READ_CALL_LOG",
-            "android.permission.READ_CELL_BROADCASTS",
-            "android.permission.READ_CONTACTS",
-            "android.permission.READ_EXTERNAL_STORAGE",
-            "android.permission.READ_PHONE_STATE",
-            "android.permission.READ_PROFILE",
-            "android.permission.READ_SMS",
-            "android.permission.READ_SOCIAL_STREAM",
-            "android.permission.RECEIVE_MMS",
-            "android.permission.RECEIVE_SMS",
-            "android.permission.RECEIVE_WAP_PUSH",
-            "android.permission.RECORD_AUDIO",
-            "android.permission.SEND_SMS",
-            "android.permission.USE_FINGERPRINT",
-            "android.permission.USE_SIP",
-            "android.permission.WRITE_CALENDAR",
-            "android.permission.WRITE_CALL_LOG",
-            "android.permission.WRITE_CONTACTS",
-            "android.permission.WRITE_EXTERNAL_STORAGE",
-            "android.permission.WRITE_SETTINGS",
-            "android.permission.WRITE_PROFILE",
-            "android.permission.WRITE_SOCIAL_STREAM",
-            "com.android.voicemail.permission.ADD_VOICEMAIL",
-    };
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PluralsDatabase.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PluralsDatabase.java
deleted file mode 100644
index 8bea3e7..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PluralsDatabase.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import static com.android.tools.klint.checks.PluralsDatabase.Quantity.few;
-import static com.android.tools.klint.checks.PluralsDatabase.Quantity.many;
-import static com.android.tools.klint.checks.PluralsDatabase.Quantity.one;
-import static com.android.tools.klint.checks.PluralsDatabase.Quantity.two;
-import static com.android.tools.klint.checks.PluralsDatabase.Quantity.zero;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.google.common.collect.Maps;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Database used by the {@link PluralsDetector} to get information
- * about plural forms for a given language
- */
-public class PluralsDatabase {
-    private static final EnumSet<Quantity> NONE = EnumSet.noneOf(Quantity.class);
-
-    private static final PluralsDatabase sInstance = new PluralsDatabase();
-    private final Map<String, EnumSet<Quantity>> mPlurals = Maps.newHashMap();
-
-    /** Bit set if this language uses quantity zero */
-    @SuppressWarnings("PointlessBitwiseExpression")
-    static final int FLAG_ZERO  = 1 << 0;
-    /** Bit set if this language uses quantity one */
-    static final int FLAG_ONE   = 1 << 1;
-    /** Bit set if this language uses quantity two */
-    static final int FLAG_TWO   = 1 << 2;
-    /** Bit set if this language uses quantity few */
-    static final int FLAG_FEW   = 1 << 3;
-    /** Bit set if this language uses quantity many */
-    static final int FLAG_MANY  = 1 << 4;
-    /** Bit set if this language has multiple values that match quantity zero */
-    static final int FLAG_MULTIPLE_ZERO = 1 << 5;
-    /** Bit set if this language has multiple values that match quantity one */
-    static final int FLAG_MULTIPLE_ONE  = 1 << 6;
-    /** Bit set if this language has multiple values that match quantity two */
-    static final int FLAG_MULTIPLE_TWO  = 1 << 7;
-
-    @NonNull
-    public static PluralsDatabase get() {
-        return sInstance;
-    }
-
-    private static int getFlags(@NonNull String language) {
-        int index = getLanguageIndex(language);
-        if (index != -1) {
-            return FLAGS[index];
-        }
-        return 0;
-    }
-
-    private static int getLanguageIndex(@NonNull String language) {
-        int index = Arrays.binarySearch(LANGUAGE_CODES, language);
-        if (index >= 0) {
-            assert LANGUAGE_CODES[index].equals(language);
-            return index;
-        } else {
-            return -1;
-        }
-    }
-
-    @Nullable
-    public EnumSet<Quantity> getRelevant(@NonNull String language) {
-        EnumSet<Quantity> set = mPlurals.get(language);
-        if (set == null) {
-            int index = getLanguageIndex(language);
-            if (index == -1) {
-                mPlurals.put(language, NONE);
-                return null;
-            }
-
-            // Process each item and look for relevance
-            int flag = FLAGS[index];
-
-            set = EnumSet.noneOf(Quantity.class);
-            if ((flag & FLAG_ZERO) != 0) {
-                set.add(zero);
-            }
-            if ((flag & FLAG_ONE) != 0) {
-                set.add(one);
-            }
-            if ((flag & FLAG_TWO) != 0) {
-                set.add(two);
-            }
-            if ((flag & FLAG_FEW) != 0) {
-                set.add(few);
-            }
-            if ((flag & FLAG_MANY) != 0) {
-                set.add(many);
-            }
-
-            mPlurals.put(language, set);
-        }
-        return set == NONE ? null : set;
-    }
-
-    @SuppressWarnings("MethodMayBeStatic")
-    public boolean hasMultipleValuesForQuantity(
-            @NonNull String language,
-            @NonNull Quantity quantity) {
-        if (quantity == one) {
-            return (getFlags(language) & FLAG_MULTIPLE_ONE) != 0;
-        } else if (quantity == two) {
-            return (getFlags(language) & FLAG_MULTIPLE_TWO) != 0;
-        } else {
-            return quantity == zero && (getFlags(language) & FLAG_MULTIPLE_ZERO) != 0;
-        }
-    }
-
-    @SuppressWarnings("MethodMayBeStatic")
-    @Nullable
-    public String findIntegerExamples(@NonNull String language, @NonNull Quantity quantity) {
-        if (quantity == one) {
-            return getExampleForQuantityOne(language);
-        } else if (quantity == two) {
-            return getExampleForQuantityTwo(language);
-        } else if (quantity == zero) {
-            return getExampleForQuantityZero(language);
-        } else {
-            return null;
-        }
-    }
-
-    public enum Quantity {
-        // deliberately lower case to match attribute names
-        few, many, one, two, zero, other;
-
-        @Nullable
-        public static Quantity get(@NonNull String name) {
-            for (Quantity quantity : values()) {
-                if (name.equals(quantity.name())) {
-                    return quantity;
-                }
-            }
-
-            return null;
-        }
-
-        public static String formatSet(@NonNull EnumSet<Quantity> set) {
-            List<String> list = new ArrayList<String>(set.size());
-            for (Quantity quantity : set) {
-                list.add('`' + quantity.name() + '`');
-            }
-            return LintUtils.formatList(list, Integer.MAX_VALUE);
-        }
-    }
-
-    // GENERATED DATA.
-    // This data is generated by the #testDatabaseAccurate method in PluralsDatabaseTest
-    // which will generate the following if it can find an ICU plurals database file
-    // in the unit test data folder.
-
-    /** Set of language codes relevant to plurals data */
-    private static final String[] LANGUAGE_CODES = new String[] {
-            "af", "ak", "am", "ar", "as", "az", "be", "bg", "bh", "bm",
-            "bn", "bo", "br", "bs", "ca", "ce", "cs", "cy", "da", "de",
-            "dv", "dz", "ee", "el", "en", "eo", "es", "et", "eu", "fa",
-            "ff", "fi", "fo", "fr", "fy", "ga", "gd", "gl", "gu", "gv",
-            "ha", "he", "hi", "hr", "hu", "hy", "id", "ig", "ii", "in",
-            "is", "it", "iu", "iw", "ja", "ji", "jv", "ka", "kk", "kl",
-            "km", "kn", "ko", "ks", "ku", "kw", "ky", "lb", "lg", "ln",
-            "lo", "lt", "lv", "mg", "mk", "ml", "mn", "mr", "ms", "mt",
-            "my", "nb", "nd", "ne", "nl", "nn", "no", "nr", "ny", "om",
-            "or", "os", "pa", "pl", "ps", "pt", "rm", "ro", "ru", "se",
-            "sg", "si", "sk", "sl", "sn", "so", "sq", "sr", "ss", "st",
-            "sv", "sw", "ta", "te", "th", "ti", "tk", "tl", "tn", "to",
-            "tr", "ts", "ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa",
-            "wo", "xh", "yi", "yo", "zh", "zu"
-    };
-
-    /**
-     * Relevant flags for each language (corresponding to each language listed
-     * in the same position in {@link #LANGUAGE_CODES})
-     */
-    private static final int[] FLAGS = new int[] {
-            0x0002, 0x0042, 0x0042, 0x001f, 0x0042, 0x0002, 0x005a, 0x0002,
-            0x0042, 0x0000, 0x0042, 0x0000, 0x00de, 0x004a, 0x0002, 0x0002,
-            0x000a, 0x001f, 0x0002, 0x0002, 0x0002, 0x0000, 0x0002, 0x0002,
-            0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0042, 0x0042, 0x0002,
-            0x0002, 0x0042, 0x0002, 0x001e, 0x00ce, 0x0002, 0x0042, 0x00ce,
-            0x0002, 0x0016, 0x0042, 0x004a, 0x0002, 0x0042, 0x0000, 0x0000,
-            0x0000, 0x0000, 0x0042, 0x0002, 0x0006, 0x0016, 0x0000, 0x0002,
-            0x0000, 0x0002, 0x0002, 0x0002, 0x0000, 0x0042, 0x0000, 0x0002,
-            0x0002, 0x0006, 0x0002, 0x0002, 0x0002, 0x0042, 0x0000, 0x004a,
-            0x0063, 0x0042, 0x0042, 0x0002, 0x0002, 0x0042, 0x0000, 0x001a,
-            0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-            0x0002, 0x0002, 0x0002, 0x0002, 0x0042, 0x001a, 0x0002, 0x0042,
-            0x0002, 0x000a, 0x005a, 0x0006, 0x0000, 0x0042, 0x000a, 0x00ce,
-            0x0002, 0x0002, 0x0002, 0x004a, 0x0002, 0x0002, 0x0002, 0x0002,
-            0x0002, 0x0002, 0x0000, 0x0042, 0x0002, 0x0042, 0x0002, 0x0000,
-            0x0002, 0x0002, 0x0002, 0x005a, 0x0002, 0x0002, 0x0002, 0x0000,
-            0x0002, 0x0042, 0x0000, 0x0002, 0x0002, 0x0000, 0x0000, 0x0042
-    };
-
-    @Nullable
-    private static String getExampleForQuantityZero(@NonNull String language) {
-        int index = getLanguageIndex(language);
-        switch (index) {
-            // set14
-            case 72: // lv
-                return "0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, \u2026";
-            case -1:
-            default:
-                return null;
-        }
-    }
-
-    @Nullable
-    private static String getExampleForQuantityOne(@NonNull String language) {
-        int index = getLanguageIndex(language);
-        switch (index) {
-            // set1
-            case 2: // am
-            case 4: // as
-            case 10: // bn
-            case 29: // fa
-            case 38: // gu
-            case 42: // hi
-            case 61: // kn
-            case 77: // mr
-            case 135: // zu
-                return "0, 1";
-            // set11
-            case 50: // is
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set12
-            case 74: // mk
-                return "1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, \u2026";
-            // set13
-            case 117: // tl
-                return "0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, \u2026";
-            // set14
-            case 72: // lv
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set2
-            case 30: // ff
-            case 33: // fr
-            case 45: // hy
-                return "0, 1";
-            // set20
-            case 13: // bs
-            case 43: // hr
-            case 107: // sr
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set21
-            case 36: // gd
-                return "1, 11";
-            // set22
-            case 103: // sl
-                return "1, 101, 201, 301, 401, 501, 601, 701, 1001, \u2026";
-            // set27
-            case 6: // be
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set28
-            case 71: // lt
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set30
-            case 98: // ru
-            case 123: // uk
-                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
-            // set31
-            case 12: // br
-                return "1, 21, 31, 41, 51, 61, 81, 101, 1001, \u2026";
-            // set33
-            case 39: // gv
-                return "1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, \u2026";
-            // set4
-            case 101: // si
-                return "0, 1";
-            // set5
-            case 1: // ak
-            case 8: // bh
-            case 69: // ln
-            case 73: // mg
-            case 92: // pa
-            case 115: // ti
-            case 129: // wa
-                return "0, 1";
-            // set7
-            case 95: // pt
-                return "0, 1";
-            case -1:
-            default:
-                return null;
-        }
-    }
-
-    @Nullable
-    private static String getExampleForQuantityTwo(@NonNull String language) {
-        int index = getLanguageIndex(language);
-        switch (index) {
-            // set21
-            case 36: // gd
-                return "2, 12";
-            // set22
-            case 103: // sl
-                return "2, 102, 202, 302, 402, 502, 602, 702, 1002, \u2026";
-            // set31
-            case 12: // br
-                return "2, 22, 32, 42, 52, 62, 82, 102, 1002, \u2026";
-            // set33
-            case 39: // gv
-                return "2, 12, 22, 32, 42, 52, 62, 72, 102, 1002, \u2026";
-            case -1:
-            default:
-                return null;
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PreferenceActivityDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PreferenceActivityDetector.java
deleted file mode 100644
index 70e7d74..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PreferenceActivityDetector.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_PACKAGE;
-import static com.android.SdkConstants.TAG_ACTIVITY;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UClass;
-import org.w3c.dom.Element;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Ensures that PreferenceActivity and its subclasses are never exported.
- */
-public class PreferenceActivityDetector extends Detector
-        implements XmlScanner, Detector.UastScanner {
-    public static final Issue ISSUE = Issue.create(
-            "ExportedPreferenceActivity", //$NON-NLS-1$
-            "PreferenceActivity should not be exported",
-            "Fragment injection gives anyone who can send your PreferenceActivity an intent the "
-                    + "ability to load any fragment, with any arguments, in your process.",
-            Category.SECURITY,
-            8,
-            Severity.WARNING,
-            new Implementation(
-                    PreferenceActivityDetector.class,
-                    EnumSet.of(Scope.MANIFEST, Scope.JAVA_FILE)))
-            .addMoreInfo("http://securityintelligence.com/"
-                    + "new-vulnerability-android-framework-fragment-injection");
-    private static final String PREFERENCE_ACTIVITY = "android.preference.PreferenceActivity"; //$NON-NLS-1$
-    private static final String IS_VALID_FRAGMENT = "isValidFragment"; //$NON-NLS-1$
-
-    private final Map<String, Location.Handle> mExportedActivities =
-            new HashMap<String, Location.Handle>();
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Collections.singletonList(TAG_ACTIVITY);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        if (SecurityDetector.getExported(element)) {
-            String fqcn = getFqcn(element);
-            if (fqcn != null) {
-                if (fqcn.equals(PREFERENCE_ACTIVITY) &&
-                        !context.getDriver().isSuppressed(context, ISSUE, element)) {
-                    String message = "`PreferenceActivity` should not be exported";
-                    context.report(ISSUE, element, context.getLocation(element), message);
-                }
-                mExportedActivities.put(fqcn, context.createLocationHandle(element));
-            }
-        }
-    }
-
-    private static String getFqcn(@NonNull Element activityElement) {
-        String activityClassName = activityElement.getAttributeNS(ANDROID_URI, ATTR_NAME);
-
-        if (activityClassName == null || activityClassName.isEmpty()) {
-            return null;
-        }
-
-        // If the activity class name starts with a '.', it is shorthand for prepending the
-        // package name specified in the manifest.
-        if (activityClassName.startsWith(".")) {
-            String pkg = activityElement.getOwnerDocument().getDocumentElement()
-                    .getAttribute(ATTR_PACKAGE);
-            if (pkg != null) {
-                return pkg + activityClassName;
-            } else {
-                return null;
-            }
-        }
-
-        return activityClassName;
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(PREFERENCE_ACTIVITY);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        if (!context.getProject().getReportIssues()) {
-            return;
-        }
-        JavaEvaluator evaluator = context.getEvaluator();
-        String className = declaration.getQualifiedName();
-        if (InheritanceUtil.isInheritor(declaration, false, PREFERENCE_ACTIVITY)
-                            && mExportedActivities.containsKey(className)) {
-            // Ignore the issue if we target an API greater than 19 and the class in
-            // question specifically overrides isValidFragment() and thus knowingly white-lists
-            // valid fragments.
-            if (context.getMainProject().getTargetSdk() >= 19
-                    && overridesIsValidFragment(evaluator, declaration)) {
-                return;
-            }
-
-            String message = String.format(
-                    "`PreferenceActivity` subclass `%1$s` should not be exported",
-                    className);
-            Location location = mExportedActivities.get(className).resolve();
-            context.reportUast(ISSUE, declaration, location, message);
-        }
-    }
-
-    private static boolean overridesIsValidFragment(
-            @NonNull JavaEvaluator evaluator,
-            @NonNull PsiClass resolvedClass) {
-        for (PsiMethod method : resolvedClass.findMethodsByName(IS_VALID_FRAGMENT, false)) {
-            if (evaluator.parametersMatch(method, TYPE_STRING)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PrivateResourceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PrivateResourceDetector.java
deleted file mode 100644
index cac223b..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PrivateResourceDetector.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_REF_PREFIX;
-import static com.android.SdkConstants.ATTR_TYPE;
-import static com.android.SdkConstants.FD_RES_VALUES;
-import static com.android.SdkConstants.RESOURCE_CLR_STYLEABLE;
-import static com.android.SdkConstants.RESOURCE_CLZ_ARRAY;
-import static com.android.SdkConstants.RESOURCE_CLZ_ID;
-import static com.android.SdkConstants.TAG_ARRAY;
-import static com.android.SdkConstants.TAG_INTEGER_ARRAY;
-import static com.android.SdkConstants.TAG_ITEM;
-import static com.android.SdkConstants.TAG_PLURALS;
-import static com.android.SdkConstants.TAG_RESOURCES;
-import static com.android.SdkConstants.TAG_STRING_ARRAY;
-import static com.android.SdkConstants.TAG_STYLE;
-import static com.android.SdkConstants.TOOLS_URI;
-import static com.android.SdkConstants.VALUE_TRUE;
-import static com.android.tools.klint.detector.api.LintUtils.getBaseName;
-import static com.android.utils.SdkUtils.getResourceFieldName;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.AndroidLibrary;
-import com.android.builder.model.MavenCoordinates;
-import com.android.ide.common.repository.ResourceVisibilityLookup;
-import com.android.resources.ResourceUrl;
-import com.android.resources.FolderTypeRelationship;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.ResourceXmlDetector;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Check which looks for access of private resources.
- */
-public class PrivateResourceDetector extends ResourceXmlDetector implements
-        Detector.UastScanner {
-    /** Attribute for overriding a resource */
-    private static final String ATTR_OVERRIDE = "override";
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            PrivateResourceDetector.class,
-            Scope.JAVA_AND_RESOURCE_FILES,
-            Scope.JAVA_FILE_SCOPE,
-            Scope.RESOURCE_FILE_SCOPE);
-
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "PrivateResource", //$NON-NLS-1$
-            "Using private resources",
-
-            "Private resources should not be referenced; the may not be present everywhere, and " +
-            "even where they are they may disappear without notice.\n" +
-            "\n" +
-            "To fix this, copy the resource into your own project instead.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Constructs a new detector */
-    public PrivateResourceDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public boolean appliesToResourceRefs() {
-        return true;
-    }
-
-    @Override
-    public void visitResourceReference(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UElement node, @NonNull ResourceType resourceType, @NonNull String name,
-            boolean isFramework) {
-        if (context.getProject().isGradleProject() && !isFramework) {
-            Project project = context.getProject();
-            if (project.getGradleProjectModel() != null && project.getCurrentVariant() != null) {
-                if (isPrivate(context, resourceType, name)) {
-                    String message = createUsageErrorMessage(context, resourceType, name);
-                    context.report(ISSUE, node, context.getUastLocation(node), message);
-                }
-            }
-        }
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        return ALL;
-    }
-
-    /** Check resource references: accessing a private resource from an upstream library? */
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        String value = attribute.getNodeValue();
-        if (context.getProject().isGradleProject()) {
-            ResourceUrl url = ResourceUrl.parse(value);
-            if (isPrivate(context, url)) {
-                String message = createUsageErrorMessage(context, url.type, url.name);
-                context.report(ISSUE, attribute, context.getValueLocation(attribute), message);
-            }
-        }
-    }
-
-    /** Check resource definitions: overriding a private resource from an upstream library? */
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(
-                TAG_STYLE,
-                TAG_RESOURCES,
-                TAG_ARRAY,
-                TAG_STRING_ARRAY,
-                TAG_INTEGER_ARRAY,
-                TAG_PLURALS
-        );
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        if (TAG_RESOURCES.equals(element.getTagName())) {
-            for (Element item : LintUtils.getChildren(element)) {
-                Attr nameAttribute = item.getAttributeNode(ATTR_NAME);
-                if (nameAttribute != null) {
-                    String name = getResourceFieldName(nameAttribute.getValue());
-                    String type = item.getTagName();
-                    if (type.equals(TAG_ITEM)) {
-                        type = item.getAttribute(ATTR_TYPE);
-                        if (type == null || type.isEmpty()) {
-                            type = RESOURCE_CLZ_ID;
-                        }
-                    } else if (type.equals("declare-styleable")) {   //$NON-NLS-1$
-                        type = RESOURCE_CLR_STYLEABLE;
-                    } else if (type.contains("array")) {             //$NON-NLS-1$
-                        // <string-array> etc
-                        type = RESOURCE_CLZ_ARRAY;
-                    }
-                    ResourceType t = ResourceType.getEnum(type);
-                    if (t != null && isPrivate(context, t, name) &&
-                            !VALUE_TRUE.equals(item.getAttributeNS(TOOLS_URI, ATTR_OVERRIDE))) {
-                        String message = createOverrideErrorMessage(context, t, name);
-                        Location location = context.getValueLocation(nameAttribute);
-                        context.report(ISSUE, nameAttribute, location, message);
-                    }
-                }
-            }
-        } else {
-            assert TAG_STYLE.equals(element.getTagName())
-                    || TAG_ARRAY.equals(element.getTagName())
-                    || TAG_PLURALS.equals(element.getTagName())
-                    || TAG_INTEGER_ARRAY.equals(element.getTagName())
-                    || TAG_STRING_ARRAY.equals(element.getTagName());
-            for (Element item : LintUtils.getChildren(element)) {
-                checkChildRefs(context, item);
-            }
-        }
-    }
-
-    private static boolean isPrivate(Context context, ResourceType type, String name) {
-        if (type == ResourceType.ID) {
-            // No need to complain about "overriding" id's. There's no harm
-            // in doing so. (This avoids warning about cases like for example
-            // appcompat's (private) @id/title resource, which would otherwise
-            // flag any attempt to create a resource named title in the user's
-            // project.
-            return false;
-        }
-
-        if (context.getProject().isGradleProject()) {
-            ResourceVisibilityLookup lookup = context.getProject().getResourceVisibility();
-            return lookup.isPrivate(type, name);
-        }
-
-        return false;
-    }
-
-    private static boolean isPrivate(@NonNull Context context, @Nullable ResourceUrl url) {
-        return url != null && !url.framework && isPrivate(context, url.type, url.name);
-    }
-
-    private static void checkChildRefs(@NonNull XmlContext context, Element item) {
-        // Look for ?attr/ and @dimen/foo etc references in the item children
-        NodeList childNodes = item.getChildNodes();
-        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-            Node child = childNodes.item(i);
-            if (child.getNodeType() == Node.TEXT_NODE) {
-                String text = child.getNodeValue();
-
-                int index = text.indexOf(ATTR_REF_PREFIX);
-                if (index != -1) {
-                    String name = text.substring(index + ATTR_REF_PREFIX.length()).trim();
-                    if (isPrivate(context, ResourceType.ATTR, name)) {
-                        String message = createUsageErrorMessage(context, ResourceType.ATTR, name);
-                        context.report(ISSUE, item, context.getLocation(child), message);
-                    }
-                } else {
-                    for (int j = 0, m = text.length(); j < m; j++) {
-                        char c = text.charAt(j);
-                        if (c == '@') {
-                            ResourceUrl url = ResourceUrl.parse(text.trim());
-                            if (isPrivate(context, url)) {
-                                String message = createUsageErrorMessage(context, url.type,
-                                        url.name);
-                                context.report(ISSUE, item, context.getLocation(child), message);
-                            }
-                            break;
-                        } else if (!Character.isWhitespace(c)) {
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void beforeCheckFile(@NonNull Context context) {
-        File file = context.file;
-        boolean isXmlFile = LintUtils.isXmlFile(file);
-        if (!isXmlFile && !LintUtils.isBitmapFile(file)) {
-            return;
-        }
-        String parentName = file.getParentFile().getName();
-        int dash = parentName.indexOf('-');
-        if (dash != -1 || FD_RES_VALUES.equals(parentName)) {
-            return;
-        }
-        ResourceFolderType folderType = ResourceFolderType.getFolderType(parentName);
-        if (folderType == null) {
-            return;
-        }
-        List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(folderType);
-        if (types.isEmpty()) {
-            return;
-        }
-        ResourceType type = types.get(0);
-        String resourceName = getResourceFieldName(getBaseName(file.getName()));
-        if (isPrivate(context, type, resourceName)) {
-            String message = createOverrideErrorMessage(context, type, resourceName);
-            Location location = Location.create(file);
-            context.report(ISSUE, location, message);
-        }
-    }
-    
-    private static String createOverrideErrorMessage(@NonNull Context context,
-            @NonNull ResourceType type, @NonNull String name) {
-        String libraryName = getLibraryName(context, type, name);
-        return String.format("Overriding `@%1$s/%2$s` which is marked as private in %3$s. If "
-                        + "deliberate, use tools:override=\"true\", otherwise pick a "
-                        + "different name.", type, name, libraryName);
-    }
-
-    private static String createUsageErrorMessage(@NonNull Context context,
-            @NonNull ResourceType type, @NonNull String name) {
-        String libraryName = getLibraryName(context, type, name);
-        return String.format("The resource `@%1$s/%2$s` is marked as private in %3$s", type,
-                name, libraryName);
-    }
-
-    /** Pick a suitable name to describe the library defining the private resource */
-    @Nullable
-    private static String getLibraryName(@NonNull Context context, @NonNull ResourceType type,
-            @NonNull String name) {
-        ResourceVisibilityLookup lookup = context.getProject().getResourceVisibility();
-        AndroidLibrary library = lookup.getPrivateIn(type, name);
-        if (library != null) {
-            String libraryName = library.getProject();
-            if (libraryName != null) {
-                return libraryName;
-            }
-            MavenCoordinates coordinates = library.getResolvedCoordinates();
-            if (coordinates != null) {
-                return coordinates.getGroupId() + ':' + coordinates.getArtifactId();
-            }
-        }
-        return "the library";
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ReadParcelableDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ReadParcelableDetector.java
deleted file mode 100644
index 8cd8cc6..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ReadParcelableDetector.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_PARCEL;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastLiteralUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Looks for Parcelable classes that are missing a CREATOR field
- */
-public class ReadParcelableDetector extends Detector implements Detector.UastScanner {
-
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "ParcelClassLoader", //$NON-NLS-1$
-            "Default Parcel Class Loader",
-
-            "The documentation for `Parcel#readParcelable(ClassLoader)` (and its variations) " +
-            "says that you can pass in `null` to pick up the default class loader. However, " +
-            "that ClassLoader is a system class loader and is not able to find classes in " +
-            "your own application.\n" +
-            "\n" +
-            "If you are writing your own classes into the `Parcel` (not just SDK classes like " +
-            "`String` and so on), then you should supply a `ClassLoader` for your application " +
-            "instead; a simple way to obtain one is to just call `getClass().getClassLoader()` " +
-            "from your own class.",
-
-            Category.CORRECTNESS,
-            3,
-            Severity.WARNING,
-            new Implementation(
-                    ReadParcelableDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo("http://developer.android.com/reference/android/os/Parcel.html");
-
-    /** Constructs a new {@link ReadParcelableDetector} check */
-    public ReadParcelableDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                "readParcelable",
-                "readParcelableArray",
-                "readBundle",
-                "readArray",
-                "readSparseArray",
-                "readValue",
-                "readPersistableBundle"
-        );
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        PsiClass containingClass = method.getContainingClass();
-        if (containingClass == null) {
-            return;
-        }
-        if (!(CLASS_PARCEL.equals(containingClass.getQualifiedName()))) {
-            return;
-        }
-
-        List<UExpression> expressions = node.getValueArguments();
-        int argumentCount = expressions.size();
-        if (argumentCount == 0) {
-            String message = String.format("Using the default class loader "
-                            + "will not work if you are restoring your own classes. Consider "
-                            + "using for example `%1$s(getClass().getClassLoader())` instead.",
-                    node.getMethodName());
-            Location location = context.getUastLocation(node);
-            context.report(ISSUE, node, location, message);
-        } else if (argumentCount == 1) {
-            UExpression parameter = expressions.get(0);
-            if (UastLiteralUtils.isNullLiteral(parameter)) {
-                String message = "Passing null here (to use the default class loader) "
-                        + "will not work if you are restoring your own classes. Consider "
-                        + "using for example `getClass().getClassLoader()` instead.";
-                Location location = context.getUastLocation(node);
-                context.report(ISSUE, node, location, message);
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RecyclerViewDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RecyclerViewDetector.java
deleted file mode 100644
index 252a0dd..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RecyclerViewDetector.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.intellij.psi.*;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.tools.klint.checks.CutPasteDetector.isReachableFrom;
-
-/**
- * Checks related to RecyclerView usage.
- */
-public class RecyclerViewDetector extends Detector implements Detector.UastScanner {
-
-    public static final Implementation IMPLEMENTATION = new Implementation(
-            RecyclerViewDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue FIXED_POSITION = Issue.create(
-            "RecyclerView", //$NON-NLS-1$
-            "RecyclerView Problems",
-            "`RecyclerView` will *not* call `onBindViewHolder` again when the position of " +
-            "the item changes in the data set unless the item itself is " +
-            "invalidated or the new position cannot be determined.\n" +
-            "\n" +
-            "For this reason, you should *only* use the position parameter " +
-            "while acquiring the related data item inside this method, and " +
-            "should *not* keep a copy of it.\n" +
-            "\n" +
-            "If you need the position of an item later on (e.g. in a click " +
-            "listener), use `getAdapterPosition()` which will have the updated " +
-            "adapter position.",
-            Category.CORRECTNESS,
-            8,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    public static final Issue DATA_BINDER = Issue.create(
-            "PendingBindings", //$NON-NLS-1$
-            "Missing Pending Bindings",
-            "When using a `ViewDataBinding` in a `onBindViewHolder` method, you *must* " +
-            "call `executePendingBindings()` before the method exits; otherwise " +
-            "the data binding runtime will update the UI in the next animation frame " +
-            "causing a delayed update and potential jumps if the item resizes.",
-            Category.CORRECTNESS,
-            8,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    private static final String VIEW_ADAPTER = "android.support.v7.widget.RecyclerView.Adapter"; //$NON-NLS-1$
-    private static final String ON_BIND_VIEW_HOLDER = "onBindViewHolder"; //$NON-NLS-1$
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(VIEW_ADAPTER);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        for (PsiMethod method : declaration.findMethodsByName(ON_BIND_VIEW_HOLDER, false)) {
-            int size = evaluator.getParameterCount(method);
-            if (size == 2 || size == 3) {
-                checkMethod(context, method, declaration);
-            }
-        }
-        
-        super.checkClass(context, declaration);
-    }
-
-    private static void checkMethod(@NonNull JavaContext context,
-            @NonNull PsiMethod declaration, @NonNull PsiClass cls) {
-        PsiParameter[] parameters = declaration.getParameterList().getParameters();
-        PsiParameter viewHolder = parameters[0];
-        PsiParameter parameter = parameters[1];
-
-        ParameterEscapesVisitor visitor = new ParameterEscapesVisitor(context, cls, parameter);
-        UMethod method = context.getUastContext().getMethod(declaration);
-        method.accept(visitor);
-        if (visitor.variableEscapes()) {
-            reportError(context, viewHolder, parameter);
-        }
-
-        // Look for pending data binder calls that aren't executed before the method finishes
-        List<UCallExpression> dataBinderReferences = visitor.getDataBinders();
-        checkDataBinders(context, method, dataBinderReferences);
-    }
-
-    private static void reportError(@NonNull JavaContext context, PsiParameter viewHolder,
-            PsiParameter parameter) {
-        String variablePrefix = viewHolder.getName();
-        if (variablePrefix == null) {
-            variablePrefix = "ViewHolder";
-        }
-        String message = String.format("Do not treat position as fixed; only use immediately "
-                + "and call `%1$s.getAdapterPosition()` to look it up later",
-                variablePrefix);
-        context.report(FIXED_POSITION, parameter, context.getLocation(parameter),
-                message);
-    }
-
-    private static void checkDataBinders(@NonNull JavaContext context,
-            @NonNull UMethod declaration, List<UCallExpression> references) {
-        if (references != null && !references.isEmpty()) {
-            List<UCallExpression> targets = Lists.newArrayList();
-            List<UCallExpression> sources = Lists.newArrayList();
-            for (UCallExpression ref : references) {
-                if (isExecutePendingBindingsCall(ref)) {
-                    targets.add(ref);
-                } else {
-                    sources.add(ref);
-                }
-            }
-
-            // Only operate on the last call in each block: ignore siblings with the same parent
-            // That way if you have
-            //     dataBinder.foo();
-            //     dataBinder.bar();
-            //     dataBinder.baz();
-            // we only flag the *last* of these calls as needing an executePendingBindings
-            // afterwards. We do this with a parent map such that we correctly pair
-            // elements when they have nested references within (such as if blocks.)
-            Map<UElement, UCallExpression> parentToChildren = Maps.newHashMap();
-            for (UCallExpression reference : sources) {
-                // Note: We're using a map, not a multimap, and iterating forwards:
-                // this means that the *last* element will overwrite previous entries,
-                // and we end up with the last reference for each parent which is what we
-                // want
-                UExpression statement = UastUtils.getParentOfType(reference, UExpression.class, true);
-                if (statement != null) {
-                    parentToChildren.put(statement.getUastParent(), reference);
-                }
-            }
-
-            for (UCallExpression source : parentToChildren.values()) {
-                UExpression sourceBinderReference = source.getReceiver();
-                PsiField sourceDataBinder = getDataBinderReference(sourceBinderReference);
-                assert sourceDataBinder != null;
-
-                boolean reachesTarget = false;
-                for (UCallExpression target : targets) {
-                    if (sourceDataBinder.equals(getDataBinderReference(target.getReceiver()))
-                            // TODO: Provide full control flow graph, or at least provide an
-                            // isReachable method which can take multiple targets
-                            && isReachableFrom(declaration, source, target)) {
-                        reachesTarget = true;
-                        break;
-                    }
-                }
-                if (!reachesTarget) {
-                    String message = String.format(
-                            "You must call `%1$s.executePendingBindings()` "
-                                + "before the `onBind` method exits, otherwise, the DataBinding "
-                                + "library will update the UI in the next animation frame "
-                                + "causing a delayed update & potential jumps if the item "
-                                + "resizes.",
-                            sourceBinderReference.asSourceString());
-                    context.report(DATA_BINDER, source, context.getUastLocation(source), message);
-                }
-            }
-        }
-    }
-
-    private static boolean isExecutePendingBindingsCall(UCallExpression call) {
-        return "executePendingBindings".equals(call.getMethodName());
-    }
-
-    @Nullable
-    private static PsiField getDataBinderReference(@Nullable UExpression element) {
-        if (element instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) element).resolve();
-            if (resolved instanceof PsiField) {
-                PsiField field = (PsiField) resolved;
-                if ("dataBinder".equals(field.getName())) {
-                    return field;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Determines whether a given variable "escapes" either to a field or to a nested
-     * runnable. (We deliberately ignore variables that escape via method calls.)
-     */
-    private static class ParameterEscapesVisitor extends AbstractUastVisitor {
-        protected final JavaContext mContext;
-        private final List<PsiVariable> mVariables;
-        private final PsiClass mBindClass;
-        private boolean mEscapes;
-        private boolean mFoundInnerClass;
-
-        private ParameterEscapesVisitor(JavaContext context,
-                @NonNull PsiClass bindClass,
-                @NonNull PsiParameter variable) {
-            mContext = context;
-            mVariables = Lists.<PsiVariable>newArrayList(variable);
-            mBindClass = bindClass;
-        }
-
-        private boolean variableEscapes() {
-            return mEscapes;
-        }
-
-        @Override
-        public boolean visitVariable(UVariable variable) {
-            UExpression initializer = variable.getUastInitializer();
-            if (initializer instanceof UReferenceExpression) {
-                PsiElement resolved = ((UReferenceExpression) initializer).resolve();
-                //noinspection SuspiciousMethodCalls
-                if (resolved != null && mVariables.contains(resolved)) {
-                    if (resolved instanceof PsiLocalVariable) {
-                        mVariables.add(variable);
-                    } else if (resolved instanceof PsiField) {
-                        mEscapes = true;
-                    }
-                }
-            }
-            
-            return super.visitVariable(variable);
-        }
-
-        @Override
-        public boolean visitBinaryExpression(UBinaryExpression node) {
-            if (node.getOperator() instanceof UastBinaryOperator.AssignOperator) {
-                UExpression rhs = node.getRightOperand();
-                boolean clearLhs = true;
-                if (rhs instanceof UReferenceExpression) {
-                    PsiElement resolved = ((UReferenceExpression) rhs).resolve();
-                    //noinspection SuspiciousMethodCalls
-                    if (resolved != null && mVariables.contains(resolved)) {
-                        clearLhs = false;
-                        PsiElement resolvedLhs = UastUtils.tryResolve(node.getLeftOperand());
-                        if (resolvedLhs instanceof PsiLocalVariable) {
-                            PsiLocalVariable variable = (PsiLocalVariable) resolvedLhs;
-                            mVariables.add(variable);
-                        } else if (resolvedLhs instanceof PsiField) {
-                            mEscapes = true;
-                        }
-                    }
-                }
-                if (clearLhs) {
-                    // If we reassign one of the variables, clear it out
-                    PsiElement resolved = UastUtils.tryResolve(node.getLeftOperand());
-                    //noinspection SuspiciousMethodCalls
-                    if (resolved != null && mVariables.contains(resolved)) {
-                        //noinspection SuspiciousMethodCalls
-                        mVariables.remove(resolved);
-                    }
-                }
-            }
-            return super.visitBinaryExpression(node);
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            if (mFoundInnerClass) {
-                // Check to see if this reference is inside the same class as the original
-                // onBind (e.g. is this a reference from an inner class, or a reference
-                // to a variable assigned from there)
-                PsiElement resolved = node.resolve();
-                //noinspection SuspiciousMethodCalls
-                if (resolved != null && mVariables.contains(resolved)) {
-                    PsiClass outer = UastUtils.getParentOfType(node, UClass.class, true);
-                    if (!mBindClass.equals(outer)) {
-                        mEscapes = true;
-                    }
-                }
-            }
-            
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-
-        @Override
-        public boolean visitClass(UClass node) {
-            if (node instanceof UAnonymousClass || !node.isStatic()) {
-                mFoundInnerClass = true;
-            }
-
-            return super.visitClass(node);
-        }
-
-        // Also look for data binder references
-
-        private List<UCallExpression> mDataBinders = null;
-
-        @Nullable
-        private List<UCallExpression> getDataBinders() {
-            return mDataBinders;
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression expression) {
-            if (UastExpressionUtils.isMethodCall(expression)) {
-                UExpression methodExpression = expression.getReceiver();
-                PsiField dataBinder = getDataBinderReference(methodExpression);
-                //noinspection VariableNotUsedInsideIf
-                if (dataBinder != null) {
-                    if (mDataBinders == null) {
-                        mDataBinders = Lists.newArrayList();
-                    }
-                    mDataBinders.add(expression);
-                }
-            }
-            
-            return super.visitCallExpression(expression);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RegistrationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RegistrationDetector.java
deleted file mode 100644
index e0e9e43..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RegistrationDetector.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.CLASS_ACTIVITY;
-import static com.android.SdkConstants.CLASS_APPLICATION;
-import static com.android.SdkConstants.CLASS_BROADCASTRECEIVER;
-import static com.android.SdkConstants.CLASS_CONTENTPROVIDER;
-import static com.android.SdkConstants.CLASS_SERVICE;
-import static com.android.SdkConstants.TAG_ACTIVITY;
-import static com.android.SdkConstants.TAG_APPLICATION;
-import static com.android.SdkConstants.TAG_PROVIDER;
-import static com.android.SdkConstants.TAG_RECEIVER;
-import static com.android.SdkConstants.TAG_SERVICE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.AndroidProject;
-import com.android.builder.model.ProductFlavorContainer;
-import com.android.builder.model.SourceProviderContainer;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.android.utils.SdkUtils;
-import com.google.common.collect.Maps;
-import com.intellij.psi.PsiClass;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UClass;
-import org.w3c.dom.Element;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Checks for missing manifest registrations for activities, services etc
- * and also makes sure that they are registered with the correct tag
- */
-public class RegistrationDetector extends LayoutDetector implements Detector.UastScanner {
-    /** Unregistered activities and services */
-    public static final Issue ISSUE = Issue.create(
-            "Registered", //$NON-NLS-1$
-            "Class is not registered in the manifest",
-
-            "Activities, services and content providers should be registered in the " +
-            "`AndroidManifest.xml` file using `<activity>`, `<service>` and `<provider>` tags.\n" +
-            "\n" +
-            "If your activity is simply a parent class intended to be subclassed by other " +
-            "\"real\" activities, make it an abstract class.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    RegistrationDetector.class,
-                    EnumSet.of(Scope.MANIFEST, Scope.JAVA_FILE)))
-            .addMoreInfo(
-            "http://developer.android.com/guide/topics/manifest/manifest-intro.html"); //$NON-NLS-1$
-
-    protected Map<String, String> mManifestRegistrations;
-
-    /** Constructs a new {@link RegistrationDetector} */
-    public RegistrationDetector() {
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(sTags);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        if (!element.hasAttributeNS(ANDROID_URI, ATTR_NAME)) {
-            // For example, application appears in manifest and doesn't always have a name
-            return;
-        }
-        String fqcn = getFqcn(context, element);
-        String tag = element.getTagName();
-        String frameworkClass = tagToClass(tag);
-        if (frameworkClass != null) {
-            String signature = fqcn;
-            if (mManifestRegistrations == null) {
-                mManifestRegistrations = Maps.newHashMap();
-            }
-            mManifestRegistrations.put(signature, frameworkClass);
-            if (signature.indexOf('$') != -1) {
-                signature = signature.replace('$', '.');
-                mManifestRegistrations.put(signature, frameworkClass);
-            }
-        }
-    }
-
-    /**
-     * Returns the fully qualified class name for a manifest entry element that
-     * specifies a name attribute
-     *
-     * @param context the query context providing the project
-     * @param element the element
-     * @return the fully qualified class name
-     */
-    @NonNull
-    private static String getFqcn(@NonNull XmlContext context, @NonNull Element element) {
-        String className = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-        if (className.startsWith(".")) { //$NON-NLS-1$
-            return context.getProject().getPackage() + className;
-        } 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:
-            return context.getProject().getPackage() + '.' + className;
-        } // else: the class name is already a fully qualified class name
-
-        return className;
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Arrays.asList(
-                // Common super class for Activity, ContentProvider, Service, Application
-                // (as well as some other classes not registered in the manifest, such as
-                // Fragment and VoiceInteractionSession)
-                "android.content.ComponentCallbacks2",
-                CLASS_BROADCASTRECEIVER);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass cls) {
-        if (cls.getName() == null) {
-            // anonymous class; can't be registered
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isAbstract(cls) || evaluator.isPrivate(cls)) {
-            // Abstract classes do not need to be registered, and
-            // private classes are clearly not intended to be registered
-            return;
-        }
-
-        String rightTag = getTag(evaluator, cls);
-        if (rightTag == null) {
-            // some non-registered Context, such as a BackupAgent
-            return;
-        }
-        String className = cls.getQualifiedName();
-        if (className == null) {
-            return;
-        }
-        if (mManifestRegistrations != null) {
-            String framework = mManifestRegistrations.get(className);
-            if (framework == null) {
-                reportMissing(context, cls, className, rightTag);
-            } else if (!InheritanceUtil.isInheritor(cls, false, framework)) {
-                reportWrongTag(context, cls, rightTag, className, framework);
-            }
-        } else {
-            reportMissing(context, cls, className, rightTag);
-        }
-    }
-
-    private static void reportWrongTag(
-            @NonNull JavaContext context,
-            @NonNull PsiClass node,
-            @NonNull String rightTag,
-            @NonNull String className,
-            @NonNull String framework) {
-        String wrongTag = classToTag(framework);
-        if (wrongTag == null) {
-            return;
-        }
-        Location location = context.getNameLocation(node);
-        String message = String.format("`%1$s` is %2$s but is registered "
-                        + "in the manifest as %3$s", className, describeTag(rightTag),
-                describeTag(wrongTag));
-        context.report(ISSUE, node, location, message);
-    }
-
-    private static String describeTag(@NonNull String tag) {
-        String article = tag.startsWith("a") ? "an" : "a"; // an for activity and application
-        return String.format("%1$s `<%2$s>`", article, tag);
-    }
-
-    private static void reportMissing(
-            @NonNull JavaContext context,
-            @NonNull PsiClass node,
-            @NonNull String className,
-            @NonNull String tag) {
-        if (tag.equals(TAG_RECEIVER)) {
-            // Receivers can be registered in code; don't flag these.
-            return;
-        }
-
-        // Don't flag activities registered in test source sets
-        if (context.getProject().isGradleProject()) {
-            AndroidProject model = context.getProject().getGradleProjectModel();
-            if (model != null) {
-                String javaSource = context.file.getPath();
-                // Test source set?
-
-                for (SourceProviderContainer extra : model.getDefaultConfig().getExtraSourceProviders()) {
-                    String artifactName = extra.getArtifactName();
-                    if (AndroidProject.ARTIFACT_ANDROID_TEST.equals(artifactName)) {
-                        for (File file : extra.getSourceProvider().getJavaDirectories()) {
-                            if (SdkUtils.startsWithIgnoreCase(javaSource, file.getPath())) {
-                                return;
-                            }
-                        }
-                    }
-                }
-
-                for (ProductFlavorContainer container : model.getProductFlavors()) {
-                    for (SourceProviderContainer extra : container.getExtraSourceProviders()) {
-                        String artifactName = extra.getArtifactName();
-                        if (AndroidProject.ARTIFACT_ANDROID_TEST.equals(artifactName)) {
-                            for (File file : extra.getSourceProvider().getJavaDirectories()) {
-                                if (SdkUtils.startsWithIgnoreCase(javaSource, file.getPath())) {
-                                    return;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        Location location = context.getNameLocation(node);
-        String message = String.format("The `<%1$s> %2$s` is not registered in the manifest",
-                tag, className);
-        context.report(ISSUE, node, location, message);
-    }
-
-    private static String getTag(@NonNull JavaEvaluator evaluator, @NonNull PsiClass cls) {
-        String tag = null;
-        for (String s : sClasses) {
-            if (InheritanceUtil.isInheritor(cls, false, s)) {
-                tag = classToTag(s);
-                break;
-            }
-        }
-        return tag;
-    }
-
-    /** The manifest tags we care about */
-    private static final String[] sTags = new String[] {
-        TAG_ACTIVITY,
-        TAG_SERVICE,
-        TAG_RECEIVER,
-        TAG_PROVIDER,
-        TAG_APPLICATION
-        // Keep synchronized with {@link #sClasses}
-    };
-
-    /** The corresponding framework classes that the tags in {@link #sTags} should extend */
-    private static final String[] sClasses = new String[] {
-            CLASS_ACTIVITY,
-            CLASS_SERVICE,
-            CLASS_BROADCASTRECEIVER,
-            CLASS_CONTENTPROVIDER,
-            CLASS_APPLICATION
-            // Keep synchronized with {@link #sTags}
-    };
-
-    /** Looks up the corresponding framework class a given manifest tag's class should extend */
-    private static String tagToClass(String tag) {
-        for (int i = 0, n = sTags.length; i < n; i++) {
-            if (sTags[i].equals(tag)) {
-                return sClasses[i];
-            }
-        }
-
-        return null;
-    }
-
-    /** Looks up the tag a given framework class should be registered with */
-    protected static String classToTag(String className) {
-        for (int i = 0, n = sClasses.length; i < n; i++) {
-            if (sClasses[i].equals(className)) {
-                return sTags[i];
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RequiredAttributeDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RequiredAttributeDetector.java
deleted file mode 100644
index 98305d2..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RequiredAttributeDetector.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
-import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX;
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_LAYOUT;
-import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_PARENT;
-import static com.android.SdkConstants.ATTR_STYLE;
-import static com.android.SdkConstants.AUTO_URI;
-import static com.android.SdkConstants.FD_RES_LAYOUT;
-import static com.android.SdkConstants.FQCN_GRID_LAYOUT_V7;
-import static com.android.SdkConstants.GRID_LAYOUT;
-import static com.android.SdkConstants.LAYOUT_RESOURCE_PREFIX;
-import static com.android.SdkConstants.REQUEST_FOCUS;
-import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
-import static com.android.SdkConstants.TABLE_LAYOUT;
-import static com.android.SdkConstants.TABLE_ROW;
-import static com.android.SdkConstants.TAG_DATA;
-import static com.android.SdkConstants.TAG_IMPORT;
-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.TAG_VARIABLE;
-import static com.android.SdkConstants.VIEW_INCLUDE;
-import static com.android.SdkConstants.VIEW_MERGE;
-import static com.android.resources.ResourceFolderType.LAYOUT;
-import static com.android.resources.ResourceFolderType.VALUES;
-import static com.android.tools.klint.detector.api.LintUtils.getLayoutName;
-import static com.android.tools.klint.detector.api.LintUtils.isNullLiteral;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.resources.ResourceUrl;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.ResourceEvaluator;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.psi.JavaElementVisitor;
-import com.intellij.psi.PsiExpression;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastLiteralUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Ensures that layout width and height attributes are specified
- */
-public class RequiredAttributeDetector extends LayoutDetector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "RequiredSize", //$NON-NLS-1$
-            "Missing `layout_width` or `layout_height` attributes",
-
-            "All views must specify an explicit `layout_width` and `layout_height` attribute. " +
-            "There is a runtime check for this, so if you fail to specify a size, an exception " +
-            "is thrown at runtime.\n" +
-            "\n" +
-            "It's possible to specify these widths via styles as well. GridLayout, as a special " +
-            "case, does not require you to specify a size.",
-            Category.CORRECTNESS,
-            4,
-            Severity.ERROR,
-            new Implementation(
-                    RequiredAttributeDetector.class,
-                    EnumSet.of(Scope.JAVA_FILE, Scope.ALL_RESOURCE_FILES)));
-
-    public static final String PERCENT_RELATIVE_LAYOUT
-            = "android.support.percent.PercentRelativeLayout";
-    public static final String ATTR_LAYOUT_WIDTH_PERCENT = "layout_widthPercent";
-    public static final String ATTR_LAYOUT_HEIGHT_PERCENT = "layout_heightPercent";
-
-    /** Map from each style name to parent style */
-    @Nullable private Map<String, String> mStyleParents;
-
-    /** Set of style names where the style sets the layout width */
-    @Nullable private Set<String> mWidthStyles;
-
-    /** Set of style names where the style sets the layout height */
-    @Nullable private Set<String> mHeightStyles;
-
-    /** Set of layout names for layouts that are included by an {@code <include>} tag
-     * where the width is set on the include */
-    @Nullable private Set<String> mIncludedWidths;
-
-    /** Set of layout names for layouts that are included by an {@code <include>} tag
-     * where the height is set on the include */
-    @Nullable private Set<String> mIncludedHeights;
-
-    /** Set of layout names for layouts that are included by an {@code <include>} tag
-     * where the width is <b>not</b> set on the include */
-    @Nullable private Set<String> mNotIncludedWidths;
-
-    /** Set of layout names for layouts that are included by an {@code <include>} tag
-     * where the height is <b>not</b> set on the include */
-    @Nullable private Set<String> mNotIncludedHeights;
-
-    /** Whether the width was set in a theme definition */
-    private boolean mSetWidthInTheme;
-
-    /** Whether the height was set in a theme definition */
-    private boolean mSetHeightInTheme;
-
-    /** Constructs a new {@link RequiredAttributeDetector} */
-    public RequiredAttributeDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == LAYOUT || folderType == VALUES;
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        // Process checks in two phases:
-        // Phase 1: Gather styles and includes (styles are encountered after the layouts
-        // so we can't do it in a single phase, and includes can be affected by includes from
-        // layouts we haven't seen yet)
-        // Phase 2: Process layouts, using gathered style and include data, and mark layouts
-        // not known.
-        //
-        if (context.getPhase() == 1) {
-            checkSizeSetInTheme();
-
-            context.requestRepeat(this, Scope.RESOURCE_FILE_SCOPE);
-        }
-    }
-
-    private boolean isWidthStyle(String style) {
-        return isSizeStyle(style, mWidthStyles);
-    }
-
-    private boolean isHeightStyle(String style) {
-        return isSizeStyle(style, mHeightStyles);
-    }
-
-    private boolean isSizeStyle(String style, Set<String> sizeStyles) {
-        if (isFrameworkSizeStyle(style)) {
-            return true;
-        }
-        if (sizeStyles == null) {
-            return false;
-        }
-        return isSizeStyle(stripStylePrefix(style), sizeStyles, 0);
-    }
-
-    private static boolean isFrameworkSizeStyle(String style) {
-        // The styles Widget.TextView.ListSeparator (and several theme variations, such as
-        // Widget.Holo.TextView.ListSeparator, Widget.Holo.Light.TextView.ListSeparator, etc)
-        // define layout_width and layout_height.
-        // These are exposed through the listSeparatorTextViewStyle style.
-        if (style.equals("?android:attr/listSeparatorTextViewStyle")      //$NON-NLS-1$
-                || style.equals("?android/listSeparatorTextViewStyle")) { //$NON-NLS-1$
-            return true;
-        }
-
-        // It's also set on Widget.QuickContactBadge and Widget.QuickContactBadgeSmall
-        // These are exposed via a handful of attributes with a common prefix
-        if (style.startsWith("?android:attr/quickContactBadgeStyle")) { //$NON-NLS-1$
-            return true;
-        }
-
-        // Finally, the styles are set on MediaButton and Widget.Holo.Tab (and
-        // Widget.Holo.Light.Tab) but these are not exposed via attributes.
-
-        return false;
-    }
-
-    private boolean isSizeStyle(
-            @NonNull String style,
-            @NonNull Set<String> sizeStyles, int depth) {
-        if (depth == 30) {
-            // Cycle between local and framework attribute style missed
-            // by the fact that we're stripping the distinction between framework
-            // and local styles here
-            return false;
-        }
-
-        assert !style.startsWith(STYLE_RESOURCE_PREFIX)
-                && !style.startsWith(ANDROID_STYLE_RESOURCE_PREFIX);
-
-        if (sizeStyles.contains(style)) {
-            return true;
-        }
-
-        if (mStyleParents != null) {
-            String parentStyle = mStyleParents.get(style);
-            if (parentStyle != null) {
-                parentStyle = stripStylePrefix(parentStyle);
-                if (isSizeStyle(parentStyle, sizeStyles, depth + 1)) {
-                    return true;
-                }
-            }
-        }
-
-        int index = style.lastIndexOf('.');
-        if (index > 0) {
-            return isSizeStyle(style.substring(0, index), sizeStyles, depth + 1);
-        }
-
-        return false;
-    }
-
-    private void checkSizeSetInTheme() {
-        // Look through the styles and determine whether each style is a theme
-        if (mStyleParents == null) {
-            return;
-        }
-
-        Map<String, Boolean> isTheme = Maps.newHashMap();
-        for (String style : mStyleParents.keySet()) {
-            if (isTheme(stripStylePrefix(style), isTheme, 0)) {
-                mSetWidthInTheme = true;
-                mSetHeightInTheme = true;
-                break;
-            }
-        }
-    }
-
-    private boolean isTheme(String style, Map<String, Boolean> isTheme, int depth) {
-        if (depth == 30) {
-            // Cycle between local and framework attribute style missed
-            // by the fact that we're stripping the distinction between framework
-            // and local styles here
-            return false;
-        }
-
-        assert !style.startsWith(STYLE_RESOURCE_PREFIX)
-                && !style.startsWith(ANDROID_STYLE_RESOURCE_PREFIX);
-
-        Boolean known = isTheme.get(style);
-        if (known != null) {
-            return known;
-        }
-
-        if (style.contains("Theme")) { //$NON-NLS-1$
-            isTheme.put(style, true);
-            return true;
-        }
-
-        if (mStyleParents != null) {
-            String parentStyle = mStyleParents.get(style);
-            if (parentStyle != null) {
-                parentStyle = stripStylePrefix(parentStyle);
-                if (isTheme(parentStyle, isTheme, depth + 1)) {
-                    isTheme.put(style, true);
-                    return true;
-                }
-            }
-        }
-
-        int index = style.lastIndexOf('.');
-        if (index > 0) {
-            String parentStyle = style.substring(0, index);
-            boolean result = isTheme(parentStyle, isTheme, depth + 1);
-            isTheme.put(style, result);
-            return result;
-        }
-
-        return false;
-    }
-
-    @VisibleForTesting
-    static boolean hasLayoutVariations(File file) {
-        File parent = file.getParentFile();
-        if (parent == null) {
-            return false;
-        }
-        File res = parent.getParentFile();
-        if (res == null) {
-            return false;
-        }
-        String name = file.getName();
-        File[] folders = res.listFiles();
-        if (folders == null) {
-            return false;
-        }
-        for (File folder : folders) {
-            if (!folder.getName().startsWith(FD_RES_LAYOUT)) {
-                continue;
-            }
-            if (folder.equals(parent)) {
-                continue;
-            }
-            File other = new File(folder, name);
-            if (other.exists()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static String stripStylePrefix(@NonNull String style) {
-        if (style.startsWith(STYLE_RESOURCE_PREFIX)) {
-            style = style.substring(STYLE_RESOURCE_PREFIX.length());
-        } else if (style.startsWith(ANDROID_STYLE_RESOURCE_PREFIX)) {
-            style = style.substring(ANDROID_STYLE_RESOURCE_PREFIX.length());
-        }
-
-        return style;
-    }
-
-    private static boolean isRootElement(@NonNull Node node) {
-        return node == node.getOwnerDocument().getDocumentElement();
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return ALL;
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        ResourceFolderType folderType = context.getResourceFolderType();
-        int phase = context.getPhase();
-        if (phase == 1 && folderType == VALUES) {
-            String tag = element.getTagName();
-            if (TAG_STYLE.equals(tag)) {
-                String parent = element.getAttribute(ATTR_PARENT);
-                if (parent != null && !parent.isEmpty()) {
-                    String name = element.getAttribute(ATTR_NAME);
-                    if (name != null && !name.isEmpty()) {
-                        if (mStyleParents == null) {
-                            mStyleParents = Maps.newHashMap();
-                        }
-                        mStyleParents.put(name, parent);
-                    }
-                }
-            } else if (TAG_ITEM.equals(tag)
-                    && TAG_STYLE.equals(element.getParentNode().getNodeName())) {
-                String name = element.getAttribute(ATTR_NAME);
-                if (name.endsWith(ATTR_LAYOUT_WIDTH) &&
-                        name.equals(ANDROID_NS_NAME_PREFIX + ATTR_LAYOUT_WIDTH)) {
-                    if (mWidthStyles == null) {
-                        mWidthStyles = Sets.newHashSet();
-                    }
-                    String styleName = ((Element) element.getParentNode()).getAttribute(ATTR_NAME);
-                    mWidthStyles.add(styleName);
-                }
-                if (name.endsWith(ATTR_LAYOUT_HEIGHT) &&
-                        name.equals(ANDROID_NS_NAME_PREFIX + ATTR_LAYOUT_HEIGHT)) {
-                    if (mHeightStyles == null) {
-                        mHeightStyles = Sets.newHashSet();
-                    }
-                    String styleName = ((Element) element.getParentNode()).getAttribute(ATTR_NAME);
-                    mHeightStyles.add(styleName);
-                }
-            }
-        } else if (folderType == LAYOUT) {
-            if (phase == 1) {
-                // Gather includes
-                if (element.getTagName().equals(VIEW_INCLUDE)) {
-                    String layout = element.getAttribute(ATTR_LAYOUT);
-                    if (layout != null && !layout.isEmpty()) {
-                        recordIncludeWidth(layout,
-                                element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH));
-                        recordIncludeHeight(layout,
-                                element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT));
-                    }
-                }
-            } else {
-                assert phase == 2; // Check everything using style data and include data
-                boolean hasWidth = element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
-                boolean hasHeight = element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
-
-                if (mSetWidthInTheme) {
-                    hasWidth = true;
-                }
-
-                if (mSetHeightInTheme) {
-                    hasHeight = true;
-                }
-
-                if (hasWidth && hasHeight) {
-                    return;
-                }
-
-                String tag = element.getTagName();
-                if (VIEW_MERGE.equals(tag)
-                        || VIEW_INCLUDE.equals(tag)
-                        || REQUEST_FOCUS.equals(tag)) {
-                    return;
-                }
-
-                // Data binding: these tags shouldn't specify width/height
-                if (tag.equals(TAG_LAYOUT)
-                        || tag.equals(TAG_VARIABLE)
-                        || tag.equals(TAG_DATA)
-                        || tag.equals(TAG_IMPORT)) {
-                    return;
-                }
-
-                String parentTag = element.getParentNode() != null
-                        ?  element.getParentNode().getNodeName() : "";
-                if (TABLE_LAYOUT.equals(parentTag)
-                        || TABLE_ROW.equals(parentTag)
-                        || GRID_LAYOUT.equals(parentTag)
-                        || FQCN_GRID_LAYOUT_V7.equals(parentTag)) {
-                    return;
-                }
-
-                // PercentRelativeLayout or PercentFrameLayout?
-                boolean isPercent = parentTag.startsWith("android.support.percent.Percent");
-                if (isPercent) {
-                    hasWidth |= element.hasAttributeNS(AUTO_URI, ATTR_LAYOUT_WIDTH_PERCENT);
-                    hasHeight |= element.hasAttributeNS(AUTO_URI, ATTR_LAYOUT_HEIGHT_PERCENT);
-                    if (hasWidth && hasHeight) {
-                        return;
-                    }
-                }
-
-                if (!context.getProject().getReportIssues()) {
-                    // If this is a library project not being analyzed, ignore it
-                    return;
-                }
-
-                boolean certain = true;
-                boolean isRoot = isRootElement(element);
-                if (isRoot || isRootElement(element.getParentNode())
-                        && VIEW_MERGE.equals(parentTag)) {
-                    String name = LAYOUT_RESOURCE_PREFIX + getLayoutName(context.file);
-                    if (!hasWidth && mIncludedWidths != null) {
-                        hasWidth = mIncludedWidths.contains(name);
-                        // If the layout is *also* included in a context where the width
-                        // was not set, we're not certain; it's possible that
-                        if (mNotIncludedWidths != null && mNotIncludedWidths.contains(name)) {
-                            hasWidth = false;
-                            // If we only have a single layout we know that this layout isn't
-                            // always included with layout_width or layout_height set, but
-                            // if there are multiple layouts, it's possible that at runtime
-                            // we only load the size-less layout by the tag which includes
-                            // the size
-                            certain = !hasLayoutVariations(context.file);
-                        }
-                    }
-                    if (!hasHeight && mIncludedHeights != null) {
-                        hasHeight = mIncludedHeights.contains(name);
-                        if (mNotIncludedHeights != null && mNotIncludedHeights.contains(name)) {
-                            hasHeight = false;
-                            certain = !hasLayoutVariations(context.file);
-                        }
-                    }
-                    if (hasWidth && hasHeight) {
-                        return;
-                    }
-                }
-
-                if (!hasWidth || !hasHeight) {
-                    String style = element.getAttribute(ATTR_STYLE);
-                    if (style != null && !style.isEmpty()) {
-                        if (!hasWidth) {
-                            hasWidth = isWidthStyle(style);
-                        }
-                        if (!hasHeight) {
-                            hasHeight = isHeightStyle(style);
-                        }
-                    }
-                    if (hasWidth && hasHeight) {
-                        return;
-                    }
-                }
-
-                String message;
-                if (!(hasWidth || hasHeight)) {
-                    if (certain) {
-                        message = "The required `layout_width` and `layout_height` attributes " +
-                                "are missing";
-                    } else {
-                        message = "The required `layout_width` and `layout_height` attributes " +
-                                "*may* be missing";
-                    }
-                } else {
-                    String attribute = hasWidth ? ATTR_LAYOUT_HEIGHT : ATTR_LAYOUT_WIDTH;
-                    if (certain) {
-                        message = String.format("The required `%1$s` attribute is missing",
-                                attribute);
-                    } else {
-                        message = String.format("The required `%1$s` attribute *may* be missing",
-                                attribute);
-                    }
-                }
-                if (isPercent) {
-                    String escapedLayoutWidth = '`' + ATTR_LAYOUT_WIDTH + '`';
-                    String escapedLayoutHeight = '`' + ATTR_LAYOUT_HEIGHT + '`';
-                    String escapedLayoutWidthPercent = '`' + ATTR_LAYOUT_WIDTH_PERCENT + '`';
-                    String escapedLayoutHeightPercent = '`' + ATTR_LAYOUT_HEIGHT_PERCENT + '`';
-                    message = message.replace(escapedLayoutWidth, escapedLayoutWidth + " or "
-                            + escapedLayoutWidthPercent).replace(escapedLayoutHeight,
-                            escapedLayoutHeight + " or " + escapedLayoutHeightPercent);
-                }
-                context.report(ISSUE, element, context.getLocation(element),
-                        message);
-            }
-        }
-    }
-
-    private void recordIncludeWidth(String layout, boolean providesWidth) {
-        if (providesWidth) {
-            if (mIncludedWidths == null) {
-                mIncludedWidths = Sets.newHashSet();
-            }
-            mIncludedWidths.add(layout);
-        } else {
-            if (mNotIncludedWidths == null) {
-                mNotIncludedWidths = Sets.newHashSet();
-            }
-            mNotIncludedWidths.add(layout);
-        }
-    }
-
-    private void recordIncludeHeight(String layout, boolean providesHeight) {
-        if (providesHeight) {
-            if (mIncludedHeights == null) {
-                mIncludedHeights = Sets.newHashSet();
-            }
-            mIncludedHeights.add(layout);
-        } else {
-            if (mNotIncludedHeights == null) {
-                mNotIncludedHeights = Sets.newHashSet();
-            }
-            mNotIncludedHeights.add(layout);
-        }
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    @Nullable
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("inflate"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        // Handle
-        //    View#inflate(Context context, int resource, ViewGroup root)
-        //    LayoutInflater#inflate(int resource, ViewGroup root)
-        //    LayoutInflater#inflate(int resource, ViewGroup root, boolean attachToRoot)
-        List<UExpression> args = call.getValueArguments();
-
-        String layout = null;
-        int index = 0;
-        ResourceEvaluator evaluator = new ResourceEvaluator(context);
-        for (UExpression expression : args) {
-            ResourceUrl url = evaluator.getResource(expression);
-            if (url != null && url.type == ResourceType.LAYOUT) {
-                layout = url.toString();
-                break;
-            }
-            index++;
-        }
-
-        if (layout == null) {
-            // Flow analysis didn't succeed
-            return;
-        }
-
-        // In all the applicable signatures, the view root argument is immediately after
-        // the layout resource id.
-        int viewRootPos = index + 1;
-        if (viewRootPos < args.size()) {
-            UExpression viewRoot = args.get(viewRootPos);
-            if (UastLiteralUtils.isNullLiteral(viewRoot)) {
-                // Yep, this one inflates the given view with a null parent:
-                // Tag it as such. For now just use the include data structure since
-                // it has the same net effect
-                recordIncludeWidth(layout, true);
-                recordIncludeHeight(layout, true);
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java
deleted file mode 100644
index 946dba5..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_DRAWABLE_END;
-import static com.android.SdkConstants.ATTR_DRAWABLE_LEFT;
-import static com.android.SdkConstants.ATTR_DRAWABLE_RIGHT;
-import static com.android.SdkConstants.ATTR_DRAWABLE_START;
-import static com.android.SdkConstants.ATTR_GRAVITY;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_END;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_LEFT;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_END;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_LEFT;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_RIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_START;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_RIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_START;
-import static com.android.SdkConstants.ATTR_LAYOUT_GRAVITY;
-import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN;
-import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_END;
-import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_LEFT;
-import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_RIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_START;
-import static com.android.SdkConstants.ATTR_LAYOUT_TO_END_OF;
-import static com.android.SdkConstants.ATTR_LAYOUT_TO_LEFT_OF;
-import static com.android.SdkConstants.ATTR_LAYOUT_TO_RIGHT_OF;
-import static com.android.SdkConstants.ATTR_LAYOUT_TO_START_OF;
-import static com.android.SdkConstants.ATTR_LIST_PREFERRED_ITEM_PADDING_END;
-import static com.android.SdkConstants.ATTR_LIST_PREFERRED_ITEM_PADDING_LEFT;
-import static com.android.SdkConstants.ATTR_LIST_PREFERRED_ITEM_PADDING_RIGHT;
-import static com.android.SdkConstants.ATTR_LIST_PREFERRED_ITEM_PADDING_START;
-import static com.android.SdkConstants.ATTR_PADDING;
-import static com.android.SdkConstants.ATTR_PADDING_END;
-import static com.android.SdkConstants.ATTR_PADDING_LEFT;
-import static com.android.SdkConstants.ATTR_PADDING_RIGHT;
-import static com.android.SdkConstants.ATTR_PADDING_START;
-import static com.android.SdkConstants.GRAVITY_VALUE_END;
-import static com.android.SdkConstants.GRAVITY_VALUE_LEFT;
-import static com.android.SdkConstants.GRAVITY_VALUE_RIGHT;
-import static com.android.SdkConstants.GRAVITY_VALUE_START;
-import static com.android.SdkConstants.TAG_APPLICATION;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LayoutDetector;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.USimpleNameReferenceExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Check which looks for RTL issues (right-to-left support) in layouts
- */
-public class RtlDetector extends LayoutDetector implements Detector.UastScanner {
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            RtlDetector.class,
-            EnumSet.of(Scope.RESOURCE_FILE, Scope.JAVA_FILE, Scope.MANIFEST),
-            Scope.RESOURCE_FILE_SCOPE,
-            Scope.JAVA_FILE_SCOPE,
-            Scope.MANIFEST_SCOPE
-    );
-
-    public static final Issue USE_START = Issue.create(
-        "RtlHardcoded", //$NON-NLS-1$
-        "Using left/right instead of start/end attributes",
-
-        "Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is " +
-        "rendered in locales where text flows from right to left. Use `Gravity#START` " +
-        "and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` " +
-        "attributes, use `start` rather than `left`.\n" +
-        "\n" +
-        "For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` " +
-        "and `layout_marginStart`. *NOTE*: If your `minSdkVersion` is less than 17, you should " +
-        "add *both* the older left/right attributes *as well as* the new start/right " +
-        "attributes. On older platforms, where RTL is not supported and the start/right " +
-        "attributes are unknown and therefore ignored, you need the older left/right " +
-        "attributes. There is a separate lint check which catches that type of error.\n" +
-        "\n" +
-        "(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even " +
-        "when targeting older platforms, because the `start` bitmask is a superset of the " +
-        "`left` bitmask. Therefore, you can use `gravity=\"start\"` rather than " +
-        "`gravity=\"left|start\"`.)",
-
-        Category.RTL, 5, Severity.WARNING, IMPLEMENTATION);
-
-    public static final Issue COMPAT = Issue.create(
-        "RtlCompat", //$NON-NLS-1$
-        "Right-to-left text compatibility issues",
-
-        "API 17 adds a `textAlignment` attribute to specify text alignment. However, " +
-        "if you are supporting older versions than API 17, you must *also* specify a " +
-        "gravity or layout_gravity attribute, since older platforms will ignore the " +
-        "`textAlignment` attribute.",
-
-        Category.RTL, 6, Severity.ERROR, IMPLEMENTATION);
-
-    public static final Issue SYMMETRY = Issue.create(
-        "RtlSymmetry", //$NON-NLS-1$
-        "Padding and margin symmetry",
-
-        "If you specify padding or margin on the left side of a layout, you should " +
-        "probably also specify padding on the right side (and vice versa) for " +
-        "right-to-left layout symmetry.",
-
-        Category.RTL, 6, Severity.WARNING, IMPLEMENTATION);
-
-
-    public static final Issue ENABLED = Issue.create(
-        "RtlEnabled", //$NON-NLS-1$
-        "Using RTL attributes without enabling RTL support",
-
-        "To enable right-to-left support, when running on API 17 and higher, you must " +
-        "set the `android:supportsRtl` attribute in the manifest `<application>` element.\n" +
-        "\n" +
-        "If you have started adding RTL attributes, but have not yet finished the " +
-        "migration, you can set the attribute to false to satisfy this lint check.",
-
-        Category.RTL, 3, Severity.WARNING, IMPLEMENTATION);
-
-    /* TODO:
-    public static final Issue FIELD = Issue.create(
-        "RtlFieldAccess", //$NON-NLS-1$
-        "Accessing margin and padding fields directly",
-
-        "Modifying the padding and margin constants in view objects directly is " +
-        "problematic when using RTL support, since it can lead to inconsistent states. You " +
-        "*must* use the corresponding setter methods instead (`View#setPadding` etc).",
-
-        Category.RTL, 3, Severity.WARNING, IMPLEMENTATION).setEnabledByDefault(false);
-
-    public static final Issue AWARE = Issue.create(
-        "RtlAware", //$NON-NLS-1$
-        "View code not aware of RTL APIs",
-
-        "When manipulating views, and especially when implementing custom layouts, " +
-        "the code may need to be aware of RTL APIs. This lint check looks for usages of " +
-        "APIs that frequently require adjustments for right-to-left text, and warns if it " +
-        "does not also see text direction look-ups indicating that the code has already " +
-        "been updated to handle RTL layouts.",
-
-        Category.RTL, 3, Severity.WARNING, IMPLEMENTATION).setEnabledByDefault(false);
-    */
-
-    private static final String RIGHT_FIELD = "RIGHT";                          //$NON-NLS-1$
-    private static final String LEFT_FIELD = "LEFT";                            //$NON-NLS-1$
-    private static final String FQCN_GRAVITY = "android.view.Gravity";          //$NON-NLS-1$
-    private static final String ATTR_TEXT_ALIGNMENT = "textAlignment";          //$NON-NLS-1$
-    static final String ATTR_SUPPORTS_RTL = "supportsRtl";                      //$NON-NLS-1$
-
-    /** API version in which RTL support was added */
-    private static final int RTL_API = 17;
-
-    private static final String LEFT = "Left";
-    private static final String START = "Start";
-    private static final String RIGHT = "Right";
-    private static final String END = "End";
-
-    private Boolean mEnabledRtlSupport;
-    private boolean mUsesRtlAttributes;
-
-    /** Constructs a new {@link RtlDetector} */
-    public RtlDetector() {
-    }
-
-    private boolean rtlApplies(@NonNull Context context) {
-        Project project = context.getMainProject();
-        if  (project.getTargetSdk() < RTL_API) {
-            return false;
-        }
-
-        int buildTarget = project.getBuildSdk();
-        if (buildTarget != -1 && buildTarget < RTL_API) {
-            return false;
-        }
-
-        //noinspection RedundantIfStatement
-        if (mEnabledRtlSupport != null && !mEnabledRtlSupport) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mUsesRtlAttributes && mEnabledRtlSupport == null && rtlApplies(context)) {
-            List<File> manifestFile = context.getMainProject().getManifestFiles();
-            if (!manifestFile.isEmpty()) {
-                Location location = Location.create(manifestFile.get(0));
-                context.report(ENABLED, location,
-                        "The project references RTL attributes, but does not explicitly enable " +
-                        "or disable RTL support with `android:supportsRtl` in the manifest");
-            }
-        }
-    }
-
-    // ---- Implements XmlDetector ----
-
-    @VisibleForTesting
-    static final String[] ATTRIBUTES = new String[] {
-            // Pairs, from left/right constants to corresponding start/end constants
-            ATTR_LAYOUT_ALIGN_PARENT_LEFT,          ATTR_LAYOUT_ALIGN_PARENT_START,
-            ATTR_LAYOUT_ALIGN_PARENT_RIGHT,         ATTR_LAYOUT_ALIGN_PARENT_END,
-            ATTR_LAYOUT_MARGIN_LEFT,                ATTR_LAYOUT_MARGIN_START,
-            ATTR_LAYOUT_MARGIN_RIGHT,               ATTR_LAYOUT_MARGIN_END,
-            ATTR_PADDING_LEFT,                      ATTR_PADDING_START,
-            ATTR_PADDING_RIGHT,                     ATTR_PADDING_END,
-            ATTR_DRAWABLE_LEFT,                     ATTR_DRAWABLE_START,
-            ATTR_DRAWABLE_RIGHT,                    ATTR_DRAWABLE_END,
-            ATTR_LIST_PREFERRED_ITEM_PADDING_LEFT,  ATTR_LIST_PREFERRED_ITEM_PADDING_START,
-            ATTR_LIST_PREFERRED_ITEM_PADDING_RIGHT, ATTR_LIST_PREFERRED_ITEM_PADDING_END,
-
-            // RelativeLayout
-            ATTR_LAYOUT_TO_LEFT_OF,                 ATTR_LAYOUT_TO_START_OF,
-            ATTR_LAYOUT_TO_RIGHT_OF,                ATTR_LAYOUT_TO_END_OF,
-            ATTR_LAYOUT_ALIGN_LEFT,                 ATTR_LAYOUT_ALIGN_START,
-            ATTR_LAYOUT_ALIGN_RIGHT,                ATTR_LAYOUT_ALIGN_END,
-    };
-    static {
-        if (LintUtils.assertionsEnabled()) {
-            for (int i = 0; i < ATTRIBUTES.length; i += 2) {
-                String replace = ATTRIBUTES[i];
-                String with = ATTRIBUTES[i + 1];
-                assert with.equals(convertOldToNew(replace));
-                assert replace.equals(convertNewToOld(with));
-            }
-        }
-    }
-
-    public static boolean isRtlAttributeName(@NonNull String attribute) {
-        for (int i = 1; i < ATTRIBUTES.length; i += 2) {
-            if (attribute.equals(ATTRIBUTES[i])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @VisibleForTesting
-    static String convertOldToNew(String attribute) {
-        if (attribute.contains(LEFT)) {
-            return attribute.replace(LEFT, START);
-        } else {
-            return attribute.replace(RIGHT, END);
-        }
-    }
-
-    @VisibleForTesting
-    static String convertNewToOld(String attribute) {
-        if (attribute.contains(START)) {
-            return attribute.replace(START, LEFT);
-        } else {
-            return attribute.replace(END, RIGHT);
-        }
-    }
-
-    @VisibleForTesting
-    static String convertToOppositeDirection(String attribute) {
-        if (attribute.contains(LEFT)) {
-            return attribute.replace(LEFT, RIGHT);
-        } else if (attribute.contains(RIGHT)) {
-            return attribute.replace(RIGHT, LEFT);
-        } else if (attribute.contains(START)) {
-            return attribute.replace(START, END);
-        } else {
-            return attribute.replace(END, START);
-        }
-    }
-
-    @Nullable
-    static String getTextAlignmentToGravity(String attribute) {
-        if (attribute.endsWith(START)) { // textStart, viewStart, ...
-            return GRAVITY_VALUE_START;
-        } else if (attribute.endsWith(END)) { // textEnd, viewEnd, ...
-            return GRAVITY_VALUE_END;
-        } else {
-            return null; // inherit, others
-        }
-    }
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        int size = ATTRIBUTES.length + 4;
-        List<String> attributes = new ArrayList<String>(size);
-
-        // For detecting whether RTL support is enabled
-        attributes.add(ATTR_SUPPORTS_RTL);
-
-        // For detecting left/right attributes which should probably be
-        // migrated to start/end
-        attributes.add(ATTR_GRAVITY);
-        attributes.add(ATTR_LAYOUT_GRAVITY);
-
-        // For detecting existing attributes which indicate an attempt to
-        // use RTL
-        attributes.add(ATTR_TEXT_ALIGNMENT);
-
-        // Add conversion attributes: left/right attributes to nominate
-        // attributes that should be added as start/end, and start/end
-        // attributes to use to look up elements that should have compatibility
-        // left/right ones as well
-        Collections.addAll(attributes, ATTRIBUTES);
-
-        assert attributes.size() == size : attributes.size();
-
-        return attributes;
-    }
-
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        Project project = context.getMainProject();
-        String value = attribute.getValue();
-
-        if (!ANDROID_URI.equals(attribute.getNamespaceURI())) {
-            // Layout attribute not in the Android namespace (or a custom namespace).
-            // This is likely an application error (which should get caught by
-            // the MissingPrefixDetector)
-            return;
-        }
-
-        String name = attribute.getLocalName();
-        assert name != null : attribute.getName();
-
-        if (name.equals(ATTR_SUPPORTS_RTL)) {
-            mEnabledRtlSupport = Boolean.valueOf(value);
-            if (!attribute.getOwnerElement().getTagName().equals(TAG_APPLICATION)) {
-                context.report(ENABLED, attribute, context.getLocation(attribute), String.format(
-                    "Wrong declaration: `%1$s` should be defined on the `<application>` element",
-                        attribute.getName()));
-            }
-            int targetSdk = project.getTargetSdk();
-            if (mEnabledRtlSupport && targetSdk < RTL_API) {
-                String message = String.format(
-                        "You must set `android:targetSdkVersion` to at least %1$d when "
-                                + "enabling RTL support (is %2$d)",
-                                RTL_API, project.getTargetSdk());
-                context.report(ENABLED, attribute, context.getValueLocation(attribute), message);
-            }
-            return;
-        }
-
-        if (!rtlApplies(context)) {
-            return;
-        }
-
-        if (name.equals(ATTR_TEXT_ALIGNMENT)) {
-            if (context.getProject().getReportIssues()) {
-              mUsesRtlAttributes = true;
-            }
-
-            Element element = attribute.getOwnerElement();
-            final String gravity;
-            final Attr gravityNode;
-            if (element.hasAttributeNS(ANDROID_URI, ATTR_GRAVITY)) {
-                gravityNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_GRAVITY);
-                gravity = gravityNode.getValue();
-            } else if (element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY)) {
-                gravityNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY);
-                gravity = gravityNode.getValue();
-            } else if (project.getMinSdk() < RTL_API) {
-                int folderVersion = context.getFolderVersion();
-                if (folderVersion < RTL_API && context.isEnabled(COMPAT)) {
-                    String expectedGravity = getTextAlignmentToGravity(value);
-                    if (expectedGravity != null) {
-                        String message = String.format(
-                                "To support older versions than API 17 (project specifies %1$d) "
-                                    + "you must *also* specify `gravity` or `layout_gravity=\"%2$s\"`",
-                                project.getMinSdk(), expectedGravity);
-                        context.report(COMPAT, attribute,
-                                context.getNameLocation(attribute), message);
-                    }
-                }
-                return;
-            } else {
-                return;
-            }
-
-            String expectedGravity = getTextAlignmentToGravity(value);
-            if (expectedGravity != null && !gravity.contains(expectedGravity)
-                    && context.isEnabled(COMPAT)) {
-                String message = String.format("Inconsistent alignment specification between "
-                                + "`textAlignment` and `gravity` attributes: was `%1$s`, expected `%2$s`",
-                        gravity, expectedGravity);
-                Location location = context.getValueLocation(attribute);
-                context.report(COMPAT, attribute, location, message);
-                Location secondary = context.getValueLocation(gravityNode);
-                secondary.setMessage("Incompatible direction here");
-                location.setSecondary(secondary);
-            }
-            return;
-        }
-
-        if (name.equals(ATTR_GRAVITY) || name.equals(ATTR_LAYOUT_GRAVITY)) {
-            boolean isLeft = value.contains(GRAVITY_VALUE_LEFT);
-            boolean isRight = value.contains(GRAVITY_VALUE_RIGHT);
-            if (!isLeft && !isRight) {
-                if ((value.contains(GRAVITY_VALUE_START) || value.contains(GRAVITY_VALUE_END))
-                        && context.getProject().getReportIssues()) {
-                    mUsesRtlAttributes = true;
-                }
-                return;
-            }
-            String message = String.format(
-                    "Use \"`%1$s`\" instead of \"`%2$s`\" to ensure correct behavior in "
-                            + "right-to-left locales",
-                    isLeft ? GRAVITY_VALUE_START : GRAVITY_VALUE_END,
-                    isLeft ? GRAVITY_VALUE_LEFT : GRAVITY_VALUE_RIGHT);
-            if (context.isEnabled(USE_START)) {
-                context.report(USE_START, attribute, context.getValueLocation(attribute), message);
-            }
-
-            return;
-        }
-
-        // Some other left/right/start/end attribute
-        int targetSdk = project.getTargetSdk();
-
-        // TODO: If attribute is drawableLeft or drawableRight, add note that you might
-        // want to consider adding a specialized image in the -ldrtl folder as well
-
-        Element element = attribute.getOwnerElement();
-        boolean isPaddingAttribute = isPaddingAttribute(name);
-        if (isPaddingAttribute || isMarginAttribute(name)) {
-            String opposite = convertToOppositeDirection(name);
-            if (element.hasAttributeNS(ANDROID_URI, opposite)) {
-                String oldValue = element.getAttributeNS(ANDROID_URI, opposite);
-                if (value.equals(oldValue)) {
-                    return;
-                }
-            } else if (isPaddingAttribute
-                    && !element.hasAttributeNS(ANDROID_URI,
-                    isOldAttribute(opposite) ? convertOldToNew(opposite)
-                            : convertNewToOld(opposite)) && context.isEnabled(SYMMETRY)) {
-                String message = String.format(
-                        "When you define `%1$s` you should probably also define `%2$s` for "
-                        + "right-to-left symmetry", name, opposite);
-                context.report(SYMMETRY, attribute, context.getNameLocation(attribute), message);
-            }
-        }
-
-        boolean isOld = isOldAttribute(name);
-        if (isOld) {
-            if (!context.isEnabled(USE_START)) {
-                return;
-            }
-            String rtl = convertOldToNew(name);
-            if (element.hasAttributeNS(ANDROID_URI, rtl)) {
-                if (project.getMinSdk() >= RTL_API || context.getFolderVersion() >= RTL_API) {
-                    // Warn that left/right isn't needed
-                    String message = String.format(
-                            "Redundant attribute `%1$s`; already defining `%2$s` with "
-                                    + "`targetSdkVersion` %3$s",
-                            name, rtl, targetSdk);
-                    context.report(USE_START, attribute,
-                            context.getNameLocation(attribute), message);
-                }
-            } else {
-                String message;
-                if (project.getMinSdk() >= RTL_API || context.getFolderVersion() >= RTL_API) {
-                    message = String.format(
-                            "Consider replacing `%1$s` with `%2$s:%3$s=\"%4$s\"` to better support "
-                                    + "right-to-left layouts",
-                            attribute.getName(), attribute.getPrefix(), rtl, value);
-                } else {
-                    message = String.format(
-                            "Consider adding `%1$s:%2$s=\"%3$s\"` to better support "
-                                    + "right-to-left layouts",
-                            attribute.getPrefix(), rtl, value);
-                }
-                context.report(USE_START, attribute,
-                        context.getNameLocation(attribute), message);
-            }
-        } else {
-            if (project.getMinSdk() >= RTL_API || !context.isEnabled(COMPAT)) {
-                // Only supporting 17+: no need to define older attributes
-                return;
-            }
-            int folderVersion = context.getFolderVersion();
-            if (folderVersion >= RTL_API) {
-                // In a -v17 folder or higher: no need to define older attributes
-                return;
-            }
-            String old = convertNewToOld(name);
-            if (element.hasAttributeNS(ANDROID_URI, old)) {
-                return;
-            }
-            String message = String.format(
-                    "To support older versions than API 17 (project specifies %1$d) "
-                            + "you should *also* add `%2$s:%3$s=\"%4$s\"`",
-                    project.getMinSdk(), attribute.getPrefix(), old,
-                    convertNewToOld(value));
-            context.report(COMPAT, attribute, context.getNameLocation(attribute), message);
-        }
-    }
-
-    private static boolean isOldAttribute(String name) {
-        return name.contains(LEFT) || name.contains(RIGHT);
-    }
-
-    private static boolean isMarginAttribute(@NonNull String name) {
-        return name.startsWith(ATTR_LAYOUT_MARGIN);
-    }
-
-    private static boolean isPaddingAttribute(@NonNull String name) {
-        return name.startsWith(ATTR_PADDING);
-    }
-
-    // ---- Implements UastScanner ----
-
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(USimpleNameReferenceExpression.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        if (rtlApplies(context)) {
-            return new IdentifierChecker(context);
-        }
-
-        return null;
-    }
-
-    private static class IdentifierChecker extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        public IdentifierChecker(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            String identifier = node.getIdentifier();
-            boolean isLeft = LEFT_FIELD.equals(identifier);
-            boolean isRight = RIGHT_FIELD.equals(identifier);
-            if (!isLeft && !isRight) {
-                return super.visitSimpleNameReferenceExpression(node);
-            }
-
-            PsiElement resolved = node.resolve();
-            if (!(resolved instanceof PsiField)) {
-                return super.visitSimpleNameReferenceExpression(node);
-            } else {
-                PsiField field = (PsiField) resolved;
-                if (!JavaEvaluator.isMemberInClass(field, FQCN_GRAVITY)) {
-                    return super.visitSimpleNameReferenceExpression(node);
-                }
-            }
-
-            String message = String.format(
-                    "Use \"`Gravity.%1$s`\" instead of \"`Gravity.%2$s`\" to ensure correct "
-                            + "behavior in right-to-left locales",
-                    (isLeft ? GRAVITY_VALUE_START : GRAVITY_VALUE_END).toUpperCase(Locale.US),
-                    (isLeft ? GRAVITY_VALUE_LEFT : GRAVITY_VALUE_RIGHT).toUpperCase(Locale.US));
-            
-            Location location = mContext.getUastLocation(node);
-            mContext.report(USE_START, node, location, message);
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SQLiteDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SQLiteDetector.java
deleted file mode 100644
index c75dbc0..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SQLiteDetector.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Detector which looks for problems related to SQLite usage
- */
-public class SQLiteDetector extends Detector implements Detector.UastScanner {
-    private static final Implementation IMPLEMENTATION = new Implementation(
-          SQLiteDetector.class, Scope.JAVA_FILE_SCOPE);
-
-    /** Using STRING instead of TEXT for columns */
-    public static final Issue ISSUE = Issue.create(
-            "SQLiteString", //$NON-NLS-1$
-            "Using STRING instead of TEXT",
-
-            "In SQLite, any column can store any data type; the declared type for a column " +
-            "is more of a hint as to what the data should be cast to when stored.\n" +
-            "\n" +
-            "There are many ways to store a string. `TEXT`, `VARCHAR`, `CHARACTER` and `CLOB` " +
-            "are string types, *but `STRING` is not*. Columns defined as STRING are actually " +
-            "numeric.\n" +
-            "\n" +
-            "If you try to store a value in a numeric column, SQLite will try to cast it to a " +
-            "float or an integer before storing. If it can't, it will just store it as a " +
-            "string.\n" +
-            "\n" +
-            "This can lead to some subtle bugs. For example, when SQLite encounters a string " +
-            "like `1234567e1234`, it will parse it as a float, but the result will be out of " +
-            "range for floating point numbers, so `Inf` will be stored! Similarly, strings " +
-            "that look like integers will lose leading zeroes.\n" +
-            "\n" +
-            "To fix this, you can change your schema to use a `TEXT` type instead.",
-
-            Category.CORRECTNESS,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo("https://www.sqlite.org/datatype3.html"); //$NON-NLS-1$
-
-    // ---- Implements Detector.JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("execSQL"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod uMethod) {
-        PsiMethod method = uMethod.getPsi();
-        JavaEvaluator evaluator = context.getEvaluator();
-        
-        if (!JavaEvaluator.isMemberInClass(method, "android.database.sqlite.SQLiteDatabase")) {
-            return;
-        }
-
-        int parameterCount = evaluator.getParameterCount(method);
-        if (parameterCount == 0) {
-            return;
-        }
-        if (!evaluator.parameterHasType(method, 0, TYPE_STRING)) {
-            return;
-        }
-        // Try to resolve the String and look for STRING keys
-        UExpression argument = call.getValueArguments().get(0);
-        String sql = ConstantEvaluator.evaluateString(context, argument, true);
-        if (sql != null && (sql.startsWith("CREATE TABLE") || sql.startsWith("ALTER TABLE"))
-                && sql.matches(".*\\bSTRING\\b.*")) {
-            String message = "Using column type STRING; did you mean to use TEXT? "
-                    + "(STRING is a numeric type and its value can be adjusted; for example, "
-                    + "strings that look like integers can drop leading zeroes. See issue "
-                    + "explanation for details.)";
-            context.report(ISSUE, call, context.getUastLocation(call), message);
-        }
-
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java
deleted file mode 100644
index 1eaf45a..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.UastLiteralUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for hardcoded references to /sdcard/.
- */
-public class SdCardDetector extends Detector implements Detector.UastScanner {
-    /** Hardcoded /sdcard/ references */
-    public static final Issue ISSUE = Issue.create(
-            "SdCardPath", //$NON-NLS-1$
-            "Hardcoded reference to `/sdcard`",
-
-            "Your code should not reference the `/sdcard` path directly; instead use " +
-            "`Environment.getExternalStorageDirectory().getPath()`.\n" +
-            "\n" +
-            "Similarly, do not reference the `/data/data/` path directly; it can vary " +
-            "in multi-user scenarios. Instead, use " +
-            "`Context.getFilesDir().getPath()`.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    SdCardDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo(
-            "http://developer.android.com/guide/topics/data/data-storage.html#filesExternal"); //$NON-NLS-1$
-
-    /** Constructs a new {@link SdCardDetector} check */
-    public SdCardDetector() {
-    }
-
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(ULiteralExpression.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new StringChecker(context);
-    }
-
-    private static class StringChecker extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private StringChecker(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitClass(@NotNull UClass node) {
-            return super.visitClass(node);
-        }
-
-        @Override
-        public boolean visitLiteralExpression(ULiteralExpression node) {
-            String s = UastLiteralUtils.getValueIfStringLiteral(node);
-            if (s != null && !s.isEmpty()) {
-                char c = s.charAt(0);
-                if (c != '/' && c != 'f') {
-                    return false;
-                }
-
-                if (s.startsWith("/sdcard")                        //$NON-NLS-1$
-                        || s.startsWith("/mnt/sdcard/")            //$NON-NLS-1$
-                        || s.startsWith("/system/media/sdcard")    //$NON-NLS-1$
-                        || s.startsWith("file://sdcard/")          //$NON-NLS-1$
-                        || s.startsWith("file:///sdcard/")) {      //$NON-NLS-1$
-                    String message = "Do not hardcode \"/sdcard/\"; " +
-                            "use `Environment.getExternalStorageDirectory().getPath()` instead";
-                    Location location = mContext.getUastLocation(node);
-                    mContext.report(ISSUE, node, location, message);
-                } else if (s.startsWith("/data/data/")    //$NON-NLS-1$
-                        || s.startsWith("/data/user/")) { //$NON-NLS-1$
-                    String message = "Do not hardcode \"`/data/`\"; " +
-                            "use `Context.getFilesDir().getPath()` instead";
-                    Location location = mContext.getUastLocation(node);
-                    mContext.report(ISSUE, node, location, message);
-                }
-            }
-            
-            return super.visitLiteralExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecureRandomDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecureRandomDetector.java
deleted file mode 100644
index 63410a1..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecureRandomDetector.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TypeEvaluator;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for hardcoded seeds with random numbers.
- */
-public class SecureRandomDetector extends Detector implements Detector.UastScanner {
-    /** Unregistered activities and services */
-    public static final Issue ISSUE = Issue.create(
-            "SecureRandom", //$NON-NLS-1$
-            "Using a fixed seed with `SecureRandom`",
-
-            "Specifying a fixed seed will cause the instance to return a predictable sequence " +
-            "of numbers. This may be useful for testing but it is not appropriate for secure use.",
-
-            Category.SECURITY,
-            9,
-            Severity.WARNING,
-            new Implementation(
-                    SecureRandomDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo("http://developer.android.com/reference/java/security/SecureRandom.html");
-
-    private static final String SET_SEED = "setSeed"; //$NON-NLS-1$
-    public static final String JAVA_SECURITY_SECURE_RANDOM = "java.security.SecureRandom";
-    public static final String JAVA_UTIL_RANDOM = "java.util.Random";
-
-    /** Constructs a new {@link SecureRandomDetector} */
-    public SecureRandomDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(SET_SEED);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.isEmpty()) {
-            return;
-        }
-        UExpression seedArgument = arguments.get(0);
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (JavaEvaluator.isMemberInClass(method, JAVA_SECURITY_SECURE_RANDOM)
-                || evaluator.isMemberInSubClassOf(method, JAVA_UTIL_RANDOM, false)
-                && isSecureRandomReceiver(context, call)) {
-            // Called with a fixed seed?
-            Object seed = ConstantEvaluator.evaluate(context, seedArgument);
-            //noinspection VariableNotUsedInsideIf
-            if (seed != null) {
-                context.report(ISSUE, call, context.getUastLocation(call),
-                        "Do not call `setSeed()` on a `SecureRandom` with a fixed seed: " +
-                                "it is not secure. Use `getSeed()`.");
-            } else {
-                // Called with a simple System.currentTimeMillis() seed or something like that?
-                PsiElement resolvedArgument = UastUtils.tryResolve(seedArgument);
-                if (resolvedArgument instanceof PsiMethod) {
-                    PsiMethod seedMethod = (PsiMethod) resolvedArgument;
-                    String methodName = seedMethod.getName();
-                    if (methodName.equals("currentTimeMillis")
-                            || methodName.equals("nanoTime")) {
-                        context.report(ISSUE, call, context.getUastLocation(call),
-                                "It is dangerous to seed `SecureRandom` with the current "
-                                        + "time because that value is more predictable to "
-                                        + "an attacker than the default seed.");
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if the given invocation is assigned a SecureRandom type
-     */
-    private static boolean isSecureRandomReceiver(
-            @NonNull JavaContext context,
-            @NonNull UCallExpression call) {
-        UElement operand = call.getReceiver();
-        return operand != null && isSecureRandomType(context, operand);
-    }
-
-    /**
-     * Returns true if the node evaluates to an instance of type SecureRandom
-     */
-    private static boolean isSecureRandomType(
-            @NonNull JavaContext context,
-            @NonNull UElement node) {
-        PsiType type = TypeEvaluator.evaluate(context, node);
-        return type != null && JAVA_SECURITY_SECURE_RANDOM.equals(type.getCanonicalText());
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java
deleted file mode 100644
index 00a6647..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_EXPORTED;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_PATH;
-import static com.android.SdkConstants.ATTR_PATH_PATTERN;
-import static com.android.SdkConstants.ATTR_PATH_PREFIX;
-import static com.android.SdkConstants.ATTR_PERMISSION;
-import static com.android.SdkConstants.ATTR_READ_PERMISSION;
-import static com.android.SdkConstants.ATTR_WRITE_PERMISSION;
-import static com.android.SdkConstants.TAG_ACTIVITY;
-import static com.android.SdkConstants.TAG_APPLICATION;
-import static com.android.SdkConstants.TAG_GRANT_PERMISSION;
-import static com.android.SdkConstants.TAG_INTENT_FILTER;
-import static com.android.SdkConstants.TAG_PATH_PERMISSION;
-import static com.android.SdkConstants.TAG_PROVIDER;
-import static com.android.SdkConstants.TAG_RECEIVER;
-import static com.android.SdkConstants.TAG_SERVICE;
-import static com.android.xml.AndroidManifest.NODE_ACTION;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.USimpleNameReferenceExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Checks that exported services request a permission.
- */
-public class SecurityDetector extends Detector implements XmlScanner, Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION_MANIFEST = new Implementation(
-            SecurityDetector.class,
-            Scope.MANIFEST_SCOPE);
-
-    private static final Implementation IMPLEMENTATION_JAVA = new Implementation(
-            SecurityDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Exported services */
-    public static final Issue EXPORTED_SERVICE = Issue.create(
-            "ExportedService", //$NON-NLS-1$
-            "Exported service does not require permission",
-            "Exported services (services which either set `exported=true` or contain " +
-            "an intent-filter and do not specify `exported=false`) should define a " +
-            "permission that an entity must have in order to launch the service " +
-            "or bind to it. Without this, any application can use this service.",
-            Category.SECURITY,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_MANIFEST);
-
-    /** Exported content providers */
-    public static final Issue EXPORTED_PROVIDER = Issue.create(
-            "ExportedContentProvider", //$NON-NLS-1$
-            "Content provider does not require permission",
-            "Content providers are exported by default and any application on the " +
-            "system can potentially use them to read and write data. If the content " +
-            "provider provides access to sensitive data, it should be protected by " +
-            "specifying `export=false` in the manifest or by protecting it with a " +
-            "permission that can be granted to other applications.",
-            Category.SECURITY,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_MANIFEST);
-
-    /** Exported receivers */
-    public static final Issue EXPORTED_RECEIVER = Issue.create(
-            "ExportedReceiver", //$NON-NLS-1$
-            "Receiver does not require permission",
-            "Exported receivers (receivers which either set `exported=true` or contain " +
-            "an intent-filter and do not specify `exported=false`) should define a " +
-            "permission that an entity must have in order to launch the receiver " +
-            "or bind to it. Without this, any application can use this receiver.",
-            Category.SECURITY,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_MANIFEST);
-
-    /** Content provides which grant all URIs access */
-    public static final Issue OPEN_PROVIDER = Issue.create(
-            "GrantAllUris", //$NON-NLS-1$
-            "Content provider shares everything",
-            "The `<grant-uri-permission>` element allows specific paths to be shared. " +
-            "This detector checks for a path URL of just '/' (everything), which is " +
-            "probably not what you want; you should limit access to a subset.",
-            Category.SECURITY,
-            7,
-            Severity.WARNING,
-            IMPLEMENTATION_MANIFEST);
-
-    /** Using java.io.File.setReadable(true, false) to set file world-readable */
-    public static final Issue SET_READABLE = Issue.create(
-            "SetWorldReadable",
-            "`File.setReadable()` used to make file world-readable",
-            "Setting files world-readable is very dangerous, and likely to cause security " +
-            "holes in applications. It is strongly discouraged; instead, applications should " +
-            "use more formal mechanisms for interactions such as `ContentProvider`, " +
-            "`BroadcastReceiver`, and `Service`.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-    /** Using java.io.File.setWritable(true, false) to set file world-writable */
-    public static final Issue SET_WRITABLE = Issue.create(
-            "SetWorldWritable",
-            "`File.setWritable()` used to make file world-writable",
-            "Setting files world-writable is very dangerous, and likely to cause security " +
-            "holes in applications. It is strongly discouraged; instead, applications should " +
-            "use more formal mechanisms for interactions such as `ContentProvider`, " +
-            "`BroadcastReceiver`, and `Service`.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-    /** Using the world-writable flag */
-    public static final Issue WORLD_WRITEABLE = Issue.create(
-            "WorldWriteableFiles", //$NON-NLS-1$
-            "`openFileOutput()` or similar call passing `MODE_WORLD_WRITEABLE`",
-            "There are cases where it is appropriate for an application to write " +
-            "world writeable files, but these should be reviewed carefully to " +
-            "ensure that they contain no private data, and that if the file is " +
-            "modified by a malicious application it does not trick or compromise " +
-            "your application.",
-            Category.SECURITY,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-
-    /** Using the world-readable flag */
-    public static final Issue WORLD_READABLE = Issue.create(
-            "WorldReadableFiles", //$NON-NLS-1$
-            "`openFileOutput()` or similar call passing `MODE_WORLD_READABLE`",
-            "There are cases where it is appropriate for an application to write " +
-            "world readable files, but these should be reviewed carefully to " +
-            "ensure that they contain no private data that is leaked to other " +
-            "applications.",
-            Category.SECURITY,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-    private static final String FILE_CLASS = "java.io.File"; //$NON-NLS-1$
-
-    /** Constructs a new {@link SecurityDetector} check */
-    public SecurityDetector() {
-    }
-
-    // ---- Implements Detector.XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Arrays.asList(
-            TAG_SERVICE,
-            TAG_GRANT_PERMISSION,
-            TAG_PROVIDER,
-            TAG_ACTIVITY,
-            TAG_RECEIVER
-        );
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        String tag = element.getTagName();
-        if (tag.equals(TAG_SERVICE)) {
-            checkService(context, element);
-        } else if (tag.equals(TAG_GRANT_PERMISSION)) {
-            checkGrantPermission(context, element);
-        } else if (tag.equals(TAG_PROVIDER)) {
-            checkProvider(context, element);
-        } else if (tag.equals(TAG_RECEIVER)) {
-            checkReceiver(context, element);
-        }
-    }
-
-    public static boolean getExported(Element element) {
-        // Used to check whether an activity, service or broadcast receiver is exported.
-        String exportValue = element.getAttributeNS(ANDROID_URI, ATTR_EXPORTED);
-        if (exportValue != null && !exportValue.isEmpty()) {
-            return Boolean.valueOf(exportValue);
-        } else {
-            for (Element child : LintUtils.getChildren(element)) {
-                if (child.getTagName().equals(TAG_INTENT_FILTER)) {
-                    return true;
-                }
-            }
-        }
-
-      return false;
-    }
-
-    private static boolean isUnprotectedByPermission(Element element) {
-        // Used to check whether an activity, service or broadcast receiver are
-        // protected by a permission.
-        String permission = element.getAttributeNS(ANDROID_URI, ATTR_PERMISSION);
-        if (permission == null || permission.isEmpty()) {
-            Node parent = element.getParentNode();
-            if (parent.getNodeType() == Node.ELEMENT_NODE
-                    && parent.getNodeName().equals(TAG_APPLICATION)) {
-                Element application = (Element) parent;
-                permission = application.getAttributeNS(ANDROID_URI, ATTR_PERMISSION);
-                return permission == null || permission.isEmpty();
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isWearableBindListener(@NonNull Element element) {
-        // Checks whether a service has an Android Wear bind listener
-        for (Element child : LintUtils.getChildren(element)) {
-            if (child.getTagName().equals(TAG_INTENT_FILTER)) {
-                for (Element innerChild : LintUtils.getChildren(child)) {
-                    if (innerChild.getTagName().equals(NODE_ACTION)) {
-                        String name = innerChild.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                        if ("com.google.android.gms.wearable.BIND_LISTENER".equals(name)) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isStandardReceiver(Element element) {
-        // Play Services also the following receiver which we'll consider standard
-        // in the sense that it doesn't require a separate permission
-        String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-        if ("com.google.android.gms.tagmanager.InstallReferrerReceiver".equals(name)) {
-            return true;
-        }
-
-        // Checks whether a broadcast receiver receives a standard Android action
-        for (Element child : LintUtils.getChildren(element)) {
-            if (child.getTagName().equals(TAG_INTENT_FILTER)) {
-                for (Element innerChild : LintUtils.getChildren(child)) {
-                    if (innerChild.getTagName().equals(NODE_ACTION)) {
-                        String categoryString = innerChild.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                        return categoryString.startsWith("android."); //$NON-NLS-1$
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static void checkReceiver(XmlContext context, Element element) {
-        if (getExported(element) && isUnprotectedByPermission(element) &&
-                !isStandardReceiver(element)) {
-            // No declared permission for this exported receiver: complain
-            context.report(EXPORTED_RECEIVER, element, context.getLocation(element),
-                           "Exported receiver does not require permission");
-        }
-    }
-
-    private static void checkService(XmlContext context, Element element) {
-        if (getExported(element) && isUnprotectedByPermission(element)
-                && !isWearableBindListener(element)) {
-            // No declared permission for this exported service: complain
-            context.report(EXPORTED_SERVICE, element, context.getLocation(element),
-                           "Exported service does not require permission");
-        }
-    }
-
-    private static void checkGrantPermission(XmlContext context, Element element) {
-        Attr path = element.getAttributeNodeNS(ANDROID_URI, ATTR_PATH);
-        Attr prefix = element.getAttributeNodeNS(ANDROID_URI, ATTR_PATH_PREFIX);
-        Attr pattern = element.getAttributeNodeNS(ANDROID_URI, ATTR_PATH_PATTERN);
-
-        String msg = "Content provider shares everything; this is potentially dangerous.";
-        if (path != null && path.getValue().equals("/")) { //$NON-NLS-1$
-            context.report(OPEN_PROVIDER, path, context.getLocation(path), msg);
-        }
-        if (prefix != null && prefix.getValue().equals("/")) { //$NON-NLS-1$
-            context.report(OPEN_PROVIDER, prefix, context.getLocation(prefix), msg);
-        }
-        if (pattern != null && (pattern.getValue().equals("/")  //$NON-NLS-1$
-               /* || pattern.getValue().equals(".*")*/)) {
-            context.report(OPEN_PROVIDER, pattern, context.getLocation(pattern), msg);
-        }
-    }
-
-    private static void checkProvider(XmlContext context, Element element) {
-        String exportValue = element.getAttributeNS(ANDROID_URI, ATTR_EXPORTED);
-        // Content providers are exported by default
-        boolean exported = true;
-        if (exportValue != null && !exportValue.isEmpty()) {
-            exported = Boolean.valueOf(exportValue);
-        }
-
-        if (exported) {
-            // Just check for some use of permissions. Other Lint checks can check the saneness
-            // of the permissions. We'll accept the permission, readPermission, or writePermission
-            // attributes on the provider element, or a path-permission element.
-            String permission = element.getAttributeNS(ANDROID_URI, ATTR_READ_PERMISSION);
-            if (permission == null || permission.isEmpty()) {
-                permission = element.getAttributeNS(ANDROID_URI, ATTR_WRITE_PERMISSION);
-                if (permission == null || permission.isEmpty()) {
-                    permission = element.getAttributeNS(ANDROID_URI, ATTR_PERMISSION);
-                    if (permission == null || permission.isEmpty()) {
-                        // No permission attributes? Check for path-permission.
-
-                        // TODO: Add a Lint check to ensure the path-permission is good, similar to
-                        // the grant-uri-permission check.
-                        boolean hasPermission = false;
-                        for (Element child : LintUtils.getChildren(element)) {
-                            String tag = child.getTagName();
-                            if (tag.equals(TAG_PATH_PERMISSION)) {
-                                hasPermission = true;
-                                break;
-                            }
-                        }
-
-                        if (!hasPermission) {
-                            context.report(EXPORTED_PROVIDER, element,
-                                    context.getLocation(element),
-                                    "Exported content providers can provide access to " +
-                                            "potentially sensitive data");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // ---- Implements Detector.JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        // These are the API calls that can accept a MODE_WORLD_READABLE/MODE_WORLD_WRITEABLE
-        // argument.
-        List<String> values = new ArrayList<String>(3);
-        values.add("openFileOutput"); //$NON-NLS-1$
-        values.add("getSharedPreferences"); //$NON-NLS-1$
-        values.add("getDir"); //$NON-NLS-1$
-        // These API calls can be used to set files world-readable or world-writable
-        values.add("setReadable"); //$NON-NLS-1$
-        values.add("setWritable"); //$NON-NLS-1$
-        return values;
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        List<UExpression> args = node.getValueArguments();
-        String methodName = node.getMethodName();
-        if (context.getEvaluator().isMemberInSubClassOf(method, FILE_CLASS, false)) {
-            // Report calls to java.io.File.setReadable(true, false) or
-            // java.io.File.setWritable(true, false)
-            if ("setReadable".equals(methodName)) {
-                if (args.size() == 2 &&
-                        Boolean.TRUE.equals(ConstantEvaluator.evaluate(context, args.get(0))) &&
-                        Boolean.FALSE.equals(ConstantEvaluator.evaluate(context, args.get(1)))) {
-                    context.report(SET_READABLE, node, context.getUastLocation(node),
-                            "Setting file permissions to world-readable can be " +
-                                    "risky, review carefully");
-                }
-                return;
-            } else if ("setWritable".equals(methodName)) {
-                if (args.size() == 2 &&
-                        Boolean.TRUE.equals(ConstantEvaluator.evaluate(context, args.get(0))) &&
-                        Boolean.FALSE.equals(ConstantEvaluator.evaluate(context, args.get(1)))) {
-                    context.report(SET_WRITABLE, node, context.getUastLocation(node),
-                            "Setting file permissions to world-writable can be " +
-                                    "risky, review carefully");
-                }
-                return;
-            }
-        }
-
-        assert visitor != null;
-        for (UExpression arg : args) {
-            arg.accept(visitor);
-        }
-
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new IdentifierVisitor(context);
-    }
-
-    private static class IdentifierVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private IdentifierVisitor(JavaContext context) {
-            super();
-            mContext = context;
-        }
-        
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            String name = node.getIdentifier();
-
-            if ("MODE_WORLD_WRITEABLE".equals(name)) { //$NON-NLS-1$
-                Location location = mContext.getUastLocation(node);
-                mContext.report(WORLD_WRITEABLE, node, location,
-                        "Using `MODE_WORLD_WRITEABLE` when creating files can be " +
-                                "risky, review carefully");
-            } else if ("MODE_WORLD_READABLE".equals(name)) { //$NON-NLS-1$
-                Location location = mContext.getUastLocation(node);
-                mContext.report(WORLD_READABLE, node, location,
-                        "Using `MODE_WORLD_READABLE` when creating files can be " +
-                                "risky, review carefully");
-            }
-
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ServiceCastDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ServiceCastDetector.java
deleted file mode 100644
index a96c171..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ServiceCastDetector.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2013 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.collect.Maps;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
-
-import org.jetbrains.uast.UBinaryExpressionWithType;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Detector looking for casts on th result of context.getSystemService which are suspect
- */
-public class ServiceCastDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "ServiceCast", //$NON-NLS-1$
-            "Wrong system service casts",
-
-            "When you call `Context#getSystemService()`, the result is typically cast to " +
-            "a specific interface. This lint check ensures that the cast is compatible with " +
-            "the expected type of the return value.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.FATAL,
-            new Implementation(
-                    ServiceCastDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link ServiceCastDetector} check */
-    public ServiceCastDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("getSystemService"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        UElement parent = LintUtils.skipParentheses(
-                UastUtils.getQualifiedParentOrThis(call).getUastParent());
-        if (UastExpressionUtils.isTypeCast(parent)) {
-            UBinaryExpressionWithType cast = (UBinaryExpressionWithType) parent;
-
-            List<UExpression> args = call.getValueArguments();
-            if (args.size() == 1 && args.get(0) instanceof UReferenceExpression) {
-                PsiElement resolvedServiceConst = ((UReferenceExpression) args.get(0)).resolve();
-                if (!(resolvedServiceConst instanceof PsiField)) {
-                    return;
-                }
-                String name = ((PsiField) resolvedServiceConst).getName();
-                String expectedClass = getExpectedType(name);
-                if (expectedClass != null && cast != null) {
-                    String castType = cast.getType().getCanonicalText();
-                    if (castType.indexOf('.') == -1) {
-                        expectedClass = stripPackage(expectedClass);
-                    }
-                    if (!castType.equals(expectedClass)) {
-                        // It's okay to mix and match
-                        // android.content.ClipboardManager and android.text.ClipboardManager
-                        if (isClipboard(castType) && isClipboard(expectedClass)) {
-                            return;
-                        }
-
-                        String message = String.format(
-                                "Suspicious cast to `%1$s` for a `%2$s`: expected `%3$s`",
-                                stripPackage(castType), name, stripPackage(expectedClass));
-                        context.report(ISSUE, call, context.getUastLocation(cast), message);
-                    }
-                }
-
-            }
-        }
-    }
-
-    private static boolean isClipboard(String cls) {
-        return cls.equals("android.content.ClipboardManager")      //$NON-NLS-1$
-                || cls.equals("android.text.ClipboardManager");    //$NON-NLS-1$
-    }
-
-    private static String stripPackage(String fqcn) {
-        int index = fqcn.lastIndexOf('.');
-        if (index != -1) {
-            fqcn = fqcn.substring(index + 1);
-        }
-
-        return fqcn;
-    }
-
-    @Nullable
-    private static String getExpectedType(@Nullable String value) {
-        return value != null ? getServiceMap().get(value) : null;
-    }
-
-    @NonNull
-    private static Map<String, String> getServiceMap() {
-        if (sServiceMap == null) {
-            final int EXPECTED_SIZE = 55;
-            sServiceMap = Maps.newHashMapWithExpectedSize(EXPECTED_SIZE);
-
-            sServiceMap.put("ACCESSIBILITY_SERVICE", "android.view.accessibility.AccessibilityManager");
-            sServiceMap.put("ACCOUNT_SERVICE", "android.accounts.AccountManager");
-            sServiceMap.put("ACTIVITY_SERVICE", "android.app.ActivityManager");
-            sServiceMap.put("ALARM_SERVICE", "android.app.AlarmManager");
-            sServiceMap.put("APPWIDGET_SERVICE", "android.appwidget.AppWidgetManager");
-            sServiceMap.put("APP_OPS_SERVICE", "android.app.AppOpsManager");
-            sServiceMap.put("AUDIO_SERVICE", "android.media.AudioManager");
-            sServiceMap.put("BATTERY_SERVICE", "android.os.BatteryManager");
-            sServiceMap.put("BLUETOOTH_SERVICE", "android.bluetooth.BluetoothManager");
-            sServiceMap.put("CAMERA_SERVICE", "android.hardware.camera2.CameraManager");
-            sServiceMap.put("CAPTIONING_SERVICE", "android.view.accessibility.CaptioningManager");
-            sServiceMap.put("CARRIER_CONFIG_SERVICE", "android.telephony.CarrierConfigManager");
-            sServiceMap.put("CLIPBOARD_SERVICE", "android.text.ClipboardManager"); // also allow @Deprecated android.content.ClipboardManager
-            sServiceMap.put("CONNECTIVITY_SERVICE", "android.net.ConnectivityManager");
-            sServiceMap.put("CONSUMER_IR_SERVICE", "android.hardware.ConsumerIrManager");
-            sServiceMap.put("DEVICE_POLICY_SERVICE", "android.app.admin.DevicePolicyManager");
-            sServiceMap.put("DISPLAY_SERVICE", "android.hardware.display.DisplayManager");
-            sServiceMap.put("DOWNLOAD_SERVICE", "android.app.DownloadManager");
-            sServiceMap.put("DROPBOX_SERVICE", "android.os.DropBoxManager");
-            sServiceMap.put("FINGERPRINT_SERVICE", "android.hardware.fingerprint.FingerprintManager");
-            sServiceMap.put("INPUT_METHOD_SERVICE", "android.view.inputmethod.InputMethodManager");
-            sServiceMap.put("INPUT_SERVICE", "android.hardware.input.InputManager");
-            sServiceMap.put("JOB_SCHEDULER_SERVICE", "android.app.job.JobScheduler");
-            sServiceMap.put("KEYGUARD_SERVICE", "android.app.KeyguardManager");
-            sServiceMap.put("LAUNCHER_APPS_SERVICE", "android.content.pm.LauncherApps");
-            sServiceMap.put("LAYOUT_INFLATER_SERVICE", "android.view.LayoutInflater");
-            sServiceMap.put("LOCATION_SERVICE", "android.location.LocationManager");
-            sServiceMap.put("MEDIA_PROJECTION_SERVICE", "android.media.projection.MediaProjectionManager");
-            sServiceMap.put("MEDIA_ROUTER_SERVICE", "android.media.MediaRouter");
-            sServiceMap.put("MEDIA_SESSION_SERVICE", "android.media.session.MediaSessionManager");
-            sServiceMap.put("MIDI_SERVICE", "android.media.midi.MidiManager");
-            sServiceMap.put("NETWORK_STATS_SERVICE", "android.app.usage.NetworkStatsManager");
-            sServiceMap.put("NFC_SERVICE", "android.nfc.NfcManager");
-            sServiceMap.put("NOTIFICATION_SERVICE", "android.app.NotificationManager");
-            sServiceMap.put("NSD_SERVICE", "android.net.nsd.NsdManager");
-            sServiceMap.put("POWER_SERVICE", "android.os.PowerManager");
-            sServiceMap.put("PRINT_SERVICE", "android.print.PrintManager");
-            sServiceMap.put("RESTRICTIONS_SERVICE", "android.content.RestrictionsManager");
-            sServiceMap.put("SEARCH_SERVICE", "android.app.SearchManager");
-            sServiceMap.put("SENSOR_SERVICE", "android.hardware.SensorManager");
-            sServiceMap.put("STORAGE_SERVICE", "android.os.storage.StorageManager");
-            sServiceMap.put("TELECOM_SERVICE", "android.telecom.TelecomManager");
-            sServiceMap.put("TELEPHONY_SERVICE", "android.telephony.TelephonyManager");
-            sServiceMap.put("TELEPHONY_SUBSCRIPTION_SERVICE", "android.telephony.SubscriptionManager");
-            sServiceMap.put("TEXT_SERVICES_MANAGER_SERVICE", "android.view.textservice.TextServicesManager");
-            sServiceMap.put("TV_INPUT_SERVICE", "android.media.tv.TvInputManager");
-            sServiceMap.put("UI_MODE_SERVICE", "android.app.UiModeManager");
-            sServiceMap.put("USAGE_STATS_SERVICE", "android.app.usage.UsageStatsManager");
-            sServiceMap.put("USB_SERVICE", "android.hardware.usb.UsbManager");
-            sServiceMap.put("USER_SERVICE", "android.os.UserManager");
-            sServiceMap.put("VIBRATOR_SERVICE", "android.os.Vibrator");
-            sServiceMap.put("WALLPAPER_SERVICE", "android.service.wallpaper.WallpaperService");
-            sServiceMap.put("WIFI_P2P_SERVICE", "android.net.wifi.p2p.WifiP2pManager");
-            sServiceMap.put("WIFI_SERVICE", "android.net.wifi.WifiManager");
-            sServiceMap.put("WINDOW_SERVICE", "android.view.WindowManager");
-
-            assert sServiceMap.size() == EXPECTED_SIZE : sServiceMap.size();
-        }
-
-        return sServiceMap;
-    }
-
-    private static Map<String, String> sServiceMap;
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetJavaScriptEnabledDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetJavaScriptEnabledDetector.java
deleted file mode 100644
index a73612b..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetJavaScriptEnabledDetector.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ConstantEvaluator;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for invocations of android.webkit.WebSettings.setJavaScriptEnabled.
- */
-public class SetJavaScriptEnabledDetector extends Detector implements Detector.UastScanner {
-    /** Invocations of setJavaScriptEnabled */
-    public static final Issue ISSUE = Issue.create("SetJavaScriptEnabled", //$NON-NLS-1$
-            "Using `setJavaScriptEnabled`",
-
-            "Your code should not invoke `setJavaScriptEnabled` if you are not sure that " +
-            "your app really requires JavaScript support.",
-
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    SetJavaScriptEnabledDetector.class,
-                    Scope.JAVA_FILE_SCOPE))
-            .addMoreInfo(
-            "http://developer.android.com/guide/practices/security.html"); //$NON-NLS-1$
-
-    /** Constructs a new {@link SetJavaScriptEnabledDetector} check */
-    public SetJavaScriptEnabledDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.size() == 1) {
-            Object constant = ConstantEvaluator.evaluate(context, arguments.get(0));
-            if (constant != null && !Boolean.FALSE.equals(constant)) {
-                context.report(ISSUE, call, context.getUastLocation(call),
-                        "Using `setJavaScriptEnabled` can introduce XSS vulnerabilities " +
-                                "into you application, review carefully.");
-            }
-        }
-    }
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("setJavaScriptEnabled");
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetTextDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetTextDetector.java
deleted file mode 100644
index cd141df..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SetTextDetector.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UBinaryExpression;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UQualifiedReferenceExpression;
-import org.jetbrains.uast.UastBinaryOperator;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for errors related to TextView#setText and internationalization
- */
-public class SetTextDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            SetTextDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Constructing SimpleDateFormat without an explicit locale */
-    public static final Issue SET_TEXT_I18N = Issue.create(
-            "SetTextI18n", //$NON-NLS-1$
-            "TextView Internationalization",
-
-            "When calling `TextView#setText`\n"  +
-            "* Never call `Number#toString()` to format numbers; it will not handle fraction " +
-            "separators and locale-specific digits properly. Consider using `String#format` " +
-            "with proper format specifications (`%d` or `%f`) instead.\n" +
-            "* Do not pass a string literal (e.g. \"Hello\") to display text. Hardcoded " +
-            "text can not be properly translated to other languages. Consider using Android " +
-            "resource strings instead.\n" +
-            "* Do not build messages by concatenating text chunks. Such messages can not be " +
-            "properly translated.",
-
-            Category.I18N,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo("http://developer.android.com/guide/topics/resources/localization.html");
-
-
-    private static final String METHOD_NAME = "setText";
-    private static final String TO_STRING_NAME = "toString";
-    private static final String CHAR_SEQUENCE_CLS = "java.lang.CharSequence";
-    private static final String NUMBER_CLS = "java.lang.Number";
-    private static final String TEXT_VIEW_CLS = "android.widget.TextView";
-
-    // Pattern to match string literal that require translation. These are those having word
-    // characters in it.
-    private static final String WORD_PATTERN = ".*\\w{2,}.*";
-
-    /** Constructs a new {@link SetTextDetector} */
-    public SetTextDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList(METHOD_NAME);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!evaluator.isMemberInSubClassOf(method, TEXT_VIEW_CLS, false)) {
-            return;
-        }
-        if (method.getParameterList().getParametersCount() > 0 &&
-                evaluator.parameterHasType(method, 0, CHAR_SEQUENCE_CLS)) {
-            checkNode(context, call.getValueArguments().get(0));
-        }
-    }
-
-    private static void checkNode(@NonNull JavaContext context, @Nullable UElement node) {
-        if (node instanceof ULiteralExpression) {
-            Object value = ((ULiteralExpression) node).getValue();
-            if (value instanceof String && value.toString().matches(WORD_PATTERN)) {
-                context.report(SET_TEXT_I18N, node, context.getUastLocation(node),
-                        "String literal in `setText` can not be translated. Use Android "
-                                + "resources instead.");
-            }
-        } else if (node instanceof UCallExpression) {
-            PsiMethod calledMethod = ((UCallExpression) node).resolve();
-            if (calledMethod != null && TO_STRING_NAME.equals(calledMethod.getName())) {
-                PsiClass containingClass = UastUtils.getContainingClass(calledMethod);
-                if (containingClass == null) {
-                    return;
-                }
-
-                PsiClass superClass = containingClass.getSuperClass();
-                if (superClass != null && NUMBER_CLS.equals(superClass.getQualifiedName())) {
-                    context.report(SET_TEXT_I18N, node, context.getUastLocation(node),
-                            "Number formatting does not take into account locale settings. " +
-                                    "Consider using `String.format` instead.");
-                }
-            }
-        } else if (node instanceof UQualifiedReferenceExpression) {
-            UQualifiedReferenceExpression expression = (UQualifiedReferenceExpression) node;
-            checkNode(context, expression.getReceiver());
-            checkNode(context, expression.getSelector());
-        } else if (node instanceof UBinaryExpression) {
-            UBinaryExpression expression = (UBinaryExpression) node;
-            if (expression.getOperator() == UastBinaryOperator.PLUS) {
-                context.report(SET_TEXT_I18N, node, context.getUastLocation(node),
-                        "Do not concatenate text displayed with `setText`. "
-                                + "Use resource string with placeholders.");
-            }
-            checkNode(context, expression.getLeftOperand());
-            checkNode(context, expression.getRightOperand());
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SslCertificateSocketFactoryDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SslCertificateSocketFactoryDetector.java
deleted file mode 100644
index da68b8c..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SslCertificateSocketFactoryDetector.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiType;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class SslCertificateSocketFactoryDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION_JAVA = new Implementation(
-            SslCertificateSocketFactoryDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue CREATE_SOCKET = Issue.create(
-            "SSLCertificateSocketFactoryCreateSocket", //$NON-NLS-1$
-            "Insecure call to `SSLCertificateSocketFactory.createSocket()`",
-            "When `SSLCertificateSocketFactory.createSocket()` is called with an `InetAddress` " +
-            "as the first parameter, TLS/SSL hostname verification is not performed, which " +
-            "could result in insecure network traffic caused by trusting arbitrary " +
-            "hostnames in TLS/SSL certificates presented by peers. In this case, developers " +
-            "must ensure that the `InetAddress` is explicitly verified against the certificate " +
-            "through other means, such as by calling " +
-            "`SSLCertificateSocketFactory.getDefaultHostnameVerifier() to get a " +
-            "`HostnameVerifier` and calling `HostnameVerifier.verify()`.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-    public static final Issue GET_INSECURE = Issue.create(
-            "SSLCertificateSocketFactoryGetInsecure", //$NON-NLS-1$
-            "Call to `SSLCertificateSocketFactory.getInsecure()`",
-            "The `SSLCertificateSocketFactory.getInsecure()` method returns " +
-            "an SSLSocketFactory with all TLS/SSL security checks disabled, which " +
-            "could result in insecure network traffic caused by trusting arbitrary " +
-            "TLS/SSL certificates presented by peers. This method should be " +
-            "avoided unless needed for a special circumstance such as " +
-            "debugging. Instead, `SSLCertificateSocketFactory.getDefault()` " +
-            "should be used.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION_JAVA);
-
-    private static final String INET_ADDRESS_CLASS =
-            "java.net.InetAddress";
-
-    private static final String SSL_CERTIFICATE_SOCKET_FACTORY_CLASS =
-            "android.net.SSLCertificateSocketFactory";
-
-    // ---- Implements JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        // Detect calls to potentially insecure SSLCertificateSocketFactory methods
-        return Arrays.asList("createSocket", "getInsecure");
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        if (context.getEvaluator().isMemberInSubClassOf(method,
-                SSL_CERTIFICATE_SOCKET_FACTORY_CLASS, false)) {
-            String methodName = method.getName();
-            if ("createSocket".equals(methodName)) {
-                List<UExpression> args = call.getValueArguments();
-                if (!args.isEmpty()) {
-                    PsiType type = args.get(0).getExpressionType();
-                    if (type != null
-                            && (INET_ADDRESS_CLASS.equals(type.getCanonicalText())
-                                || InheritanceUtil.isInheritor(((PsiClassType)type).resolve(), false,
-                                                                                       INET_ADDRESS_CLASS))) {
-                        context.report(CREATE_SOCKET, call, context.getUastLocation(call),
-                                "Use of `SSLCertificateSocketFactory.createSocket()` " +
-                                        "with an InetAddress parameter can cause insecure " +
-                                        "network traffic due to trusting arbitrary hostnames in " +
-                                        "TLS/SSL certificates presented by peers");
-                    }
-                }
-            } else if ("getInsecure".equals(methodName)) {
-                context.report(GET_INSECURE, call, context.getUastLocation(call),
-                        "Use of `SSLCertificateSocketFactory.getInsecure()` can cause " +
-                                "insecure network traffic due to trusting arbitrary TLS/SSL " +
-                                "certificates presented by peers");
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringAuthLeakDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringAuthLeakDetector.java
deleted file mode 100644
index 9a6e6ba..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringAuthLeakDetector.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.android.tools.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.Scope;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Detector that looks for leaked credentials in strings.
- */
-public class StringAuthLeakDetector extends Detector implements Detector.UastScanner {
-
-    /** Looks for hidden code */
-    public static final Issue AUTH_LEAK = Issue.create(
-            "AuthLeak", "Code might contain an auth leak",
-            "Strings in java apps can be discovered by decompiling apps, this lint check looks " +
-            "for code which looks like it may contain an url with a username and password",
-            Category.SECURITY, 6, Severity.WARNING,
-            new Implementation(StringAuthLeakDetector.class, Scope.JAVA_FILE_SCOPE));
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(ULiteralExpression.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new AuthLeakChecker(context);
-    }
-
-    private static class AuthLeakChecker extends AbstractUastVisitor {
-        private final static String LEGAL_CHARS = "([\\w_.!~*\'()%;&=+$,-]+)";      // From RFC 2396
-        private final static Pattern AUTH_REGEXP =
-                Pattern.compile("([\\w+.-]+)://" + LEGAL_CHARS + ':' + LEGAL_CHARS + '@' +
-                        LEGAL_CHARS);
-
-        private final JavaContext mContext;
-
-        private AuthLeakChecker(JavaContext context) {
-            mContext = context;
-        }
-        
-        @Override
-        public boolean visitLiteralExpression(ULiteralExpression node) {
-            if (node.getValue() instanceof String) {
-                Matcher matcher = AUTH_REGEXP.matcher((String)node.getValue());
-                if (matcher.find()) {
-                    String password = matcher.group(3);
-                    if (password == null || (password.startsWith("%") && password.endsWith("s"))) {
-                        return super.visitLiteralExpression(node);
-                    }
-                    Location location = mContext.getUastLocation(node);
-                    mContext.report(AUTH_LEAK, node, location, "Possible credential leak");
-                }
-            }
-            return super.visitLiteralExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java
deleted file mode 100644
index d2529c4..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.SdkConstants.CLASS_FRAGMENT;
-import static com.android.SdkConstants.CLASS_RESOURCES;
-import static com.android.SdkConstants.CLASS_V4_FRAGMENT;
-import static com.android.SdkConstants.DOT_JAVA;
-import static com.android.SdkConstants.FORMAT_METHOD;
-import static com.android.SdkConstants.GET_STRING_METHOD;
-import static com.android.SdkConstants.TAG_STRING;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_BOOLEAN_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_BYTE_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_CHARACTER_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_DOUBLE_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_FLOAT_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_INTEGER_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_LONG_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_OBJECT;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_SHORT_WRAPPER;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceUrl;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Location.Handle;
-import com.android.tools.klint.detector.api.Position;
-import com.android.tools.klint.detector.api.ResourceEvaluator;
-import com.android.tools.klint.detector.api.ResourceXmlDetector;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.android.utils.Pair;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameterList;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiVariable;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.ULiteralExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.UReferenceExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Check which looks for problems with formatting strings such as inconsistencies between
- * translations or between string declaration and string usage in Java.
- * <p>
- * TODO: Handle Resources.getQuantityString as well
- */
-public class StringFormatDetector extends ResourceXmlDetector implements Detector.UastScanner {
-    private static final Implementation IMPLEMENTATION_XML = new Implementation(
-            StringFormatDetector.class,
-            Scope.ALL_RESOURCES_SCOPE);
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION_XML_AND_JAVA = new Implementation(
-            StringFormatDetector.class,
-            EnumSet.of(Scope.ALL_RESOURCE_FILES, Scope.JAVA_FILE),
-            Scope.JAVA_FILE_SCOPE);
-
-
-    /** Whether formatting strings are invalid */
-    public static final Issue INVALID = Issue.create(
-            "StringFormatInvalid", //$NON-NLS-1$
-            "Invalid format string",
-
-            "If a string contains a '%' character, then the string may be a formatting string " +
-            "which will be passed to `String.format` from Java code to replace each '%' " +
-            "occurrence with specific values.\n" +
-            "\n" +
-            "This lint warning checks for two related problems:\n" +
-            "(1) Formatting strings that are invalid, meaning that `String.format` will throw " +
-            "exceptions at runtime when attempting to use the format string.\n" +
-            "(2) Strings containing '%' that are not formatting strings getting passed to " +
-            "a `String.format` call. In this case the '%' will need to be escaped as '%%'.\n" +
-            "\n" +
-            "NOTE: Not all Strings which look like formatting strings are intended for " +
-            "use by `String.format`; for example, they may contain date formats intended " +
-            "for `android.text.format.Time#format()`. Lint cannot always figure out that " +
-            "a String is a date format, so you may get false warnings in those scenarios. " +
-            "See the suppress help topic for information on how to suppress errors in " +
-            "that case.",
-
-            Category.MESSAGES,
-            9,
-            Severity.ERROR,
-            IMPLEMENTATION_XML);
-
-    /** Whether formatting argument types are consistent across translations */
-    public static final Issue ARG_COUNT = Issue.create(
-            "StringFormatCount", //$NON-NLS-1$
-            "Formatting argument types incomplete or inconsistent",
-
-            "When a formatted string takes arguments, it usually needs to reference the " +
-            "same arguments in all translations (or all arguments if there are no " +
-            "translations.\n" +
-            "\n" +
-            "There are cases where this is not the case, so this issue is a warning rather " +
-            "than an error by default. However, this usually happens when a language is not " +
-            "translated or updated correctly.",
-            Category.MESSAGES,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_XML);
-
-    /** Whether the string format supplied in a call to String.format matches the format string */
-    public static final Issue ARG_TYPES = Issue.create(
-            "StringFormatMatches", //$NON-NLS-1$
-            "`String.format` string doesn't match the XML format string",
-
-            "This lint check ensures the following:\n" +
-            "(1) If there are multiple translations of the format string, then all translations " +
-            "use the same type for the same numbered arguments\n" +
-            "(2) The usage of the format string in Java is consistent with the format string, " +
-            "meaning that the parameter types passed to String.format matches those in the " +
-            "format string.",
-            Category.MESSAGES,
-            9,
-            Severity.ERROR,
-            IMPLEMENTATION_XML_AND_JAVA);
-
-    /** This plural does not use the quantity value */
-    public static final Issue POTENTIAL_PLURAL = Issue.create(
-            "PluralsCandidate", //$NON-NLS-1$
-            "Potential Plurals",
-
-            "This lint check looks for potential errors in internationalization where you have " +
-            "translated a message which involves a quantity and it looks like other parts of " +
-            "the string may need grammatical changes.\n" +
-            "\n" +
-            "For example, rather than something like this:\n" +
-            "  <string name=\"try_again\">Try again in %d seconds.</string>\n" +
-            "you should be using a plural:\n" +
-            "   <plurals name=\"try_again\">\n" +
-            "        <item quantity=\"one\">Try again in %d second</item>\n" +
-            "        <item quantity=\"other\">Try again in %d seconds</item>\n" +
-            "    </plurals>\n" +
-            "This will ensure that in other languages the right set of translations are " +
-            "provided for the different quantity classes.\n" +
-            "\n" +
-            "(This check depends on some heuristics, so it may not accurately determine whether " +
-            "a string really should be a quantity. You can use tools:ignore to filter out false " +
-            "positives.",
-
-            Category.MESSAGES,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION_XML).addMoreInfo(
-            "http://developer.android.com/guide/topics/resources/string-resource.html#Plurals");
-
-    /**
-     * Map from a format string name to a list of declaration file and actual
-     * formatting string content. We're using a list since a format string can be
-     * defined multiple times, usually for different translations.
-     */
-    private Map<String, List<Pair<Handle, String>>> mFormatStrings;
-
-    /**
-     * Map of strings that do not contain any formatting.
-     */
-    private final Map<String, Handle> mNotFormatStrings = new HashMap<String, Handle>();
-
-    /**
-     * Set of strings that have an unknown format such as date formatting; we should not
-     * flag these as invalid when used from a String#format call
-     */
-    private Set<String> mIgnoreStrings;
-
-    /** Constructs a new {@link StringFormatDetector} check */
-    public StringFormatDetector() {
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.VALUES;
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull Context context, @NonNull File file) {
-        if (LintUtils.endsWith(file.getName(), DOT_JAVA)) {
-            return mFormatStrings != null;
-        }
-
-        return super.appliesTo(context, file);
-    }
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Collections.singletonList(TAG_STRING);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
-        NodeList childNodes = element.getChildNodes();
-        if (childNodes.getLength() > 0) {
-            if (childNodes.getLength() == 1) {
-                Node child = childNodes.item(0);
-                if (child.getNodeType() == Node.TEXT_NODE) {
-                    checkTextNode(context, element, stripQuotes(child.getNodeValue()));
-                }
-            } else {
-                // Concatenate children and build up a plain string.
-                // This is needed to handle xliff localization documents,
-                // but this needs more work so ignore compound XML documents as
-                // string values for now:
-                StringBuilder sb = new StringBuilder();
-                addText(sb, element);
-                if (sb.length() > 0) {
-                    checkTextNode(context, element, sb.toString());
-                }
-            }
-        }
-    }
-
-    private static void addText(StringBuilder sb, Node node) {
-        if (node.getNodeType() == Node.TEXT_NODE) {
-            sb.append(stripQuotes(node.getNodeValue().trim()));
-        } else {
-            NodeList childNodes = node.getChildNodes();
-            for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-                addText(sb, childNodes.item(i));
-            }
-        }
-    }
-
-    /**
-     * Removes all the unescaped quotes. See
-     * <a href="http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling">Escaping apostrophes and quotes</a>
-     */
-    @VisibleForTesting
-    static String stripQuotes(String s) {
-        StringBuilder sb = new StringBuilder();
-        boolean isEscaped = false;
-        boolean isQuotedBlock = false;
-        for (int i = 0, len = s.length(); i < len; i++) {
-            char current = s.charAt(i);
-            if (isEscaped) {
-                sb.append(current);
-                isEscaped = false;
-            } else {
-                isEscaped = current == '\\'; // Next char will be escaped so we will just copy it
-                if (current == '"') {
-                    isQuotedBlock = !isQuotedBlock;
-                } else if (current == '\'') {
-                    if (isQuotedBlock) {
-                        // We only add single quotes when they are within a quoted block
-                        sb.append(current);
-                    }
-                } else {
-                    sb.append(current);
-                }
-            }
-        }
-
-        return sb.toString();
-    }
-
-    private void checkTextNode(XmlContext context, Element element, String text) {
-        String name = element.getAttribute(ATTR_NAME);
-        boolean found = false;
-        boolean foundPlural = false;
-
-        // Look at the String and see if it's a format string (contains
-        // positional %'s)
-        for (int j = 0, m = text.length(); j < m; j++) {
-            char c = text.charAt(j);
-            if (c == '\\') {
-                j++;
-            }
-            if (c == '%') {
-                // Also make sure this String isn't an unformatted String
-                String formatted = element.getAttribute("formatted"); //$NON-NLS-1$
-                if (!formatted.isEmpty() && !Boolean.parseBoolean(formatted)) {
-                    if (!mNotFormatStrings.containsKey(name)) {
-                        Handle handle = context.createLocationHandle(element);
-                        handle.setClientData(element);
-                        mNotFormatStrings.put(name, handle);
-                    }
-                    return;
-                }
-
-                // See if it's not a format string, e.g. "Battery charge is 100%!".
-                // If so we want to record this name in a special list such that we can
-                // make sure you don't attempt to reference this string from a String.format
-                // call.
-                Matcher matcher = FORMAT.matcher(text);
-                if (!matcher.find(j)) {
-                    if (!mNotFormatStrings.containsKey(name)) {
-                        Handle handle = context.createLocationHandle(element);
-                        handle.setClientData(element);
-                        mNotFormatStrings.put(name, handle);
-                    }
-                    return;
-                }
-
-                String conversion = matcher.group(6);
-                int conversionClass = getConversionClass(conversion.charAt(0));
-                if (conversionClass == CONVERSION_CLASS_UNKNOWN || matcher.group(5) != null) {
-                    if (mIgnoreStrings == null) {
-                        mIgnoreStrings = new HashSet<String>();
-                    }
-                    mIgnoreStrings.add(name);
-
-                    // Don't process any other strings here; some of them could
-                    // accidentally look like a string, e.g. "%H" is a hash code conversion
-                    // in String.format (and hour in Time formatting).
-                    return;
-                }
-
-                if (conversionClass == CONVERSION_CLASS_INTEGER && !foundPlural) {
-                    // See if there appears to be further text content here.
-                    // Look for whitespace followed by a letter, with no punctuation in between
-                    for (int k = matcher.end(); k < m; k++) {
-                        char nc = text.charAt(k);
-                        if (!Character.isWhitespace(nc)) {
-                            if (Character.isLetter(nc)) {
-                                foundPlural = checkPotentialPlural(context, element, text, k);
-                            }
-                            break;
-                        }
-                    }
-                }
-
-                found = true;
-                j++; // Ensure that when we process a "%%" we don't separately check the second %
-            }
-        }
-
-        if (!context.getProject().getReportIssues()) {
-            // If this is a library project not being analyzed, ignore it
-            return;
-        }
-
-        if (name != null) {
-            Handle handle = context.createLocationHandle(element);
-            handle.setClientData(element);
-            if (found) {
-                // Record it for analysis when seen in Java code
-                if (mFormatStrings == null) {
-                    mFormatStrings = new HashMap<String, List<Pair<Handle, String>>>();
-                }
-
-                List<Pair<Handle, String>> list = mFormatStrings.get(name);
-                if (list == null) {
-                    list = new ArrayList<Pair<Handle, String>>();
-                    mFormatStrings.put(name, list);
-                }
-                list.add(Pair.of(handle, text));
-            } else {
-                if (!isReference(text)) {
-                    mNotFormatStrings.put(name, handle);
-                }
-            }
-        }
-    }
-
-    private static boolean isReference(@NonNull String text) {
-        for (int i = 0, n = text.length(); i < n; i++) {
-            char c = text.charAt(i);
-            if (!Character.isWhitespace(c)) {
-                return c == '@' || c == '?';
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Checks whether the text begins with a non-unit word, pointing to a string
-     * that should probably be a plural instead. This
-     */
-    private static boolean checkPotentialPlural(XmlContext context, Element element, String text,
-            int wordBegin) {
-        // This method should only be called if the text is known to start with a word
-        assert Character.isLetter(text.charAt(wordBegin));
-
-        int wordEnd = wordBegin;
-        while (wordEnd < text.length()) {
-            if (!Character.isLetter(text.charAt(wordEnd))) {
-                break;
-            }
-            wordEnd++;
-        }
-
-        // Eliminate units, since those are not sentences you need to use plurals for, e.g.
-        //   "Elevation gain: %1$d m (%2$d ft)"
-        // We'll determine whether something is a unit by looking for
-        // (1) Multiple uppercase characters (e.g. KB, or MiB), or better yet, uppercase characters
-        //     anywhere but as the first letter
-        // (2) No vowels (e.g. ft)
-        // (3) Adjacent consonants (e.g. ft); this one can eliminate some legitimate
-        //     English words as well (e.g. "the") so we should really limit this to
-        //     letter pairs that are not common in English. This is probably overkill
-        //     so not handled yet. Instead we use a simpler heuristic:
-        // (4) Very short "words" (1-2 letters)
-        if (wordEnd - wordBegin <= 2) {
-            // Very short word (1-2 chars): possible unit, e.g. "m", "ft", "kb", etc
-            return false;
-        }
-        boolean hasVowel = false;
-        for (int i = wordBegin; i < wordEnd; i++) {
-            // Uppercase character anywhere but first character: probably a unit (e.g. KB)
-            char c = text.charAt(i);
-            if (i > wordBegin && Character.isUpperCase(c)) {
-                return false;
-            }
-            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y') {
-                hasVowel = true;
-            }
-        }
-        if (!hasVowel) {
-            // No vowels: likely unit
-            return false;
-        }
-
-        String word = text.substring(wordBegin, wordEnd);
-
-        // Some other known abbreviations that we don't want to count:
-        if (word.equals("min")) {
-            return false;
-        }
-
-        // This heuristic only works in English!
-        if (LintUtils.isEnglishResource(context, true)) {
-            String message = String.format("Formatting %%d followed by words (\"%1$s\"): "
-                            + "This should probably be a plural rather than a string", word);
-            context.report(POTENTIAL_PLURAL, element,
-                    context.getLocation(element),
-                    message);
-            // Avoid reporting multiple errors on the same string
-            // (if it contains more than one %d)
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (mFormatStrings != null) {
-            boolean checkCount = context.isEnabled(ARG_COUNT);
-            boolean checkValid = context.isEnabled(INVALID);
-            boolean checkTypes = context.isEnabled(ARG_TYPES);
-
-            // Ensure that all the format strings are consistent with respect to each other;
-            // e.g. they all have the same number of arguments, they all use all the
-            // arguments, and they all use the same types for all the numbered arguments
-            for (Map.Entry<String, List<Pair<Handle, String>>> entry : mFormatStrings.entrySet()) {
-                String name = entry.getKey();
-                List<Pair<Handle, String>> list = entry.getValue();
-
-                // Check argument counts
-                if (checkCount) {
-                    Handle notFormatted = mNotFormatStrings.get(name);
-                    if (notFormatted != null) {
-                        list = ImmutableList.<Pair<Handle, String>>builder()
-                                .add(Pair.of(notFormatted, name)).addAll(list).build();
-                    }
-                    checkArity(context, name, list);
-                }
-
-                // Check argument types (and also make sure that the formatting strings are valid)
-                if (checkValid || checkTypes) {
-                    checkTypes(context, checkValid, checkTypes, name, list);
-                }
-            }
-        }
-    }
-
-    private static void checkTypes(Context context, boolean checkValid,
-            boolean checkTypes, String name, List<Pair<Handle, String>> list) {
-        Map<Integer, String> types = new HashMap<Integer, String>();
-        Map<Integer, Handle> typeDefinition = new HashMap<Integer, Handle>();
-        for (Pair<Handle, String> pair : list) {
-            Handle handle = pair.getFirst();
-            String formatString = pair.getSecond();
-
-            //boolean warned = false;
-            Matcher matcher = FORMAT.matcher(formatString);
-            int index = 0;
-            int prevIndex = 0;
-            int nextNumber = 1;
-            while (true) {
-                if (matcher.find(index)) {
-                    int matchStart = matcher.start();
-                    // Make sure this is not an escaped '%'
-                    for (; prevIndex < matchStart; prevIndex++) {
-                        char c = formatString.charAt(prevIndex);
-                        if (c == '\\') {
-                            prevIndex++;
-                        }
-                    }
-                    if (prevIndex > matchStart) {
-                        // We're in an escape, ignore this result
-                        index = prevIndex;
-                        continue;
-                    }
-
-                    index = matcher.end(); // Ensure loop proceeds
-                    String str = formatString.substring(matchStart, matcher.end());
-                    if (str.equals("%%") || str.equals("%n")) { //$NON-NLS-1$ //$NON-NLS-2$
-                        // Just an escaped %
-                        continue;
-                    }
-
-                    if (checkValid) {
-                        // Make sure it's a valid format string
-                        if (str.length() > 2 && str.charAt(str.length() - 2) == ' ') {
-                            char last = str.charAt(str.length() - 1);
-                            // If you forget to include the conversion character, e.g.
-                            //   "Weight=%1$ g" instead of "Weight=%1$d g", then
-                            // you're going to end up with a format string interpreted as
-                            // "%1$ g". This means that the space character is interpreted
-                            // as a flag character, but it can only be a flag character
-                            // when used in conjunction with the numeric conversion
-                            // formats (d, o, x, X). If that's not the case, make a
-                            // dedicated error message
-                            if (last != 'd' && last != 'o' && last != 'x' && last != 'X') {
-                                Object clientData = handle.getClientData();
-                                if (clientData instanceof Node) {
-                                    if (context.getDriver().isSuppressed(null, INVALID,
-                                            (Node) clientData)) {
-                                        return;
-                                    }
-                                }
-
-                                Location location = handle.resolve();
-                                String message = String.format(
-                                        "Incorrect formatting string `%1$s`; missing conversion " +
-                                        "character in '`%2$s`' ?", name, str);
-                                context.report(INVALID, location, message);
-                                //warned = true;
-                                continue;
-                            }
-                        }
-                    }
-
-                    if (!checkTypes) {
-                        continue;
-                    }
-
-                    // Shouldn't throw a number format exception since we've already
-                    // matched the pattern in the regexp
-                    int number;
-                    String numberString = matcher.group(1);
-                    if (numberString != null) {
-                        // Strip off trailing $
-                        numberString = numberString.substring(0, numberString.length() - 1);
-                        number = Integer.parseInt(numberString);
-                        nextNumber = number + 1;
-                    } else {
-                        number = nextNumber++;
-                    }
-                    String format = matcher.group(6);
-                    String currentFormat = types.get(number);
-                    if (currentFormat == null) {
-                        types.put(number, format);
-                        typeDefinition.put(number, handle);
-                    } else if (!currentFormat.equals(format)
-                            && isIncompatible(currentFormat.charAt(0), format.charAt(0))) {
-
-                        Object clientData = handle.getClientData();
-                        if (clientData instanceof Node) {
-                            if (context.getDriver().isSuppressed(null, ARG_TYPES,
-                                    (Node) clientData)) {
-                                return;
-                            }
-                        }
-
-                        Location location = handle.resolve();
-                        // Attempt to limit the location range to just the formatting
-                        // string in question
-                        location = refineLocation(context, location, formatString,
-                                matcher.start(), matcher.end());
-                        Location otherLocation = typeDefinition.get(number).resolve();
-                        otherLocation.setMessage("Conflicting argument type here");
-                        location.setSecondary(otherLocation);
-                        File f = otherLocation.getFile();
-                        String message = String.format(
-                                "Inconsistent formatting types for argument #%1$d in " +
-                                "format string `%2$s` ('%3$s'): Found both '`%4$s`' and '`%5$s`' " +
-                                "(in %6$s)",
-                                number, name,
-                                str,
-                                currentFormat, format,
-                                f.getParentFile().getName() + File.separator + f.getName());
-                        //warned = true;
-                        context.report(ARG_TYPES, location, message);
-                        break;
-                    }
-                } else {
-                    break;
-                }
-            }
-
-            // Check that the format string is valid by actually attempting to instantiate
-            // it. We only do this if we haven't already complained about this string
-            // for other reasons.
-            /* Check disabled for now: it had many false reports due to conversion
-             * errors (which is expected since we just pass in strings), but once those
-             * are eliminated there aren't really any other valid error messages returned
-             * (for example, calling the formatter with bogus formatting flags always just
-             * returns a "conversion" error. It looks like we'd need to actually pass compatible
-             * arguments to trigger other types of formatting errors such as precision errors.
-            if (!warned && checkValid) {
-                try {
-                    formatter.format(formatString, "", "", "", "", "", "", "",
-                            "", "", "", "", "", "", "");
-
-                } catch (IllegalFormatException t) { // TODO: UnknownFormatConversionException
-                    if (!t.getLocalizedMessage().contains(" != ")
-                            && !t.getLocalizedMessage().contains("Conversion")) {
-                        Location location = handle.resolve();
-                        context.report(INVALID, location,
-                                String.format("Wrong format for %1$s: %2$s",
-                                        name, t.getLocalizedMessage()), null);
-                    }
-                }
-            }
-            */
-        }
-    }
-
-    /**
-     * Returns true if two String.format conversions are "incompatible" (meaning
-     * that using these two for the same argument across different translations
-     * is more likely an error than intentional. Some conversions are
-     * incompatible, e.g. "d" and "s" where one is a number and string, whereas
-     * others may work (e.g. float versus integer) but are probably not
-     * intentional.
-     */
-    private static boolean isIncompatible(char conversion1, char conversion2) {
-        int class1 = getConversionClass(conversion1);
-        int class2 = getConversionClass(conversion2);
-        return class1 != class2
-                && class1 != CONVERSION_CLASS_UNKNOWN
-                && class2 != CONVERSION_CLASS_UNKNOWN;
-    }
-
-    private static final int CONVERSION_CLASS_UNKNOWN = 0;
-    private static final int CONVERSION_CLASS_STRING = 1;
-    private static final int CONVERSION_CLASS_CHARACTER = 2;
-    private static final int CONVERSION_CLASS_INTEGER = 3;
-    private static final int CONVERSION_CLASS_FLOAT = 4;
-    private static final int CONVERSION_CLASS_BOOLEAN = 5;
-    private static final int CONVERSION_CLASS_HASHCODE = 6;
-    private static final int CONVERSION_CLASS_PERCENT = 7;
-    private static final int CONVERSION_CLASS_NEWLINE = 8;
-    private static final int CONVERSION_CLASS_DATETIME = 9;
-
-    private static int getConversionClass(char conversion) {
-        // See http://developer.android.com/reference/java/util/Formatter.html
-        switch (conversion) {
-            case 't':   // Time/date conversion
-            case 'T':
-                return CONVERSION_CLASS_DATETIME;
-            case 's':   // string
-            case 'S':   // Uppercase string
-                return CONVERSION_CLASS_STRING;
-            case 'c':   // character
-            case 'C':   // Uppercase character
-                return CONVERSION_CLASS_CHARACTER;
-            case 'd':   // decimal
-            case 'o':   // octal
-            case 'x':   // hex
-            case 'X':
-                return CONVERSION_CLASS_INTEGER;
-            case 'f':   // decimal float
-            case 'e':   // exponential float
-            case 'E':
-            case 'g':   // decimal or exponential depending on size
-            case 'G':
-            case 'a':   // hex float
-            case 'A':
-                return CONVERSION_CLASS_FLOAT;
-            case 'b':   // boolean
-            case 'B':
-                return CONVERSION_CLASS_BOOLEAN;
-            case 'h':   // boolean
-            case 'H':
-                return CONVERSION_CLASS_HASHCODE;
-            case '%':   // literal
-                return CONVERSION_CLASS_PERCENT;
-            case 'n':   // literal
-                return CONVERSION_CLASS_NEWLINE;
-        }
-
-        return CONVERSION_CLASS_UNKNOWN;
-    }
-
-    private static Location refineLocation(Context context, Location location,
-            String formatString, int substringStart, int substringEnd) {
-        Position startLocation = location.getStart();
-        Position endLocation = location.getEnd();
-        if (startLocation != null && endLocation != null) {
-            int startOffset = startLocation.getOffset();
-            int endOffset = endLocation.getOffset();
-            if (startOffset >= 0) {
-                String contents = context.getClient().readFile(location.getFile());
-                if (endOffset <= contents.length() && startOffset < endOffset) {
-                    int formatOffset = contents.indexOf(formatString, startOffset);
-                    if (formatOffset != -1 && formatOffset <= endOffset) {
-                        return Location.create(location.getFile(), contents,
-                                formatOffset + substringStart, formatOffset + substringEnd);
-                    }
-                }
-            }
-        }
-
-        return location;
-    }
-
-    /**
-     * Check that the number of arguments in the format string is consistent
-     * across translations, and that all arguments are used
-     */
-    private static void checkArity(Context context, String name, List<Pair<Handle, String>> list) {
-        // Check to make sure that the argument counts and types are consistent
-        int prevCount = -1;
-        for (Pair<Handle, String> pair : list) {
-            Set<Integer> indices = new HashSet<Integer>();
-            int count = getFormatArgumentCount(pair.getSecond(), indices);
-            Handle handle = pair.getFirst();
-            if (prevCount != -1 && prevCount != count) {
-                Object clientData = handle.getClientData();
-                if (clientData instanceof Node) {
-                    if (context.getDriver().isSuppressed(null, ARG_COUNT, (Node) clientData)) {
-                        return;
-                    }
-                }
-                Location location = handle.resolve();
-                Location secondary = list.get(0).getFirst().resolve();
-                secondary.setMessage("Conflicting number of arguments here");
-                location.setSecondary(secondary);
-                String message = String.format(
-                        "Inconsistent number of arguments in formatting string `%1$s`; " +
-                        "found both %2$d and %3$d", name, prevCount, count);
-                context.report(ARG_COUNT, location, message);
-                break;
-            }
-
-            for (int i = 1; i <= count; i++) {
-                if (!indices.contains(i)) {
-                    Object clientData = handle.getClientData();
-                    if (clientData instanceof Node) {
-                        if (context.getDriver().isSuppressed(null, ARG_COUNT,
-                                (Node) clientData)) {
-                            return;
-                        }
-                    }
-
-                    Set<Integer> all = new HashSet<Integer>();
-                    for (int j = 1; j < count; j++) {
-                        all.add(j);
-                    }
-                    all.removeAll(indices);
-                    List<Integer> sorted = new ArrayList<Integer>(all);
-                    Collections.sort(sorted);
-                    Location location = handle.resolve();
-                    String message = String.format(
-                            "Formatting string '`%1$s`' is not referencing numbered arguments %2$s",
-                            name, sorted);
-                    context.report(ARG_COUNT, location, message);
-                    break;
-                }
-            }
-
-            prevCount = count;
-        }
-    }
-
-    // See java.util.Formatter docs
-    public static final Pattern FORMAT = Pattern.compile(
-            // Generic format:
-            //   %[argument_index$][flags][width][.precision]conversion
-            //
-            "%" +                                                               //$NON-NLS-1$
-            // Argument Index
-            "(\\d+\\$)?" +                                                      //$NON-NLS-1$
-            // Flags
-            "([-+#, 0(<]*)?" +                                                  //$NON-NLS-1$
-            // Width
-            "(\\d+)?" +                                                         //$NON-NLS-1$
-            // Precision
-            "(\\.\\d+)?" +                                                      //$NON-NLS-1$
-            // Conversion. These are all a single character, except date/time conversions
-            // which take a prefix of t/T:
-            "([tT])?" +                                                         //$NON-NLS-1$
-            // The current set of conversion characters are
-            // b,h,s,c,d,o,x,e,f,g,a,t (as well as all those as upper-case characters), plus
-            // n for newlines and % as a literal %. And then there are all the time/date
-            // characters: HIKLm etc. Just match on all characters here since there should
-            // be at least one.
-            "([a-zA-Z%])");                                                     //$NON-NLS-1$
-
-    /** Given a format string returns the format type of the given argument */
-    @VisibleForTesting
-    @Nullable
-    static String getFormatArgumentType(String s, int argument) {
-        Matcher matcher = FORMAT.matcher(s);
-        int index = 0;
-        int prevIndex = 0;
-        int nextNumber = 1;
-        while (true) {
-            if (matcher.find(index)) {
-                String value = matcher.group(6);
-                if ("%".equals(value) || "n".equals(value)) { //$NON-NLS-1$ //$NON-NLS-2$
-                    index = matcher.end();
-                    continue;
-                }
-                int matchStart = matcher.start();
-                // Make sure this is not an escaped '%'
-                for (; prevIndex < matchStart; prevIndex++) {
-                    char c = s.charAt(prevIndex);
-                    if (c == '\\') {
-                        prevIndex++;
-                    }
-                }
-                if (prevIndex > matchStart) {
-                    // We're in an escape, ignore this result
-                    index = prevIndex;
-                    continue;
-                }
-
-                // Shouldn't throw a number format exception since we've already
-                // matched the pattern in the regexp
-                int number;
-                String numberString = matcher.group(1);
-                if (numberString != null) {
-                    // Strip off trailing $
-                    numberString = numberString.substring(0, numberString.length() - 1);
-                    number = Integer.parseInt(numberString);
-                    nextNumber = number + 1;
-                } else {
-                    number = nextNumber++;
-                }
-
-                if (number == argument) {
-                    return matcher.group(6);
-                }
-                index = matcher.end();
-            } else {
-                break;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Given a format string returns the number of required arguments. If the
-     * {@code seenArguments} parameter is not null, put the indices of any
-     * observed arguments into it.
-     */
-    static int getFormatArgumentCount(@NonNull String s, @Nullable Set<Integer> seenArguments) {
-        Matcher matcher = FORMAT.matcher(s);
-        int index = 0;
-        int prevIndex = 0;
-        int nextNumber = 1;
-        int max = 0;
-        while (true) {
-            if (matcher.find(index)) {
-                String value = matcher.group(6);
-                if ("%".equals(value) || "n".equals(value)) { //$NON-NLS-1$ //$NON-NLS-2$
-                    index = matcher.end();
-                    continue;
-                }
-                int matchStart = matcher.start();
-                // Make sure this is not an escaped '%'
-                for (; prevIndex < matchStart; prevIndex++) {
-                    char c = s.charAt(prevIndex);
-                    if (c == '\\') {
-                        prevIndex++;
-                    }
-                }
-                if (prevIndex > matchStart) {
-                    // We're in an escape, ignore this result
-                    index = prevIndex;
-                    continue;
-                }
-
-                // Shouldn't throw a number format exception since we've already
-                // matched the pattern in the regexp
-                int number;
-                String numberString = matcher.group(1);
-                if (numberString != null) {
-                    // Strip off trailing $
-                    numberString = numberString.substring(0, numberString.length() - 1);
-                    number = Integer.parseInt(numberString);
-                    nextNumber = number + 1;
-                } else {
-                    number = nextNumber++;
-                }
-
-                if (number > max) {
-                    max = number;
-                }
-                if (seenArguments != null) {
-                    seenArguments.add(number);
-                }
-
-                index = matcher.end();
-            } else {
-                break;
-            }
-        }
-
-        return max;
-    }
-
-    /**
-     * Determines whether the given {@link String#format(String, Object...)}
-     * formatting string is "locale dependent", meaning that its output depends
-     * on the locale. This is the case if it for example references decimal
-     * numbers of dates and times.
-     *
-     * @param format the format string
-     * @return true if the format is locale sensitive, false otherwise
-     */
-    public static boolean isLocaleSpecific(@NonNull String format) {
-        if (format.indexOf('%') == -1) {
-            return false;
-        }
-
-        Matcher matcher = FORMAT.matcher(format);
-        int index = 0;
-        int prevIndex = 0;
-        while (true) {
-            if (matcher.find(index)) {
-                int matchStart = matcher.start();
-                // Make sure this is not an escaped '%'
-                for (; prevIndex < matchStart; prevIndex++) {
-                    char c = format.charAt(prevIndex);
-                    if (c == '\\') {
-                        prevIndex++;
-                    }
-                }
-                if (prevIndex > matchStart) {
-                    // We're in an escape, ignore this result
-                    index = prevIndex;
-                    continue;
-                }
-
-                String type = matcher.group(6);
-                if (!type.isEmpty()) {
-                    char t = type.charAt(0);
-
-                    // The following formatting characters are locale sensitive:
-                    switch (t) {
-                        case 'd': // decimal integer
-                        case 'e': // scientific
-                        case 'E':
-                        case 'f': // decimal float
-                        case 'g': // general
-                        case 'G':
-                        case 't': // date/time
-                        case 'T':
-                            return true;
-                    }
-                }
-                index = matcher.end();
-            } else {
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(FORMAT_METHOD, GET_STRING_METHOD);
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod method) {
-        if (mFormatStrings == null && !context.getClient().supportsProjectResources()) {
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        String methodName = method.getName();
-        if (methodName.equals(FORMAT_METHOD)) {
-            if (JavaEvaluator.isMemberInClass(method, TYPE_STRING)) {
-                // Check formatting parameters for
-                //   java.lang.String#format(String format, Object... formatArgs)
-                //   java.lang.String#format(Locale locale, String format, Object... formatArgs)
-                checkStringFormatCall(context, method, node,
-                        method.getParameterList().getParametersCount() == 3);
-
-                // TODO: Consider also enforcing
-                // java.util.Formatter#format(String string, Object... formatArgs)
-            }
-        } else {
-            // Look up any of these string formatting methods:
-            // android.content.res.Resources#getString(@StringRes int resId, Object... formatArgs)
-            // android.content.Context#getString(@StringRes int resId, Object... formatArgs)
-            // android.app.Fragment#getString(@StringRes int resId, Object... formatArgs)
-            // android.support.v4.app.Fragment#getString(@StringRes int resId, Object... formatArgs)
-
-            // Many of these also define a plain getString method:
-            // android.content.res.Resources#getString(@StringRes int resId)
-            // However, while it's possible that these contain formatting strings) it's
-            // also possible that they're looking up strings that are not intended to be used
-            // for formatting so while we may want to warn about this it's not necessarily
-            // an error.
-            if (method.getParameterList().getParametersCount() < 2) {
-                return;
-            }
-
-            if (evaluator.isMemberInSubClassOf(method, CLASS_RESOURCES, false) ||
-                    evaluator.isMemberInSubClassOf(method, CLASS_CONTEXT, false) ||
-                    evaluator.isMemberInSubClassOf(method, CLASS_FRAGMENT, false) ||
-                    evaluator.isMemberInSubClassOf(method, CLASS_V4_FRAGMENT, false)) {
-                checkStringFormatCall(context, method, node, false);
-            }
-
-            // TODO: Consider also looking up
-            // android.content.res.Resources#getQuantityString(@PluralsRes int id, int quantity,
-            //              Object... formatArgs)
-            // though this will require being smarter about cross referencing formatting
-            // strings since we'll need to go via the quantity string definitions
-        }
-    }
-
-    /**
-     * Checks a String.format call that is using a string that doesn't contain format placeholders.
-     * @param context the context to report errors to
-     * @param call the AST node for the {@link String#format}
-     * @param name the string name
-     * @param handle the string location
-     */
-    private static void checkNotFormattedHandle(
-            JavaContext context,
-            UCallExpression call,
-            String name,
-            Handle handle) {
-        Object clientData = handle.getClientData();
-        if (clientData instanceof Node) {
-            if (context.getDriver().isSuppressed(null, INVALID, (Node) clientData)) {
-                return;
-            }
-        }
-        Location location = context.getUastLocation(call);
-        Location secondary = handle.resolve();
-        secondary.setMessage("This definition does not require arguments");
-        location.setSecondary(secondary);
-        String message = String.format(
-                "Format string '`%1$s`' is not a valid format string so it should not be " +
-                        "passed to `String.format`",
-                name);
-        context.report(INVALID, call, location, message);
-    }
-
-    /**
-     * Check the given String.format call (with the given arguments) to see if the string format is
-     * being used correctly
-     *  @param context           the context to report errors to
-     * @param calledMethod      the method being called
-     * @param call              the AST node for the {@link String#format}
-     * @param specifiesLocale   whether the first parameter is a locale string, shifting the
-     */
-    private void checkStringFormatCall(
-            JavaContext context,
-            PsiMethod calledMethod,
-            UCallExpression call,
-            boolean specifiesLocale) {
-
-        int argIndex = specifiesLocale ? 1 : 0;
-        List<UExpression> args = call.getValueArguments();
-
-        if (args.size() <= argIndex) {
-            return;
-        }
-
-        UExpression argument = args.get(argIndex);
-        ResourceUrl resource = ResourceEvaluator.getResource(context, argument);
-        if (resource == null || resource.framework || resource.type != ResourceType.STRING) {
-            return;
-        }
-
-        String name = resource.name;
-        if (mIgnoreStrings != null && mIgnoreStrings.contains(name)) {
-            return;
-        }
-
-        boolean passingVarArgsArray = false;
-        int callCount = args.size() - 1 - argIndex;
-
-        if (callCount == 1) {
-            // If instead of a varargs call like
-            //    getString(R.string.foo, arg1, arg2, arg3)
-            // the code is calling the varargs method with a packed Object array, as in
-            //    getString(R.string.foo, new Object[] { arg1, arg2, arg3 })
-            // we'll need to handle that such that we don't think this is a single
-            // argument
-
-            UExpression lastArg = args.get(args.size() - 1);
-            PsiParameterList parameterList = calledMethod.getParameterList();
-            int parameterCount = parameterList.getParametersCount();
-            if (parameterCount > 0 && parameterList.getParameters()[parameterCount - 1].isVarArgs()) {
-                boolean knownArity = false;
-
-                boolean argWasReference = false;
-                if (lastArg instanceof UReferenceExpression) {
-                    PsiElement resolved = ((UReferenceExpression) lastArg).resolve();
-                    if (resolved instanceof PsiVariable) {
-                        UExpression initializer = context.getUastContext().getInitializerBody (
-                                (PsiVariable) resolved);
-                        if (initializer != null &&
-                            (UastExpressionUtils.isNewArray(initializer) ||
-                             UastExpressionUtils.isArrayInitializer(initializer))) {
-                            argWasReference = true;
-                            // Now handled by check below
-                            lastArg = initializer;
-                        }
-                    }
-                }
-
-                if (UastExpressionUtils.isNewArray(lastArg) ||
-                    UastExpressionUtils.isArrayInitializer(lastArg)) {
-                    UCallExpression arrayInitializer = (UCallExpression) lastArg;
-
-                    if (UastExpressionUtils.isNewArrayWithInitializer(lastArg) ||
-                        UastExpressionUtils.isArrayInitializer(lastArg)) {
-                        callCount = arrayInitializer.getValueArgumentCount();
-                        knownArity = true;
-                    } else if (UastExpressionUtils.isNewArrayWithDimensions(lastArg)) {
-                        List<UExpression> arrayDimensions = arrayInitializer.getValueArguments();
-                        if (arrayDimensions.size() == 1) {
-                            UExpression first = arrayDimensions.get(0);
-                            if (first instanceof ULiteralExpression) {
-                                Object o = ((ULiteralExpression) first).getValue();
-                                if (o instanceof Integer) {
-                                    callCount = (Integer)o;
-                                    knownArity = true;
-                                }
-                            }
-                        }
-                    }
-
-                    if (!knownArity) {
-                        if (!argWasReference) {
-                            return;
-                        }
-                    } else {
-                        passingVarArgsArray = true;
-                    }
-                }
-            }
-        }
-
-        if (callCount > 0 && mNotFormatStrings.containsKey(name)) {
-            checkNotFormattedHandle(context, call, name, mNotFormatStrings.get(name));
-            return;
-        }
-
-        List<Pair<Handle, String>> list = mFormatStrings != null ? mFormatStrings.get(name) : null;
-        if (list == null) {
-            LintClient client = context.getClient();
-            if (client.supportsProjectResources() &&
-                    !context.getScope().contains(Scope.RESOURCE_FILE)) {
-                AbstractResourceRepository resources = client
-                        .getProjectResources(context.getMainProject(), true);
-                List<ResourceItem> items;
-                if (resources != null) {
-                    items = resources.getResourceItem(ResourceType.STRING, name);
-                } else {
-                    // Must be a non-Android module
-                    items = null;
-                }
-                if (items != null) {
-                    for (final ResourceItem item : items) {
-                        ResourceValue v = item.getResourceValue(false);
-                        if (v != null) {
-                            String value = v.getRawXmlValue();
-                            if (value != null) {
-                                // Make sure it's really a formatting string,
-                                // not for example "Battery remaining: 90%"
-                                boolean isFormattingString = value.indexOf('%') != -1;
-                                for (int j = 0, m = value.length();
-                                        j < m && isFormattingString;
-                                        j++) {
-                                    char c = value.charAt(j);
-                                    if (c == '\\') {
-                                        j++;
-                                    } else if (c == '%') {
-                                        Matcher matcher = FORMAT.matcher(value);
-                                        if (!matcher.find(j)) {
-                                            isFormattingString = false;
-                                        } else {
-                                            String conversion = matcher.group(6);
-                                            int conversionClass = getConversionClass(
-                                                    conversion.charAt(0));
-                                            if (conversionClass == CONVERSION_CLASS_UNKNOWN
-                                                    || matcher.group(5) != null) {
-                                                // Some date format etc - don't process
-                                                return;
-                                            }
-                                        }
-                                        j++; // Don't process second % in a %%
-                                    }
-                                    // If the user marked the string with
-                                }
-
-                                Handle handle = client.createResourceItemHandle(item);
-                                if (isFormattingString) {
-                                    if (list == null) {
-                                        list = Lists.newArrayList();
-                                        if (mFormatStrings == null) {
-                                            mFormatStrings = Maps.newHashMap();
-                                        }
-                                        mFormatStrings.put(name, list);
-                                    }
-                                    list.add(Pair.of(handle, value));
-                                } else if (callCount > 0) {
-                                    checkNotFormattedHandle(context, call, name, handle);
-                                }
-                            }
-                        }
-                    }
-                }
-            } else {
-                return;
-            }
-        }
-
-        if (list != null) {
-            Set<String> reported = null;
-            for (Pair<Handle, String> pair : list) {
-                String s = pair.getSecond();
-                if (reported != null && reported.contains(s)) {
-                    continue;
-                }
-                int count = getFormatArgumentCount(s, null);
-                Handle handle = pair.getFirst();
-                if (count != callCount) {
-                    Location location = context.getUastLocation(call);
-                    Location secondary = handle.resolve();
-                    secondary.setMessage(String.format("This definition requires %1$d arguments",
-                            count));
-                    location.setSecondary(secondary);
-                    String message = String.format(
-                            "Wrong argument count, format string `%1$s` requires `%2$d` but format " +
-                            "call supplies `%3$d`",
-                            name, count, callCount);
-                    context.report(ARG_TYPES, call, location, message);
-                    if (reported == null) {
-                        reported = Sets.newHashSet();
-                    }
-                    reported.add(s);
-                } else {
-                    if (passingVarArgsArray) {
-                        // Can't currently check these: make sure we don't incorrectly
-                        // flag parameters on the Object[] instead of the wrapped parameters
-                        return;
-                    }
-                    for (int i = 1; i <= count; i++) {
-                        int argumentIndex = i + argIndex;
-                        PsiType type = args.get(argumentIndex).getExpressionType();
-                        if (type != null) {
-                            boolean valid = true;
-                            String formatType = getFormatArgumentType(s, i);
-                            if (formatType == null) {
-                                continue;
-                            }
-                            char last = formatType.charAt(formatType.length() - 1);
-                            if (formatType.length() >= 2 &&
-                                    Character.toLowerCase(
-                                            formatType.charAt(formatType.length() - 2)) == 't') {
-                                // Date time conversion.
-                                // TODO
-                                continue;
-                            }
-                            switch (last) {
-                                // Booleans. It's okay to pass objects to these;
-                                // it will print "true" if non-null, but it's
-                                // unusual and probably not intended.
-                                case 'b':
-                                case 'B':
-                                    valid = isBooleanType(type);
-                                    break;
-
-                                // Numeric: integer and floats in various formats
-                                case 'x':
-                                case 'X':
-                                case 'd':
-                                case 'o':
-                                case 'e':
-                                case 'E':
-                                case 'f':
-                                case 'g':
-                                case 'G':
-                                case 'a':
-                                case 'A':
-                                    valid = isNumericType(type, true);
-                                    break;
-                                case 'c':
-                                case 'C':
-                                    // Unicode character
-                                    valid = isCharacterType(type);
-                                    break;
-                                case 'h':
-                                case 'H': // Hex print of hash code of objects
-                                case 's':
-                                case 'S':
-                                    // String. Can pass anything, but warn about
-                                    // numbers since you may have meant more
-                                    // specific formatting. Use special issue
-                                    // explanation for this?
-                                    valid = !isBooleanType(type) &&
-                                            !isNumericType(type, false);
-                                    break;
-                            }
-
-                            if (!valid) {
-                                Location location = context.getUastLocation(args.get(argumentIndex));
-                                Location secondary = handle.resolve();
-                                secondary.setMessage("Conflicting argument declaration here");
-                                location.setSecondary(secondary);
-                                String suggestion = null;
-                                if (isBooleanType(type)) {
-                                    suggestion = "`b`";
-                                } else if (isCharacterType(type)) {
-                                    suggestion = "'c'";
-                                } else if (PsiType.INT.equals(type)
-                                            || PsiType.LONG.equals(type)
-                                            || PsiType.BYTE.equals(type)
-                                            || PsiType.SHORT.equals(type)) {
-                                    suggestion = "`d`, 'o' or `x`";
-                                } else if (PsiType.FLOAT.equals(type)
-                                        || PsiType.DOUBLE.equals(type)) {
-                                    suggestion = "`e`, 'f', 'g' or `a`";
-                                } else if (type instanceof PsiClassType) {
-                                    String fqn = type.getCanonicalText();
-                                    if (TYPE_INTEGER_WRAPPER.equals(fqn)
-                                            || TYPE_LONG_WRAPPER.equals(fqn)
-                                            || TYPE_BYTE_WRAPPER.equals(fqn)
-                                            || TYPE_SHORT_WRAPPER.equals(fqn)) {
-                                        suggestion = "`d`, 'o' or `x`";
-                                    } else if (TYPE_FLOAT_WRAPPER.equals(fqn)
-                                            || TYPE_DOUBLE_WRAPPER.equals(fqn)) {
-                                        suggestion = "`d`, 'o' or `x`";
-                                    } else if (TYPE_OBJECT.equals(fqn)) {
-                                        suggestion = "'s' or 'h'";
-                                    }
-                                }
-
-                                if (suggestion != null) {
-                                    suggestion = " (Did you mean formatting character "
-                                            + suggestion + "?)";
-                                } else {
-                                    suggestion = "";
-                                }
-
-                                String canonicalText = type.getCanonicalText();
-                                canonicalText = canonicalText.substring(
-                                        canonicalText.lastIndexOf('.') + 1);
-
-                                String message = String.format(
-                                        "Wrong argument type for formatting argument '#%1$d' " +
-                                        "in `%2$s`: conversion is '`%3$s`', received `%4$s` " +
-                                        "(argument #%5$d in method call)%6$s",
-                                        i, name, formatType, canonicalText,
-                                        argumentIndex + 1, suggestion);
-                                context.report(ARG_TYPES, call, location, message);
-                                if (reported == null) {
-                                    reported = Sets.newHashSet();
-                                }
-                                reported.add(s);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private static boolean isCharacterType(PsiType type) {
-        //return PsiType.CHAR.isAssignableFrom(type);
-        if (type == PsiType.CHAR) {
-            return true;
-        }
-        if (type instanceof PsiClassType) {
-            String fqn = type.getCanonicalText();
-            return TYPE_CHARACTER_WRAPPER.equals(fqn);
-        }
-
-        return false;
-    }
-
-    private static boolean isBooleanType(PsiType type) {
-        //return PsiType.BOOLEAN.isAssignableFrom(type);
-        if (type == PsiType.BOOLEAN) {
-            return true;
-        }
-        if (type instanceof PsiClassType) {
-            String fqn = type.getCanonicalText();
-            return TYPE_BOOLEAN_WRAPPER.equals(fqn);
-        }
-
-        return false;
-    }
-
-    //PsiType:java.lang.Boolean
-    private static boolean isNumericType(@NonNull PsiType type, boolean allowBigNumbers) {
-        if (PsiType.INT.equals(type)
-                || PsiType.FLOAT.equals(type)
-                || PsiType.DOUBLE.equals(type)
-                || PsiType.LONG.equals(type)
-                || PsiType.BYTE.equals(type)
-                || PsiType.SHORT.equals(type)) {
-            return true;
-        }
-
-        if (type instanceof PsiClassType) {
-            String fqn = type.getCanonicalText();
-            if (TYPE_INTEGER_WRAPPER.equals(fqn)
-                    || TYPE_FLOAT_WRAPPER.equals(fqn)
-                    || TYPE_DOUBLE_WRAPPER.equals(fqn)
-                    || TYPE_LONG_WRAPPER.equals(fqn)
-                    || TYPE_BYTE_WRAPPER.equals(fqn)
-                    || TYPE_SHORT_WRAPPER.equals(fqn)) {
-                return true;
-            }
-            if (allowBigNumbers) {
-                if ("java.math.BigInteger".equals(fqn) ||
-                        "java.math.BigDecimal".equals(fqn)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java
deleted file mode 100644
index fd19657..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java
+++ /dev/null
@@ -1,1901 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.resources.ResourceType;
-import com.android.sdklib.AndroidVersion;
-import com.android.tools.klint.checks.PermissionFinder.Operation;
-import com.android.tools.klint.checks.PermissionFinder.Result;
-import com.android.tools.klint.checks.PermissionHolder.SetPermissionLookup;
-import com.android.tools.klint.client.api.ExternalReferenceExpression;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.UastLintUtils;
-import com.android.tools.klint.detector.api.*;
-import com.android.utils.XmlUtils;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Sets;
-import com.intellij.psi.*;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.java.JavaUAnnotation;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.*;
-
-import static com.android.SdkConstants.*;
-import static com.android.resources.ResourceType.*;
-import static com.android.tools.klint.checks.PermissionFinder.Operation.*;
-import static com.android.tools.klint.checks.PermissionRequirement.*;
-import static com.android.tools.klint.detector.api.ResourceEvaluator.*;
-import static org.jetbrains.uast.UastUtils.getQualifiedParentOrThis;
-
-/**
- * Looks up annotations on method calls and enforces the various things they
- * express, e.g. for {@code @CheckReturn} it makes sure the return value is used,
- * for {@code ColorInt} it ensures that a proper color integer is passed in, etc.
- *
- * TODO: Throw in some annotation usage checks here too; e.g. specifying @Size without parameters,
- * specifying toInclusive without setting to, combining @ColorInt with any @ResourceTypeRes,
- * using @CheckResult on a void method, etc.
- */
-@SuppressWarnings("WeakerAccess")
-public class SupportAnnotationDetector extends Detector implements Detector.UastScanner {
-
-    public static final Implementation IMPLEMENTATION
-            = new Implementation(SupportAnnotationDetector.class, Scope.JAVA_FILE_SCOPE);
-
-    /** Method result should be used */
-    public static final Issue RANGE = Issue.create(
-        "Range", //$NON-NLS-1$
-        "Outside Range",
-
-        "Some parameters are required to in a particular numerical range; this check " +
-        "makes sure that arguments passed fall within the range. For arrays, Strings " +
-        "and collections this refers to the size or length.",
-
-        Category.CORRECTNESS,
-        6,
-        Severity.ERROR,
-        IMPLEMENTATION);
-
-    /**
-     * Attempting to set a resource id as a color
-     */
-    public static final Issue RESOURCE_TYPE = Issue.create(
-        "ResourceType", //$NON-NLS-1$
-        "Wrong Resource Type",
-
-        "Ensures that resource id's passed to APIs are of the right type; for example, " +
-        "calling `Resources.getColor(R.string.name)` is wrong.",
-
-        Category.CORRECTNESS,
-        7,
-        Severity.FATAL,
-        IMPLEMENTATION);
-
-    /** Attempting to set a resource id as a color */
-    public static final Issue COLOR_USAGE = Issue.create(
-        "ResourceAsColor", //$NON-NLS-1$
-        "Should pass resolved color instead of resource id",
-
-        "Methods that take a color in the form of an integer should be passed " +
-        "an RGB triple, not the actual color resource id. You must call " +
-        "`getResources().getColor(resource)` to resolve the actual color value first.",
-
-        Category.CORRECTNESS,
-        7,
-        Severity.ERROR,
-        IMPLEMENTATION);
-
-    /** Passing the wrong constant to an int or String method */
-    public static final Issue TYPE_DEF = Issue.create(
-        "WrongConstant", //$NON-NLS-1$
-        "Incorrect constant",
-
-        "Ensures that when parameter in a method only allows a specific set " +
-        "of constants, calls obey those rules.",
-
-        Category.SECURITY,
-        6,
-        Severity.ERROR,
-        IMPLEMENTATION);
-
-    /** Method result should be used */
-    public static final Issue CHECK_RESULT = Issue.create(
-        "CheckResult", //$NON-NLS-1$
-        "Ignoring results",
-
-        "Some methods have no side effects, an calling them without doing something " +
-        "without the result is suspicious. ",
-
-        Category.CORRECTNESS,
-        6,
-        Severity.WARNING,
-            IMPLEMENTATION);
-
-    /** Failing to enforce security by just calling check permission */
-    public static final Issue CHECK_PERMISSION = Issue.create(
-        "UseCheckPermission", //$NON-NLS-1$
-        "Using the result of check permission calls",
-
-        "You normally want to use the result of checking a permission; these methods " +
-        "return whether the permission is held; they do not throw an error if the permission " +
-        "is not granted. Code which does not do anything with the return value probably " +
-        "meant to be calling the enforce methods instead, e.g. rather than " +
-        "`Context#checkCallingPermission` it should call `Context#enforceCallingPermission`.",
-
-        Category.SECURITY,
-        6,
-        Severity.WARNING,
-        IMPLEMENTATION);
-
-    /** Method result should be used */
-    public static final Issue MISSING_PERMISSION = Issue.create(
-            "MissingPermission", //$NON-NLS-1$
-            "Missing Permissions",
-
-            "This check scans through your code and libraries and looks at the APIs being used, " +
-            "and checks this against the set of permissions required to access those APIs. If " +
-            "the code using those APIs is called at runtime, then the program will crash.\n" +
-            "\n" +
-            "Furthermore, for permissions that are revocable (with targetSdkVersion 23), client " +
-            "code must also be prepared to handle the calls throwing an exception if the user " +
-            "rejects the request for permission at runtime.",
-
-            Category.CORRECTNESS,
-            9,
-            Severity.ERROR,
-            IMPLEMENTATION);
-
-    /** Passing the wrong constant to an int or String method */
-    public static final Issue THREAD = Issue.create(
-            "WrongThread", //$NON-NLS-1$
-            "Wrong Thread",
-
-            "Ensures that a method which expects to be called on a specific thread, is actually " +
-            "called from that thread. For example, calls on methods in widgets should always " +
-            "be made on the UI thread.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.ERROR,
-            IMPLEMENTATION)
-            .addMoreInfo(
-                    "http://developer.android.com/guide/components/processes-and-threads.html#Threads");
-
-    public static final String CHECK_RESULT_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "CheckResult"; //$NON-NLS-1$
-    public static final String INT_RANGE_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "IntRange"; //$NON-NLS-1$
-    public static final String FLOAT_RANGE_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "FloatRange"; //$NON-NLS-1$
-    public static final String SIZE_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "Size"; //$NON-NLS-1$
-    public static final String PERMISSION_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "RequiresPermission"; //$NON-NLS-1$
-    public static final String UI_THREAD_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "UiThread"; //$NON-NLS-1$
-    public static final String MAIN_THREAD_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "MainThread"; //$NON-NLS-1$
-    public static final String WORKER_THREAD_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "WorkerThread"; //$NON-NLS-1$
-    public static final String BINDER_THREAD_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "BinderThread"; //$NON-NLS-1$
-    public static final String ANY_THREAD_ANNOTATION = SUPPORT_ANNOTATIONS_PREFIX + "AnyThread"; //$NON-NLS-1$
-    public static final String PERMISSION_ANNOTATION_READ = PERMISSION_ANNOTATION + ".Read"; //$NON-NLS-1$
-    public static final String PERMISSION_ANNOTATION_WRITE = PERMISSION_ANNOTATION + ".Write"; //$NON-NLS-1$
-
-    public static final String THREAD_SUFFIX = "Thread";
-    public static final String ATTR_SUGGEST = "suggest";
-    public static final String ATTR_TO = "to";
-    public static final String ATTR_FROM = "from";
-    public static final String ATTR_FROM_INCLUSIVE = "fromInclusive";
-    public static final String ATTR_TO_INCLUSIVE = "toInclusive";
-    public static final String ATTR_MULTIPLE = "multiple";
-    public static final String ATTR_MIN = "min";
-    public static final String ATTR_MAX = "max";
-    public static final String ATTR_ALL_OF = "allOf";
-    public static final String ATTR_ANY_OF = "anyOf";
-    public static final String ATTR_CONDITIONAL = "conditional";
-
-    public static final String SECURITY_EXCEPTION = "java.lang.SecurityException";
-
-    /**
-     * Constructs a new {@link SupportAnnotationDetector} check
-     */
-    public SupportAnnotationDetector() {
-    }
-
-    private void checkMethodAnnotation(
-            @NonNull JavaContext context,
-            @NonNull PsiMethod method,
-            @NonNull UCallExpression call,
-            @NonNull UAnnotation annotation,
-            @NonNull List<UAnnotation> allMethodAnnotations,
-            @NonNull List<UAnnotation> allClassAnnotations) {
-        String signature = annotation.getQualifiedName();
-        if (signature == null) {
-            return;
-        }
-        if (CHECK_RESULT_ANNOTATION.equals(signature)
-                // support findbugs annotation too
-                || signature.endsWith(".CheckReturnValue")) {
-            checkResult(context, call, method, annotation);
-        } else if (signature.equals(PERMISSION_ANNOTATION)) {
-            PermissionRequirement requirement = PermissionRequirement.create(annotation);
-            checkPermission(context, call, method, null, requirement);
-        } else if (signature.endsWith(THREAD_SUFFIX)
-                && signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) {
-            checkThreading(context, call, method, signature, annotation, allMethodAnnotations,
-                    allClassAnnotations);
-        }
-    }
-
-    private void checkParameterAnnotations(
-            @NonNull JavaContext context,
-            @NonNull UExpression argument,
-            @NonNull UCallExpression call,
-            @NonNull PsiMethod method,
-            @NonNull List<UAnnotation> annotations) {
-        boolean handledResourceTypes = false;
-        for (UAnnotation annotation : annotations) {
-            String signature = annotation.getQualifiedName();
-            if (signature == null) {
-                continue;
-            }
-
-            if (COLOR_INT_ANNOTATION.equals(signature)) {
-                checkColor(context, argument);
-            } else if (signature.equals(PX_ANNOTATION)) {
-                checkPx(context, argument);
-            } else if (signature.equals(INT_RANGE_ANNOTATION)) {
-                checkIntRange(context, annotation, argument, annotations);
-            } else if (signature.equals(FLOAT_RANGE_ANNOTATION)) {
-                checkFloatRange(context, annotation, argument);
-            } else if (signature.equals(SIZE_ANNOTATION)) {
-                checkSize(context, annotation, argument);
-            } else if (signature.startsWith(PERMISSION_ANNOTATION)) {
-                // PERMISSION_ANNOTATION, PERMISSION_ANNOTATION_READ, PERMISSION_ANNOTATION_WRITE
-                // When specified on a parameter, that indicates that we're dealing with
-                // a permission requirement on this *method* which depends on the value
-                // supplied by this parameter
-                checkParameterPermission(context, signature, call, method, argument);
-            } else {
-                // We only run @IntDef, @StringDef and @<Type>Res checks if we're not
-                // running inside Android Studio / IntelliJ where there are already inspections
-                // covering the same warnings (using IntelliJ's own data flow analysis); we
-                // don't want to (a) create redundant warnings or (b) work harder than we
-                // have to
-                if (signature.equals(INT_DEF_ANNOTATION)) {
-                    boolean flag = getAnnotationBooleanValue(annotation, TYPE_DEF_FLAG_ATTRIBUTE) == Boolean.TRUE;
-                    checkTypeDefConstant(context, annotation, argument, null, flag,
-                            annotations);
-                } else if (signature.equals(STRING_DEF_ANNOTATION)) {
-                    checkTypeDefConstant(context, annotation, argument, null, false,
-                            annotations);
-                } else if (signature.endsWith(RES_SUFFIX)) {
-                    if (handledResourceTypes) {
-                        continue;
-                    }
-                    handledResourceTypes = true;
-                    EnumSet<ResourceType> types = null;
-                    // Handle all resource type annotations in one go: there could be multiple
-                    // resource type annotations specified on the same element; we need to
-                    // know about them all up front.
-                    for (UAnnotation a : annotations) {
-                        String s = a.getQualifiedName();
-                        if (s != null && s.endsWith(RES_SUFFIX)) {
-                            String typeString = s.substring(SUPPORT_ANNOTATIONS_PREFIX.length(),
-                                    s.length() - RES_SUFFIX.length()).toLowerCase(Locale.US);
-                            ResourceType type = ResourceType.getEnum(typeString);
-                            if (type != null) {
-                                if (types == null) {
-                                    types = EnumSet.of(type);
-                                } else {
-                                    types.add(type);
-                                }
-                            } else if (typeString.equals("any")) { // @AnyRes
-                                types = getAnyRes();
-                                break;
-                            }
-                        }
-                    }
-
-                    if (types != null) {
-                        checkResourceType(context, argument, types, call, method);
-                    }
-                }
-            }
-        }
-    }
-
-    private static EnumSet<ResourceType> getAnyRes() {
-        EnumSet<ResourceType> types = EnumSet.allOf(ResourceType.class);
-        types.remove(ResourceEvaluator.COLOR_INT_MARKER_TYPE);
-        types.remove(ResourceEvaluator.PX_MARKER_TYPE);
-        return types;
-    }
-
-    private void checkParameterPermission(
-            @NonNull JavaContext context,
-            @NonNull String signature,
-            @NonNull UElement call,
-            @NonNull PsiMethod method,
-            @NonNull UExpression argument) {
-        Operation operation = null;
-        if (signature.equals(PERMISSION_ANNOTATION_READ)) {
-            operation = READ;
-        } else if (signature.equals(PERMISSION_ANNOTATION_WRITE)) {
-            operation = WRITE;
-        } else {
-            PsiType type = argument.getExpressionType();
-            if (type != null && CLASS_INTENT.equals(type.getCanonicalText())) {
-                operation = ACTION;
-            }
-        }
-        if (operation == null) {
-            return;
-        }
-        Result result = PermissionFinder.findRequiredPermissions(operation, context, argument);
-        if (result != null) {
-            checkPermission(context, call, method, result, result.requirement);
-        }
-    }
-
-    private static void checkColor(@NonNull JavaContext context, @NonNull UElement argument) {
-        if (argument instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) argument;
-            if (expression.getThenExpression() != null) {
-                checkColor(context, expression.getThenExpression());
-            }
-            if (expression.getElseExpression() != null) {
-                checkColor(context, expression.getElseExpression());
-            }
-            return;
-        }
-
-        EnumSet<ResourceType> types = ResourceEvaluator.getResourceTypes(context, argument);
-
-        if (types != null && types.contains(COLOR)
-                && !isIgnoredInIde(COLOR_USAGE, context, argument)) {
-            String message = String.format(
-                    "Should pass resolved color instead of resource id here: " +
-                            "`getResources().getColor(%1$s)`", argument.asSourceString());
-            context.report(COLOR_USAGE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    private static void checkPx(@NonNull JavaContext context, @NonNull UElement argument) {
-        if (argument instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) argument;
-            if (expression.getThenExpression() != null) {
-                checkPx(context, expression.getThenExpression());
-            }
-            if (expression.getElseExpression() != null) {
-                checkPx(context, expression.getElseExpression());
-            }
-            return;
-        }
-
-        EnumSet<ResourceType> types = ResourceEvaluator.getResourceTypes(context, argument);
-
-        if (types != null && types.contains(DIMEN)) {
-            String message = String.format(
-              "Should pass resolved pixel dimension instead of resource id here: " +
-                "`getResources().getDimension*(%1$s)`", argument.asSourceString());
-            context.report(COLOR_USAGE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    private static boolean isIgnoredInIde(@NonNull Issue issue, @NonNull JavaContext context,
-            @NonNull UElement node) {
-        // Historically, the IDE would treat *all* support annotation warnings as
-        // handled by the id "ResourceType", so look for that id too for issues
-        // deliberately suppressed prior to Android Studio 2.0.
-        Issue synonym = Issue.create("ResourceType", issue.getBriefDescription(TextFormat.RAW),
-                issue.getExplanation(TextFormat.RAW), issue.getCategory(), issue.getPriority(),
-                issue.getDefaultSeverity(), issue.getImplementation());
-        return context.getDriver().isSuppressed(context, synonym, node);
-    }
-
-    private void checkPermission(
-            @NonNull JavaContext context,
-            @NonNull UElement node,
-            @Nullable PsiMethod method,
-            @Nullable Result result,
-            @NonNull PermissionRequirement requirement) {
-        if (requirement.isConditional()) {
-            return;
-        }
-        PermissionHolder permissions = getPermissions(context);
-        if (!requirement.isSatisfied(permissions)) {
-            // See if it looks like we're holding the permission implicitly by @RequirePermission
-            // annotations in the surrounding context
-            permissions  = addLocalPermissions(permissions, node);
-            if (!requirement.isSatisfied(permissions)) {
-                if (isIgnoredInIde(MISSING_PERMISSION, context, node)) {
-                    return;
-                }
-                Operation operation;
-                String name;
-                if (result != null) {
-                    name = result.name;
-                    operation = result.operation;
-                } else {
-                    assert method != null;
-                    PsiClass containingClass = method.getContainingClass();
-                    if (containingClass != null) {
-                        name = containingClass.getName() + "." + method.getName();
-                    } else {
-                        name = method.getName();
-                    }
-                    operation = Operation.CALL;
-                }
-                String message = getMissingPermissionMessage(requirement, name, permissions,
-                        operation);
-                context.report(MISSING_PERMISSION, node, context.getUastLocation(node), message);
-            }
-        } else if (requirement.isRevocable(permissions) &&
-                context.getMainProject().getTargetSdkVersion().getFeatureLevel() >= 23) {
-
-            boolean handlesMissingPermission = handlesSecurityException(node);
-
-            // If not, check to see if the code is deliberately checking to see if the
-            // given permission is available.
-            if (!handlesMissingPermission) {
-                UMethod methodNode = UastUtils.getParentOfType(node, UMethod.class, true);
-                if (methodNode != null) {
-                    CheckPermissionVisitor visitor = new CheckPermissionVisitor(node);
-                    methodNode.accept(visitor);
-                    handlesMissingPermission = visitor.checksPermission();
-                }
-            }
-
-            if (!handlesMissingPermission && !isIgnoredInIde(MISSING_PERMISSION, context, node)) {
-                String message = getUnhandledPermissionMessage();
-                context.report(MISSING_PERMISSION, node, context.getUastLocation(node), message);
-            }
-        }
-    }
-
-    private static boolean handlesSecurityException(@NonNull UElement node) {
-        // Ensure that the caller is handling a security exception
-        // First check to see if we're inside a try/catch which catches a SecurityException
-        // (or some wider exception than that). Check for nested try/catches too.
-        UElement parent = node;
-        while (true) {
-            UTryExpression tryCatch = UastUtils.getParentOfType(parent, UTryExpression.class, true);
-            if (tryCatch == null) {
-                break;
-            } else {
-                for (UCatchClause catchClause : tryCatch.getCatchClauses()) {
-                    if (containsSecurityException(catchClause.getTypes())) {
-                        return true;
-                    }
-                }
-
-                parent = tryCatch;
-            }
-        }
-
-        // If not, check to see if the method itself declares that it throws a
-        // SecurityException or something wider.
-        UMethod declaration = UastUtils.getParentOfType(parent, UMethod.class, false);
-        if (declaration != null) {
-            PsiClassType[] thrownTypes = declaration.getThrowsList().getReferencedTypes();
-            if (containsSecurityException(Arrays.asList(thrownTypes))) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @NonNull
-    private static PermissionHolder addLocalPermissions(
-            @NonNull PermissionHolder permissions,
-            @NonNull UElement node
-    ) {
-        // Accumulate @RequirePermissions available in the local context
-        UMethod method = UastUtils.getParentOfType(node, UMethod.class, true);
-        if (method == null) {
-            return permissions;
-        }
-        UAnnotation annotation = method.findAnnotation(PERMISSION_ANNOTATION);
-        permissions = mergeAnnotationPermissions(permissions, annotation);
-
-        UClass containingClass = UastUtils.getContainingUClass(method);
-        if (containingClass != null) {
-            annotation = containingClass.findAnnotation(PERMISSION_ANNOTATION);
-            permissions = mergeAnnotationPermissions(permissions, annotation);
-        }
-        return permissions;
-    }
-
-    @NonNull
-    private static PermissionHolder mergeAnnotationPermissions(
-            @NonNull PermissionHolder permissions,
-            @Nullable UAnnotation annotation
-    ) {
-        if (annotation != null) {
-            PermissionRequirement requirement = PermissionRequirement.create(annotation);
-            permissions = SetPermissionLookup.join(permissions, requirement);
-        }
-
-        return permissions;
-    }
-
-    /** Returns the error message shown when a given call is missing one or more permissions */
-    public static String getMissingPermissionMessage(@NonNull PermissionRequirement requirement,
-            @NonNull String callName, @NonNull PermissionHolder permissions,
-            @NonNull Operation operation) {
-        return String.format("Missing permissions required %1$s %2$s: %3$s", operation.prefix(),
-                callName, requirement.describeMissingPermissions(permissions));
-    }
-
-    /** Returns the error message shown when a revocable permission call is not properly handled */
-    public static String getUnhandledPermissionMessage() {
-        return "Call requires permission which may be rejected by user: code should explicitly "
-                + "check to see if permission is available (with `checkPermission`) or explicitly "
-                + "handle a potential `SecurityException`";
-    }
-
-    /**
-     * Visitor which looks through a method, up to a given call (the one requiring a
-     * permission) and checks whether it's preceeded by a call to checkPermission or
-     * checkCallingPermission or enforcePermission etc.
-     * <p>
-     * Currently it only looks for the presence of this check; it does not perform
-     * flow analysis to determine whether the check actually affects program flow
-     * up to the permission call, or whether the check permission is checking for
-     * permissions sufficient to satisfy the permission requirement of the target call,
-     * or whether the check return value (== PERMISSION_GRANTED vs != PERMISSION_GRANTED)
-     * is handled correctly, etc.
-     */
-    private static class CheckPermissionVisitor extends AbstractUastVisitor {
-        private boolean mChecksPermission;
-        private boolean mDone;
-        private final UElement mTarget;
-
-        public CheckPermissionVisitor(@NonNull UElement target) {
-            mTarget = target;
-        }
-
-        @Override
-        public boolean visitElement(UElement node) {
-            return mDone || super.visitElement(node);
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (UastExpressionUtils.isMethodCall(node)) {
-                visitMethodCallExpression(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void visitMethodCallExpression(UCallExpression node) {
-            if (node == mTarget) {
-                mDone = true;
-            }
-
-            String name = node.getMethodName();
-            if (name != null
-                    && (name.startsWith("check") || name.startsWith("enforce"))
-                    && name.endsWith("Permission")) {
-                mChecksPermission = true;
-                mDone = true;
-            }
-        }
-
-        public boolean checksPermission() {
-            return mChecksPermission;
-        }
-    }
-
-    private static boolean containsSecurityException(
-            @NonNull List<? extends PsiType> types) {
-        for (PsiType type : types) {
-            if (type instanceof PsiClassType) {
-                PsiClass cls = ((PsiClassType) type).resolve();
-                // In earlier versions we checked not just for java.lang.SecurityException but
-                // any super type as well, however that probably hides warnings in cases where
-                // users don't want that; see http://b.android.com/182165
-                //return context.getEvaluator().extendsClass(cls, "java.lang.SecurityException", false);
-                if (cls != null && SECURITY_EXCEPTION.equals(cls.getQualifiedName())) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private PermissionHolder mPermissions;
-
-    private PermissionHolder getPermissions(
-            @NonNull JavaContext context) {
-        if (mPermissions == null) {
-            Set<String> permissions = Sets.newHashSetWithExpectedSize(30);
-            Set<String> revocable = Sets.newHashSetWithExpectedSize(4);
-            LintClient client = context.getClient();
-            // Gather permissions from all projects that contribute to the
-            // main project.
-            Project mainProject = context.getMainProject();
-            for (File manifest : mainProject.getManifestFiles()) {
-                addPermissions(client, permissions, revocable, manifest);
-            }
-            for (Project library : mainProject.getAllLibraries()) {
-                for (File manifest : library.getManifestFiles()) {
-                    addPermissions(client, permissions, revocable, manifest);
-                }
-            }
-
-            AndroidVersion minSdkVersion = mainProject.getMinSdkVersion();
-            AndroidVersion targetSdkVersion = mainProject.getTargetSdkVersion();
-            mPermissions = new SetPermissionLookup(permissions, revocable, minSdkVersion,
-                targetSdkVersion);
-        }
-
-        return mPermissions;
-    }
-
-    private static void addPermissions(@NonNull LintClient client,
-            @NonNull Set<String> permissions,
-            @NonNull Set<String> revocable,
-            @NonNull File manifest) {
-        Document document = XmlUtils.parseDocumentSilently(client.readFile(manifest), true);
-        if (document == null) {
-            return;
-        }
-        Element root = document.getDocumentElement();
-        if (root == null) {
-            return;
-        }
-        NodeList children = root.getChildNodes();
-        for (int i = 0, n = children.getLength(); i < n; i++) {
-            Node item = children.item(i);
-            if (item.getNodeType() != Node.ELEMENT_NODE) {
-                continue;
-            }
-            String nodeName = item.getNodeName();
-            if (nodeName.equals(TAG_USES_PERMISSION)
-                || nodeName.equals(TAG_USES_PERMISSION_SDK_23)
-                || nodeName.equals(TAG_USES_PERMISSION_SDK_M)) {
-                Element element = (Element)item;
-                String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                if (!name.isEmpty()) {
-                    permissions.add(name);
-                }
-            } else if (nodeName.equals(TAG_PERMISSION)) {
-                Element element = (Element)item;
-                String protectionLevel = element.getAttributeNS(ANDROID_URI,
-                        ATTR_PROTECTION_LEVEL);
-                if (VALUE_DANGEROUS.equals(protectionLevel)) {
-                    String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-                    if (!name.isEmpty()) {
-                        revocable.add(name);
-                    }
-                }
-            }
-        }
-    }
-    
-    private static void checkResult(@NonNull JavaContext context, @NonNull UCallExpression node,
-            @NonNull PsiMethod method, @NonNull UAnnotation annotation) {
-        if (isExpressionValueUnused(node)) {
-            String methodName = JavaContext.getMethodName(node);
-            String suggested = getAnnotationStringValue(annotation, ATTR_SUGGEST);
-
-            // Failing to check permissions is a potential security issue (and had an existing
-            // dedicated issue id before which people may already have configured with a
-            // custom severity in their LintOptions etc) so continue to use that issue
-            // (which also has category Security rather than Correctness) for these:
-            Issue issue = CHECK_RESULT;
-            if (methodName != null && methodName.startsWith("check")
-                    && methodName.contains("Permission")) {
-                issue = CHECK_PERMISSION;
-            }
-
-            if (isIgnoredInIde(issue, context, node)) {
-                return;
-            }
-
-            String message = String.format("The result of `%1$s` is not used",
-                    methodName);
-            if (suggested != null) {
-                // TODO: Resolve suggest attribute (e.g. prefix annotation class if it starts
-                // with "#" etc?
-                message = String.format(
-                        "The result of `%1$s` is not used; did you mean to call `%2$s`?",
-                        methodName, suggested);
-            } else if ("intersect".equals(methodName)
-                    && context.getEvaluator().isMemberInClass(method, "android.graphics.Rect")) {
-                message += ". If the rectangles do not intersect, no change is made and the "
-                        + "original rectangle is not modified. These methods return false to "
-                        + "indicate that this has happened.";
-            }
-            context.report(issue, node, context.getUastLocation(node), message);
-        }
-    }
-
-    private static boolean isExpressionValueUnused(UExpression expression) {
-        return getQualifiedParentOrThis(expression).getUastParent()
-                instanceof UBlockExpression;
-    }
-
-    private static void checkThreading(
-            @NonNull JavaContext context,
-            @NonNull UElement node,
-            @NonNull PsiMethod method,
-            @NonNull String signature,
-            @NonNull UAnnotation annotation,
-            @NonNull List<UAnnotation> allMethodAnnotations,
-            @NonNull List<UAnnotation> allClassAnnotations) {
-        List<String> threadContext = getThreadContext(context, node);
-        if (threadContext != null && !isCompatibleThread(threadContext, signature)
-                && !isIgnoredInIde(THREAD, context, node)) {
-            // If the annotation is specified on the class, ignore this requirement
-            // if there is another annotation specified on the method.
-            if (containsAnnotation(allClassAnnotations, annotation)) {
-                if (containsThreadingAnnotation(allMethodAnnotations)) {
-                    return;
-                }
-                // Make sure ALL the other context annotations are acceptable!
-            } else {
-                assert containsAnnotation(allMethodAnnotations, annotation);
-                // See if any of the *other* annotations are compatible.
-                Boolean isFirst = null;
-                for (UAnnotation other : allMethodAnnotations) {
-                    if (other == annotation) {
-                        if (isFirst == null) {
-                            isFirst = true;
-                        }
-                        continue;
-                    } else if (!isThreadingAnnotation(other)) {
-                        continue;
-                    }
-                    if (isFirst == null) {
-                        // We'll be called for each annotation on the method.
-                        // For each one we're checking *all* annotations on the target.
-                        // Therefore, when we're seeing the second, third, etc annotation
-                        // on the method we've already checked them, so return here.
-                        return;
-                    }
-                    String s = other.getQualifiedName();
-                    if (s != null && isCompatibleThread(threadContext, s)) {
-                        return;
-                    }
-                }
-            }
-
-            String name = method.getName();
-            if ((name.startsWith("post") )
-                && context.getEvaluator().isMemberInClass(method, CLASS_VIEW)) {
-                // The post()/postDelayed() methods are (currently) missing
-                // metadata (@AnyThread); they're on a class marked @UiThread
-                // but these specific methods are not @UiThread.
-                return;
-            }
-
-            List<String> targetThreads = getThreads(context, method);
-            if (targetThreads == null) {
-                targetThreads = Collections.singletonList(signature);
-            }
-
-            String message = String.format(
-                 "%1$s %2$s must be called from the `%3$s` thread, currently inferred thread is `%4$s` thread",
-                 method.isConstructor() ? "Constructor" : "Method",
-                 method.getName(), describeThreads(targetThreads, true),
-                 describeThreads(threadContext, false));
-            context.report(THREAD, node, context.getUastLocation(node), message);
-        }
-    }
-
-    public static boolean containsAnnotation(
-            @NonNull List<UAnnotation> array,
-            @NonNull UAnnotation annotation) {
-        for (UAnnotation a : array) {
-            if (a == annotation) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public static boolean containsThreadingAnnotation(@NonNull List<UAnnotation> array) {
-        for (UAnnotation annotation : array) {
-            if (isThreadingAnnotation(annotation)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public static boolean isThreadingAnnotation(@NonNull UAnnotation annotation) {
-        String signature = annotation.getQualifiedName();
-        return signature != null
-                && signature.endsWith(THREAD_SUFFIX)
-                && signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX);
-    }
-
-    @NonNull
-    public static String describeThreads(@NonNull List<String> annotations, boolean any) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < annotations.size(); i++) {
-            if (i > 0) {
-                if (i == annotations.size() - 1) {
-                    if (any) {
-                        sb.append(" or ");
-                    } else {
-                        sb.append(" and ");
-                    }
-                } else {
-                    sb.append(", ");
-                }
-            }
-            sb.append(describeThread(annotations.get(i)));
-        }
-        return sb.toString();
-    }
-
-    @NonNull
-    public static String describeThread(@NonNull String annotation) {
-        if (annotation.equals(UI_THREAD_ANNOTATION)) {
-            return "UI";
-        }
-        else if (annotation.equals(MAIN_THREAD_ANNOTATION)) {
-            return "main";
-        }
-        else if (annotation.equals(BINDER_THREAD_ANNOTATION)) {
-            return "binder";
-        }
-        else if (annotation.equals(WORKER_THREAD_ANNOTATION)) {
-            return "worker";
-        }
-        else if (annotation.equals(ANY_THREAD_ANNOTATION)) {
-            return "any";
-        }
-        else {
-            return "other";
-        }
-    }
-
-    /** returns true if the two threads are compatible */
-    public static boolean isCompatibleThread(@NonNull List<String> callers,
-            @NonNull String callee) {
-        // ALL calling contexts must be valid
-        assert !callers.isEmpty();
-        for (String caller : callers) {
-            if (!isCompatibleThread(caller, callee)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /** returns true if the two threads are compatible */
-    public static boolean isCompatibleThread(@NonNull String caller, @NonNull String callee) {
-        if (callee.equals(caller)) {
-            return true;
-        }
-
-        if (callee.equals(ANY_THREAD_ANNOTATION)) {
-            return true;
-        }
-
-        // Allow @UiThread and @MainThread to be combined
-        if (callee.equals(UI_THREAD_ANNOTATION)) {
-            if (caller.equals(MAIN_THREAD_ANNOTATION)) {
-                return true;
-            }
-        } else if (callee.equals(MAIN_THREAD_ANNOTATION)) {
-            if (caller.equals(UI_THREAD_ANNOTATION)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /** Attempts to infer the current thread context at the site of the given method call */
-    @Nullable
-    private static List<String> getThreadContext(@NonNull JavaContext context,
-            @NonNull UElement methodCall) {
-        //noinspection unchecked
-        PsiMethod method = UastUtils.getParentOfType(methodCall, UMethod.class, true,
-                UAnonymousClass.class);
-        return getThreads(context, method);
-    }
-
-    /** Attempts to infer the current thread context at the site of the given method call */
-    @Nullable
-    private static List<String> getThreads(@NonNull JavaContext context,
-            @Nullable PsiMethod method) {
-        if (method != null) {
-            List<String> result = null;
-            PsiClass cls = method.getContainingClass();
-
-            while (method != null) {
-                for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
-                    String name = annotation.getQualifiedName();
-                    if (name != null && name.startsWith(SUPPORT_ANNOTATIONS_PREFIX)
-                            && name.endsWith(THREAD_SUFFIX)) {
-                        if (result == null) {
-                            result = new ArrayList<String>(4);
-                        }
-                        result.add(name);
-                    }
-                }
-                if (result != null) {
-                    // We don't accumulate up the chain: one method replaces the requirements
-                    // of its super methods.
-                    return result;
-                }
-                method = context.getEvaluator().getSuperMethod(method);
-            }
-
-            // See if we're extending a class with a known threading context
-            while (cls != null) {
-                PsiModifierList modifierList = cls.getModifierList();
-                if (modifierList != null) {
-                    for (PsiAnnotation annotation : modifierList.getAnnotations()) {
-                        String name = annotation.getQualifiedName();
-                        if (name != null && name.startsWith(SUPPORT_ANNOTATIONS_PREFIX)
-                                && name.endsWith(THREAD_SUFFIX)) {
-                            if (result == null) {
-                                result = new ArrayList<String>(4);
-                            }
-                            result.add(name);
-                        }
-                    }
-                    if (result != null) {
-                        // We don't accumulate up the chain: one class replaces the requirements
-                        // of its super classes.
-                        return result;
-                    }
-                }
-                cls = cls.getSuperClass();
-            }
-        }
-
-        // In the future, we could also try to infer the threading context using
-        // other heuristics. For example, if we're in a method with unknown threading
-        // context, but we see that the method is called by another method with a known
-        // threading context, we can infer that that threading context is the context for
-        // this thread too (assuming the call is direct).
-
-        return null;
-    }
-
-    private static boolean isNumber(@NonNull UElement argument) {
-        if (argument instanceof ULiteralExpression) {
-            Object value = ((ULiteralExpression) argument).getValue();
-            return value instanceof Number;
-        } else if (argument instanceof UPrefixExpression) {
-            UPrefixExpression expression = (UPrefixExpression) argument;
-            UExpression operand = expression.getOperand();
-            return isNumber(operand);
-        } else {
-            return false;
-        }
-    }
-
-    private static boolean isZero(@NonNull UElement argument) {
-        if (argument instanceof ULiteralExpression) {
-            Object value = ((ULiteralExpression) argument).getValue();
-            return value instanceof Number && ((Number)value).intValue() == 0;
-        }
-        return false;
-    }
-
-    private static boolean isMinusOne(@NonNull UElement argument) {
-        if (argument instanceof UPrefixExpression) {
-            UPrefixExpression expression = (UPrefixExpression) argument;
-            UExpression operand = expression.getOperand();
-            if (operand instanceof ULiteralExpression &&
-                    expression.getOperator() == UastPrefixOperator.UNARY_MINUS) {
-                Object value = ((ULiteralExpression) operand).getValue();
-                return value instanceof Number && ((Number) value).intValue() == 1;
-            } else {
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    private static void checkResourceType(
-            @NonNull JavaContext context,
-            @NonNull UElement argument,
-            @NonNull EnumSet<ResourceType> expectedType,
-            @NonNull UCallExpression call,
-            @NonNull PsiMethod calledMethod) {
-        EnumSet<ResourceType> actual = ResourceEvaluator.getResourceTypes(context, argument);
-
-        if (actual == null && (!isNumber(argument) || isZero(argument) || isMinusOne(argument)) ) {
-            return;
-        } else if (actual != null && (!Sets.intersection(actual, expectedType).isEmpty()
-                || expectedType.contains(DRAWABLE)
-                && (actual.contains(COLOR) || actual.contains(MIPMAP)))) {
-            return;
-        }
-
-        if (isIgnoredInIde(RESOURCE_TYPE, context, argument)) {
-            return;
-        }
-
-        if (expectedType.contains(ResourceType.STYLEABLE) && (expectedType.size() == 1)
-                && JavaEvaluator.isMemberInClass(calledMethod,
-                        "android.content.res.TypedArray")
-                && typeArrayFromArrayLiteral(call.getReceiver(), context)) {
-            // You're generally supposed to provide a styleable to the TypedArray methods,
-            // but you're also allowed to supply an integer array
-            return;
-        }
-
-        String message;
-        if (actual != null && actual.size() == 1 && actual.contains(
-                ResourceEvaluator.COLOR_INT_MARKER_TYPE)) {
-            message = "Expected a color resource id (`R.color.`) but received an RGB integer";
-        } else if (expectedType.contains(ResourceEvaluator.COLOR_INT_MARKER_TYPE)) {
-            message = String.format("Should pass resolved color instead of resource id here: " +
-              "`getResources().getColor(%1$s)`", argument.asSourceString());
-        } else if (actual != null && actual.size() == 1 && actual.contains(
-          ResourceEvaluator.PX_MARKER_TYPE)) {
-            message = "Expected a dimension resource id (`R.color.`) but received a pixel integer";
-        } else if (expectedType.contains(ResourceEvaluator.PX_MARKER_TYPE)) {
-            message = String.format("Should pass resolved pixel size instead of resource id here: " +
-              "`getResources().getDimension*(%1$s)`", argument.asSourceString());
-        } else if (expectedType.size() < ResourceType.getNames().length - 2) { // -2: marker types
-            message = String.format("Expected resource of type %1$s",
-                    Joiner.on(" or ").join(expectedType));
-        } else {
-            message = "Expected resource identifier (`R`.type.`name`)";
-        }
-        context.report(RESOURCE_TYPE, argument, context.getUastLocation(argument), message);
-    }
-
-    /**
-     * Returns true if the node is pointing to a TypedArray whose value was obtained
-     * from an array literal
-     */
-    public static boolean typeArrayFromArrayLiteral(
-            @Nullable UElement node, @NonNull JavaContext context) {
-        if (isMethodCall(node)) {
-            UCallExpression expression = (UCallExpression) node;
-            assert expression != null;
-            String name = expression.getMethodName();
-            if (name != null && "obtainStyledAttributes".equals(name)) {
-                List<UExpression> expressions = expression.getValueArguments();
-                if (!expressions.isEmpty()) {
-                    int arg;
-                    if (expressions.size() == 1) {
-                        // obtainStyledAttributes(int[] attrs)
-                        arg = 0;
-                    } else if (expressions.size() == 2) {
-                        // obtainStyledAttributes(AttributeSet set, int[] attrs)
-                        // obtainStyledAttributes(int resid, int[] attrs)
-                        for (arg = 0; arg < expressions.size(); arg++) {
-                            PsiType type = expressions.get(arg).getExpressionType();
-                            if (type instanceof PsiArrayType) {
-                                break;
-                            }
-                        }
-                        if (arg == expressions.size()) {
-                            return false;
-                        }
-                    } else if (expressions.size() == 4) {
-                        // obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
-                        arg = 1;
-                    } else {
-                        return false;
-                    }
-
-                    return ConstantEvaluator.isArrayLiteral(expressions.get(arg), context);
-                }
-            }
-            return false;
-        } else if (node instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) node).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-                UExpression lastAssignment = 
-                        UastLintUtils.findLastAssignment(variable, node, context);
-
-                if (lastAssignment != null) {
-                    return typeArrayFromArrayLiteral(lastAssignment, context);
-                }
-            }
-        } else if (UastExpressionUtils.isNewArrayWithInitializer(node)) {
-            return true;
-        } else if (UastExpressionUtils.isNewArrayWithDimensions(node)) {
-            return true;
-        } else if (node instanceof UParenthesizedExpression) {
-            UParenthesizedExpression parenthesizedExpression = (UParenthesizedExpression) node;
-            UExpression expression = parenthesizedExpression.getExpression();
-            return typeArrayFromArrayLiteral(expression, context);
-        } else if (UastExpressionUtils.isTypeCast(node)) {
-            UBinaryExpressionWithType castExpression = (UBinaryExpressionWithType) node;
-            assert castExpression != null;
-            UExpression operand = castExpression.getOperand();
-            return typeArrayFromArrayLiteral(operand, context);
-        }
-
-        return false;
-    }
-
-    private static boolean isMethodCall(UElement node) {
-        if (node instanceof UQualifiedReferenceExpression) {
-            UExpression last = getLastInQualifiedChain((UQualifiedReferenceExpression) node);
-            return UastExpressionUtils.isMethodCall(last);
-        }
-
-        return UastExpressionUtils.isMethodCall(node);
-    }
-
-    @NonNull
-    private static UExpression getLastInQualifiedChain(@NonNull UQualifiedReferenceExpression node) {
-        UExpression last = node.getSelector();
-        while (last instanceof UQualifiedReferenceExpression) {
-            last = ((UQualifiedReferenceExpression) last).getSelector();
-        }
-        return last;
-    }
-
-    private static void checkIntRange(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @NonNull UElement argument,
-            @NonNull List<UAnnotation> allAnnotations) {
-        String message = getIntRangeError(context, annotation, argument);
-        if (message != null) {
-            if (findIntDef(allAnnotations) != null) {
-                // Don't flag int range errors if there is an int def annotation there too;
-                // there could be a valid @IntDef constant. (The @IntDef check will
-                // perform range validation by calling getIntRange.)
-                return;
-            }
-
-            if (isIgnoredInIde(RANGE, context, argument)) {
-                return;
-            }
-
-            context.report(RANGE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    @Nullable
-    private static String getIntRangeError(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @NonNull UElement argument) {
-        if (UastExpressionUtils.isNewArrayWithInitializer(argument)) {
-            UCallExpression newExpression = (UCallExpression) argument;
-            for (UExpression expression : newExpression.getValueArguments()) {
-                String error = getIntRangeError(context, annotation, expression);
-                if (error != null) {
-                    return error;
-                }
-            }
-        }
-
-        Object object = ConstantEvaluator.evaluate(context, argument);
-        if (!(object instanceof Number)) {
-            return null;
-        }
-        long value = ((Number)object).longValue();
-        long from = getLongAttribute(annotation, ATTR_FROM, Long.MIN_VALUE);
-        long to = getLongAttribute(annotation, ATTR_TO, Long.MAX_VALUE);
-
-        return getIntRangeError(value, from, to);
-    }
-
-    /**
-     * Checks whether a given integer value is in the allowed range, and if so returns
-     * null; otherwise returns a suitable error message.
-     */
-    private static String getIntRangeError(long value, long from, long to) {
-        String message = null;
-        if (value < from || value > to) {
-            StringBuilder sb = new StringBuilder(20);
-            if (value < from) {
-                sb.append("Value must be \u2265 ");
-                sb.append(Long.toString(from));
-            } else {
-                assert value > to;
-                sb.append("Value must be \u2264 ");
-                sb.append(Long.toString(to));
-            }
-            sb.append(" (was ").append(value).append(')');
-            message = sb.toString();
-        }
-        return message;
-    }
-
-    private static void checkFloatRange(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @NonNull UElement argument) {
-        Object object = ConstantEvaluator.evaluate(context, argument);
-        if (!(object instanceof Number)) {
-            return;
-        }
-        double value = ((Number)object).doubleValue();
-        double from = getDoubleAttribute(annotation, ATTR_FROM, Double.NEGATIVE_INFINITY);
-        double to = getDoubleAttribute(annotation, ATTR_TO, Double.POSITIVE_INFINITY);
-        boolean fromInclusive = getBoolean(annotation, ATTR_FROM_INCLUSIVE, true);
-        boolean toInclusive = getBoolean(annotation, ATTR_TO_INCLUSIVE, true);
-
-        String message = getFloatRangeError(value, from, to, fromInclusive, toInclusive, argument);
-        if (message != null && !isIgnoredInIde(RANGE, context, argument)) {
-            context.report(RANGE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    /**
-     * Checks whether a given floating point value is in the allowed range, and if so returns
-     * null; otherwise returns a suitable error message.
-     */
-    @Nullable
-    private static String getFloatRangeError(double value, double from, double to,
-            boolean fromInclusive, boolean toInclusive, @NonNull UElement node) {
-        if (!((fromInclusive && value >= from || !fromInclusive && value > from) &&
-                (toInclusive && value <= to || !toInclusive && value < to))) {
-            StringBuilder sb = new StringBuilder(20);
-            if (from != Double.NEGATIVE_INFINITY) {
-                if (to != Double.POSITIVE_INFINITY) {
-                    if (fromInclusive && value < from || !fromInclusive && value <= from) {
-                        sb.append("Value must be ");
-                        if (fromInclusive) {
-                            sb.append('\u2265'); // >= sign
-                        } else {
-                            sb.append('>');
-                        }
-                        sb.append(' ');
-                        sb.append(Double.toString(from));
-                    } else {
-                        assert toInclusive && value > to || !toInclusive && value >= to;
-                        sb.append("Value must be ");
-                        if (toInclusive) {
-                            sb.append('\u2264'); // <= sign
-                        } else {
-                            sb.append('<');
-                        }
-                        sb.append(' ');
-                        sb.append(Double.toString(to));
-                    }
-                } else {
-                    sb.append("Value must be ");
-                    if (fromInclusive) {
-                        sb.append('\u2265'); // >= sign
-                    } else {
-                        sb.append('>');
-                    }
-                    sb.append(' ');
-                    sb.append(Double.toString(from));
-                }
-            } else if (to != Double.POSITIVE_INFINITY) {
-                sb.append("Value must be ");
-                if (toInclusive) {
-                    sb.append('\u2264'); // <= sign
-                } else {
-                    sb.append('<');
-                }
-                sb.append(' ');
-                sb.append(Double.toString(to));
-            }
-            sb.append(" (was ");
-            if (node instanceof ULiteralExpression) {
-                // Use source text instead to avoid rounding errors involved in conversion, e.g
-                //    Error: Value must be > 2.5 (was 2.490000009536743) [Range]
-                //    printAtLeastExclusive(2.49f); // ERROR
-                //                          ~~~~~
-                String str = node.asSourceString();
-                if (str.endsWith("f") || str.endsWith("F")) {
-                    str = str.substring(0, str.length() - 1);
-                }
-                sb.append(str);
-            } else {
-                sb.append(value);
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-        return null;
-    }
-
-    private static void checkSize(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @NonNull UElement argument) {
-        int actual;
-        boolean isString = false;
-
-        // TODO: Collections syntax, e.g. Arrays.asList ⇒ param count, emptyList=0, singleton=1, etc
-        // TODO: Flow analysis
-        // No flow analysis for this check yet, only checking literals passed in as parameters
-        
-        if (UastExpressionUtils.isNewArrayWithInitializer(argument)) {
-            actual = ((UCallExpression) argument).getValueArgumentCount();
-        } else {
-            Object object = ConstantEvaluator.evaluate(context, argument);
-            // Check string length
-            if (object instanceof String) {
-                actual = ((String)object).length();
-                isString = true;
-            } else {
-                return;
-            }
-        }
-        long exact = getLongAttribute(annotation, ATTR_VALUE, -1);
-        long min = getLongAttribute(annotation, ATTR_MIN, Long.MIN_VALUE);
-        long max = getLongAttribute(annotation, ATTR_MAX, Long.MAX_VALUE);
-        long multiple = getLongAttribute(annotation, ATTR_MULTIPLE, 1);
-
-        String unit;
-        if (isString) {
-            unit = "length";
-        } else {
-            unit = "size";
-        }
-        String message = getSizeError(actual, exact, min, max, multiple, unit);
-        if (message != null && !isIgnoredInIde(RANGE, context, argument)) {
-            context.report(RANGE, argument, context.getUastLocation(argument), message);
-        }
-    }
-
-    /**
-     * Checks whether a given size follows the given constraints, and if so returns
-     * null; otherwise returns a suitable error message.
-     */
-    private static String getSizeError(long actual, long exact, long min, long max, long multiple,
-            @NonNull String unit) {
-        String message = null;
-        if (exact != -1) {
-            if (exact != actual) {
-                message = String.format("Expected %1$s %2$d (was %3$d)",
-                        unit, exact, actual);
-            }
-        } else if (actual < min || actual > max) {
-            StringBuilder sb = new StringBuilder(20);
-            if (actual < min) {
-                sb.append("Expected ").append(unit).append(" \u2265 ");
-                sb.append(Long.toString(min));
-            } else {
-                assert actual > max;
-                sb.append("Expected ").append(unit).append(" \u2264 ");
-                sb.append(Long.toString(max));
-            }
-            sb.append(" (was ").append(actual).append(')');
-            message = sb.toString();
-        } else if (actual % multiple != 0) {
-            message = String.format("Expected %1$s to be a multiple of %2$d (was %3$d "
-                            + "and should be either %4$d or %5$d)",
-                    unit, multiple, actual, (actual / multiple) * multiple,
-                    (actual / multiple + 1) * multiple);
-        }
-        return message;
-    }
-
-    @Nullable
-    private static UAnnotation findIntRange(
-            @NonNull List<UAnnotation> annotations) {
-        for (UAnnotation annotation : annotations) {
-            if (INT_RANGE_ANNOTATION.equals(annotation.getQualifiedName())) {
-                return annotation;
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    static UAnnotation findIntDef(@NonNull List<UAnnotation> annotations) {
-        for (UAnnotation annotation : annotations) {
-            if (INT_DEF_ANNOTATION.equals(annotation.getQualifiedName())) {
-                return annotation;
-            }
-        }
-
-        return null;
-    }
-
-    private static void checkTypeDefConstant(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @Nullable UElement argument,
-            @Nullable UElement errorNode,
-            boolean flag,
-            @NonNull List<UAnnotation> allAnnotations) {
-        if (argument == null) {
-            return;
-        }
-        if (argument instanceof ULiteralExpression) {
-            Object value = ((ULiteralExpression) argument).getValue();
-            if (value == null) {
-                // Accepted for @StringDef
-                //noinspection UnnecessaryReturnStatement
-                return;
-            } else if (value instanceof String) {
-                String string = (String) value;
-                checkTypeDefConstant(context, annotation, argument, errorNode, false, string,
-                        allAnnotations);
-            } else if (value instanceof Integer || value instanceof Long) {
-                long v = value instanceof Long ? ((Long) value) : ((Integer) value).longValue();
-                if (flag && v == 0) {
-                    // Accepted for a flag @IntDef
-                    return;
-                }
-
-                checkTypeDefConstant(context, annotation, argument, errorNode, flag, value,
-                        allAnnotations);
-            }
-        } else if (isMinusOne(argument)) {
-            // -1 is accepted unconditionally for flags
-            if (!flag) {
-                reportTypeDef(context, annotation, argument, errorNode, allAnnotations);
-            }
-        } else if (argument instanceof UPrefixExpression) {
-            UPrefixExpression expression = (UPrefixExpression) argument;
-            if (flag) {
-                checkTypeDefConstant(context, annotation, expression.getOperand(),
-                        errorNode, true, allAnnotations);
-            } else {
-                UastOperator operator = expression.getOperator();
-                if (operator == UastPrefixOperator.BITWISE_NOT) {
-                    if (isIgnoredInIde(TYPE_DEF, context, expression)) {
-                        return;
-                    }
-                    context.report(TYPE_DEF, expression, context.getUastLocation(expression),
-                            "Flag not allowed here");
-                } else if (operator == UastPrefixOperator.UNARY_MINUS) {
-                    reportTypeDef(context, annotation, argument, errorNode, allAnnotations);
-                }
-            }
-        } else if (argument instanceof UParenthesizedExpression) {
-            UExpression expression = ((UParenthesizedExpression) argument).getExpression();
-            if (expression != null) {
-                checkTypeDefConstant(context, annotation, expression, errorNode, flag, allAnnotations);
-            }
-        } else if (argument instanceof UIfExpression) {
-            UIfExpression expression = (UIfExpression) argument;
-            if (expression.getThenExpression() != null) {
-                checkTypeDefConstant(context, annotation, expression.getThenExpression(), errorNode, flag,
-                        allAnnotations);
-            }
-            if (expression.getElseExpression() != null) {
-                checkTypeDefConstant(context, annotation, expression.getElseExpression(), errorNode, flag,
-                        allAnnotations);
-            }
-        } else if (argument instanceof UBinaryExpression) {
-            // If it's ?: then check both the if and else clauses
-            UBinaryExpression expression = (UBinaryExpression) argument;
-            if (flag) {
-                checkTypeDefConstant(context, annotation, expression.getLeftOperand(), errorNode, true,
-                        allAnnotations);
-                checkTypeDefConstant(context, annotation, expression.getRightOperand(), errorNode, true,
-                        allAnnotations);
-            } else {
-                UastBinaryOperator operator = expression.getOperator();
-                if (operator == UastBinaryOperator.BITWISE_AND
-                        || operator == UastBinaryOperator.BITWISE_OR
-                        || operator == UastBinaryOperator.BITWISE_XOR) {
-                    if (isIgnoredInIde(TYPE_DEF, context, expression)) {
-                        return;
-                    }
-                    context.report(TYPE_DEF, expression, context.getUastLocation(expression),
-                            "Flag not allowed here");
-                }
-            }
-        } if (argument instanceof UReferenceExpression) {
-            PsiElement resolved = ((UReferenceExpression) argument).resolve();
-            if (resolved instanceof PsiVariable) {
-                PsiVariable variable = (PsiVariable) resolved;
-
-                if (variable.getType() instanceof PsiArrayType) {
-                    // It's pointing to an array reference; we can't check these individual
-                    // elements (because we can't jump from ResolvedNodes to AST elements; this
-                    // is part of the motivation for the PSI change in lint 2.0), but we also
-                    // don't want to flag it as invalid.
-                    return;
-                }
-
-                // If it's a constant (static/final) check that it's one of the allowed ones
-                if (variable.hasModifierProperty(PsiModifier.STATIC)
-                        && variable.hasModifierProperty(PsiModifier.FINAL)) {
-                    checkTypeDefConstant(context, annotation, argument,
-                            errorNode != null ? errorNode : argument,
-                            flag, resolved, allAnnotations);
-                } else {
-                    UExpression lastAssignment =
-                            UastLintUtils.findLastAssignment(variable, argument, context);
-
-                    if (lastAssignment != null) {
-                        checkTypeDefConstant(context, annotation,
-                                lastAssignment,
-                                errorNode != null ? errorNode : argument, flag,
-                                allAnnotations);
-                    }
-                }
-            }
-        } else if (UastExpressionUtils.isNewArrayWithInitializer(argument)) {
-            UCallExpression arrayInitializer = (UCallExpression) argument;
-            PsiType type = arrayInitializer.getExpressionType();
-            if (type != null) {
-                type = type.getDeepComponentType();
-            }
-            if (PsiType.INT.equals(type) || PsiType.LONG.equals(type)) {
-                for (UExpression expression : arrayInitializer.getValueArguments()) {
-                    checkTypeDefConstant(context, annotation, expression, errorNode, flag,
-                            allAnnotations);
-                }
-            }
-        }
-    }
-
-    private static void checkTypeDefConstant(@NonNull JavaContext context,
-            @NonNull UAnnotation annotation, @NonNull UElement argument,
-            @Nullable UElement errorNode, boolean flag, Object value,
-            @NonNull List<UAnnotation> allAnnotations) {
-        UAnnotation rangeAnnotation = findIntRange(allAnnotations);
-        if (rangeAnnotation != null) {
-            // Allow @IntRange on this number
-            if (getIntRangeError(context, rangeAnnotation, argument) == null) {
-                return;
-            }
-        }
-
-        UExpression allowed = getAnnotationValue(annotation);
-        if (allowed == null) {
-            return;
-        }
-
-        if (UastExpressionUtils.isArrayInitializer(allowed)) {
-            UCallExpression initializerExpression = (UCallExpression) allowed;
-            List<UExpression> initializers = initializerExpression.getValueArguments();
-            for (UExpression expression : initializers) {
-                if (expression instanceof ULiteralExpression) {
-                    if (value.equals(((ULiteralExpression)expression).getValue())) {
-                        return;
-                    }
-                } else if (expression instanceof ExternalReferenceExpression) {
-                    PsiElement resolved = UastLintUtils.resolve(
-                            (ExternalReferenceExpression) expression, argument);
-                    if (resolved != null && resolved.equals(value)) {
-                        return;
-                    }
-                } else if (expression instanceof UReferenceExpression) {
-                    PsiElement resolved = ((UReferenceExpression) expression).resolve();
-                    if (resolved != null && resolved.equals(value)) {
-                        return;
-                    }
-                }
-            }
-
-            if (value instanceof PsiField) {
-                PsiField astNode = (PsiField)value;
-                UExpression initializer = context.getUastContext().getInitializerBody(astNode);
-                if (initializer != null) {
-                    checkTypeDefConstant(context, annotation, initializer, errorNode,
-                            flag, allAnnotations);
-                    return;
-                }
-            }
-
-            reportTypeDef(context, argument, errorNode, flag,
-                    initializers, allAnnotations);
-        }
-    }
-
-    private static void reportTypeDef(
-            @NonNull JavaContext context,
-            @NonNull UAnnotation annotation,
-            @NonNull UElement argument,
-            @Nullable UElement errorNode,
-            @NonNull List<UAnnotation> allAnnotations
-    ) {
-        //    reportTypeDef(context, argument, errorNode, false, allowedValues, allAnnotations);
-        UExpression allowed = getAnnotationValue(annotation);
-        if (UastExpressionUtils.isArrayInitializer(allowed)) {
-            UCallExpression initializerExpression =
-                    (UCallExpression) allowed;
-            List<UExpression> initializers = initializerExpression.getValueArguments();
-            reportTypeDef(context, argument, errorNode, false, initializers, allAnnotations);
-        }
-    }
-
-    private static void reportTypeDef(@NonNull JavaContext context, @NonNull UElement node,
-            @Nullable UElement errorNode, boolean flag,
-            @NonNull List<UExpression> allowedValues,
-            @NonNull List<UAnnotation> allAnnotations) {
-        if (errorNode == null) {
-            errorNode = node;
-        }
-        if (isIgnoredInIde(TYPE_DEF, context, errorNode)) {
-            return;
-        }
-
-        String values = listAllowedValues(node, allowedValues);
-        String message;
-        if (flag) {
-            message = "Must be one or more of: " + values;
-        } else {
-            message = "Must be one of: " + values;
-        }
-
-        UAnnotation rangeAnnotation = findIntRange(allAnnotations);
-        if (rangeAnnotation != null) {
-            // Allow @IntRange on this number
-            String rangeError = getIntRangeError(context, rangeAnnotation, node);
-            if (rangeError != null && !rangeError.isEmpty()) {
-                message += " or " + Character.toLowerCase(rangeError.charAt(0))
-                        + rangeError.substring(1);
-            }
-        }
-
-        context.report(TYPE_DEF, errorNode, context.getUastLocation(errorNode), message);
-    }
-
-    @Nullable
-    private static UExpression getAnnotationValue(@NonNull UAnnotation annotation) {
-        UExpression value = annotation.findDeclaredAttributeValue(ATTR_VALUE);
-        if (value == null) {
-            value = annotation.findDeclaredAttributeValue(null);
-        }
-        return value;
-    }
-
-    private static String listAllowedValues(@NonNull UElement context,
-            @NonNull List<UExpression> allowedValues) {
-        StringBuilder sb = new StringBuilder();
-        for (UExpression allowedValue : allowedValues) {
-            String s = null;
-            PsiElement resolved = null;
-            if (allowedValue instanceof ExternalReferenceExpression) {
-                resolved = UastLintUtils.resolve(
-                        (ExternalReferenceExpression) allowedValue, context);
-            } else if (allowedValue instanceof UReferenceExpression) {
-                resolved = ((UReferenceExpression) allowedValue).resolve();
-            }
-
-            if (resolved instanceof PsiField) {
-                PsiField field = (PsiField) resolved;
-                String containingClassName = field.getContainingClass() != null
-                                             ? field.getContainingClass().getName() : null;
-                if (containingClassName == null) {
-                    continue;
-                }
-                s = containingClassName + "." + field.getName();
-            }
-
-            if (s == null) {
-                s = allowedValue.asSourceString();
-            }
-            if (sb.length() > 0) {
-                sb.append(", ");
-            }
-            sb.append(s);
-        }
-        return sb.toString();
-    }
-
-    static double getDoubleAttribute(@NonNull UAnnotation annotation,
-            @NonNull String name, double defaultValue) {
-        Double value = getAnnotationDoubleValue(annotation, name);
-        if (value != null) {
-            return value;
-        }
-
-        return defaultValue;
-    }
-
-    static long getLongAttribute(@NonNull UAnnotation annotation,
-            @NonNull String name, long defaultValue) {
-        Long value = getAnnotationLongValue(annotation, name);
-        if (value != null) {
-            return value;
-        }
-
-        return defaultValue;
-    }
-
-    static boolean getBoolean(@NonNull UAnnotation annotation,
-            @NonNull String name, boolean defaultValue) {
-        Boolean value = getAnnotationBooleanValue(annotation, name);
-        if (value != null) {
-            return value;
-        }
-
-        return defaultValue;
-    }
-
-    @NonNull
-    static PsiAnnotation[] filterRelevantAnnotations(
-            @NonNull JavaEvaluator evaluator, @NonNull PsiAnnotation[] annotations) {
-        List<PsiAnnotation> result = null;
-        int length = annotations.length;
-        if (length == 0) {
-            return annotations;
-        }
-        for (PsiAnnotation annotation : annotations) {
-            String signature = annotation.getQualifiedName();
-            if (signature == null || signature.startsWith("java.")) {
-                // @Override, @SuppressWarnings etc. Ignore
-                continue;
-            }
-
-            if (signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) {
-                // Bail on the nullness annotations early since they're the most commonly
-                // defined ones. They're not analyzed in lint yet.
-                if (signature.endsWith(".Nullable") || signature.endsWith(".NonNull")) {
-                    continue;
-                }
-
-                // Common case: there's just one annotation; no need to create a list copy
-                if (length == 1) {
-                    return annotations;
-                }
-                if (result == null) {
-                    result = new ArrayList<PsiAnnotation>(2);
-                }
-                result.add(annotation);
-            }
-
-            // Special case @IntDef and @StringDef: These are used on annotations
-            // themselves. For example, you create a new annotation named @foo.bar.Baz,
-            // annotate it with @IntDef, and then use @foo.bar.Baz in your signatures.
-            // Here we want to map from @foo.bar.Baz to the corresponding int def.
-            // Don't need to compute this if performing @IntDef or @StringDef lookup
-            PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
-            if (ref == null) {
-                continue;
-            }
-            PsiElement resolved = ref.resolve();
-            if (!(resolved instanceof PsiClass) || !((PsiClass)resolved).isAnnotationType()) {
-                continue;
-            }
-            PsiClass cls = (PsiClass)resolved;
-            PsiAnnotation[] innerAnnotations = evaluator.getAllAnnotations(cls);
-            for (int j = 0; j < innerAnnotations.length; j++) {
-                PsiAnnotation inner = innerAnnotations[j];
-                String a = inner.getQualifiedName();
-                if (a == null || a.startsWith("java.")) {
-                    // @Override, @SuppressWarnings etc. Ignore
-                    continue;
-                }
-                if (a.equals(INT_DEF_ANNOTATION)
-                    || a.equals(PERMISSION_ANNOTATION)
-                    || a.equals(INT_RANGE_ANNOTATION)
-                    || a.equals(STRING_DEF_ANNOTATION)) {
-                    if (length == 1 && j == innerAnnotations.length - 1 && result == null) {
-                        return innerAnnotations;
-                    }
-                    if (result == null) {
-                        result = new ArrayList<PsiAnnotation>(2);
-                    }
-                    result.add(inner);
-                }
-            }
-        }
-
-        return result != null
-               ? result.toArray(PsiAnnotation.EMPTY_ARRAY) : PsiAnnotation.EMPTY_ARRAY;
-    }
-
-    // ---- Implements UastScanner ----
-
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        List<Class<? extends UElement>> types = new ArrayList<Class<? extends UElement>>(3);
-        types.add(UCallExpression.class);
-        types.add(UVariable.class);
-        return types;
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new CallVisitor(context);
-    }
-
-    private class CallVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        public CallVisitor(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression call) {
-            PsiMethod method = call.resolve();
-            if (method != null) {
-                checkCall(method, call);
-            }
-            return super.visitCallExpression(call);
-        }
-
-        @Override
-        public boolean visitVariable(UVariable node) {
-            if (node instanceof UEnumConstant) {
-                UEnumConstant constant = (UEnumConstant) node; 
-                PsiMethod method = constant.resolveMethod();
-                checkCall(method, constant);
-            }
-            return super.visitVariable(node);
-        }
-
-        public void checkCall(PsiMethod method, UCallExpression call) {
-            JavaEvaluator evaluator = mContext.getEvaluator();
-
-            List<UAnnotation> methodAnnotations;
-            {
-                PsiAnnotation[] annotations = evaluator.getAllAnnotations(method);
-                methodAnnotations = JavaUAnnotation.wrap(filterRelevantAnnotations(evaluator, annotations));
-            }
-
-            // Look for annotations on the class as well: these trickle
-            // down to all the methods in the class
-            PsiClass containingClass = method.getContainingClass();
-            List<UAnnotation> classAnnotations;
-            if (containingClass != null) {
-                PsiAnnotation[] annotations = evaluator.getAllAnnotations(containingClass);
-                classAnnotations = JavaUAnnotation.wrap(filterRelevantAnnotations(evaluator, annotations));
-            } else {
-                classAnnotations = Collections.emptyList();
-            }
-
-            for (UAnnotation annotation : methodAnnotations) {
-                checkMethodAnnotation(mContext, method, call, annotation, methodAnnotations,
-                                      classAnnotations);
-            }
-
-            if (!classAnnotations.isEmpty()) {
-                for (UAnnotation annotation : classAnnotations) {
-                    checkMethodAnnotation(mContext, method, call, annotation, methodAnnotations,
-                                          classAnnotations);
-                }
-            }
-
-            List<UExpression> arguments = call.getValueArguments();
-            PsiParameterList parameterList = method.getParameterList();
-            PsiParameter[] parameters = parameterList.getParameters();
-            List<UAnnotation> annotations = null;
-            for (int i = 0, n = Math.min(parameters.length, arguments.size());
-                 i < n;
-                 i++) {
-                UExpression argument = arguments.get(i);
-                PsiParameter parameter = parameters[i];
-                annotations = JavaUAnnotation.wrap(
-                        filterRelevantAnnotations(evaluator, evaluator.getAllAnnotations(parameter)));
-                checkParameterAnnotations(mContext, argument, call, method, annotations);
-            }
-            if (annotations != null) {
-                // last parameter is varargs (same parameter annotations)
-                for (int i = parameters.length; i < arguments.size(); i++) {
-                    UExpression argument = arguments.get(i);
-                    checkParameterAnnotations(mContext, argument, call, method, annotations);
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java
deleted file mode 100644
index 366e17a..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/** Detector looking for Toast.makeText() without a corresponding show() call */
-public class ToastDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "ShowToast", //$NON-NLS-1$
-            "Toast created but not shown",
-
-            "`Toast.makeText()` creates a `Toast` but does *not* show it. You must call " +
-            "`show()` on the resulting object to actually make the `Toast` appear.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    ToastDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-
-    /** Constructs a new {@link ToastDetector} check */
-    public ToastDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("makeText"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod uMethod) {
-        PsiMethod method = uMethod.getPsi();
-        
-        if (!JavaEvaluator.isMemberInClass(method, "android.widget.Toast")) {
-            return;
-        }
-
-        // Make sure you pass the right kind of duration: it's not a delay, it's
-        //  LENGTH_SHORT or LENGTH_LONG
-        // (see http://code.google.com/p/android/issues/detail?id=3655)
-        List<UExpression> args = call.getValueArguments();
-        if (args.size() == 3) {
-            UExpression duration = args.get(2);
-            if (duration instanceof ULiteralExpression) {
-                context.report(ISSUE, duration, context.getUastLocation(duration),
-                        "Expected duration `Toast.LENGTH_SHORT` or `Toast.LENGTH_LONG`, a custom " +
-                                "duration value is not supported");
-            }
-        }
-        
-        UElement surroundingDeclaration = UastUtils.getParentOfType(
-                call, true,
-                UMethod.class, UBlockExpression.class, ULambdaExpression.class);
-
-        if (surroundingDeclaration == null) {
-            return;
-        }
-
-        ShowFinder finder = new ShowFinder(call);
-        surroundingDeclaration.accept(finder);
-        if (!finder.isShowCalled()) {
-            context.report(ISSUE, call, context.getUastNameLocation(call),
-                           "Toast created but not shown: did you forget to call `show()` ?");
-        }
-
-    }
-
-    private static class ShowFinder extends AbstractUastVisitor {
-        /** The target makeText call */
-        private final UCallExpression mTarget;
-        /** Whether we've found the show method */
-        private boolean mFound;
-        /** Whether we've seen the target makeText node yet */
-        private boolean mSeenTarget;
-
-        private ShowFinder(UCallExpression target) {
-            mTarget = target;
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (node.equals(mTarget)) {
-                mSeenTarget = true;
-            } else {
-                if ((mSeenTarget || mTarget.equals(node.getReceiver()))
-                    && "show".equals(node.getMethodName())) {
-                    // TODO: Do more flow analysis to see whether we're really calling show
-                    // on the right type of object?
-                    mFound = true;
-                }
-            }
-
-            return super.visitCallExpression(node);
-        }
-
-        @Override
-        public boolean visitReturnExpression(UReturnExpression node) {
-            if (UastUtils.isChildOf(mTarget, node.getReturnExpression(), true)) {
-                // If you just do "return Toast.makeText(...) don't warn
-                mFound = true;
-            }
-
-            return super.visitReturnExpression(node);
-        }
-
-        private boolean isShowCalled() {
-            return mFound;
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TrustAllX509TrustManagerDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TrustAllX509TrustManagerDetector.java
deleted file mode 100644
index c070e82..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TrustAllX509TrustManagerDetector.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.ClassScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.uast.UBlockExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UReturnExpression;
-import org.jetbrains.uast.UastEmptyExpression;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.org.objectweb.asm.Opcodes;
-import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.jetbrains.org.objectweb.asm.tree.InsnList;
-import org.jetbrains.org.objectweb.asm.tree.MethodNode;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-
-public class TrustAllX509TrustManagerDetector extends Detector implements Detector.UastScanner,
-        ClassScanner {
-
-    @SuppressWarnings("unchecked")
-    private static final Implementation IMPLEMENTATION =
-            new Implementation(TrustAllX509TrustManagerDetector.class,
-                    EnumSet.of(Scope.JAVA_LIBRARIES, Scope.JAVA_FILE),
-                    Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue ISSUE = Issue.create("TrustAllX509TrustManager",
-            "Insecure TLS/SSL trust manager",
-            "This check looks for X509TrustManager implementations whose `checkServerTrusted` or " +
-            "`checkClientTrusted` methods do nothing (thus trusting any certificate chain) " +
-            "which could result in insecure network traffic caused by trusting arbitrary " +
-            "TLS/SSL certificates presented by peers.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    public TrustAllX509TrustManagerDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList("javax.net.ssl.X509TrustManager");
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass cls) {
-        checkMethod(context, cls, "checkServerTrusted");
-        checkMethod(context, cls, "checkClientTrusted");
-    }
-
-    private static void checkMethod(@NonNull JavaContext context,
-            @NonNull UClass cls,
-            @NonNull String methodName) {
-        JavaEvaluator evaluator = context.getEvaluator();
-        for (PsiMethod method : cls.findMethodsByName(methodName, true)) {
-            if (evaluator.isAbstract(method)) {
-                continue;
-            }
-
-            // For now very simple; only checks if nothing is done.
-            // Future work: Improve this check to be less sensitive to irrelevant
-            // instructions/statements/invocations (e.g. System.out.println) by
-            // looking for calls that could lead to a CertificateException being
-            // thrown, e.g. throw statement within the method itself or invocation
-            // of another method that may throw a CertificateException, and only
-            // reporting an issue if none of these calls are found. ControlFlowGraph
-            // may be useful here.
-
-            UExpression body = context.getUastContext().getMethodBody(method);
-
-            ComplexBodyVisitor visitor = new ComplexBodyVisitor();
-            body.accept(visitor);
-            
-            if (!visitor.isComplex()) {
-                Location location = context.getNameLocation(method);
-                String message = getErrorMessage(methodName);
-                context.report(ISSUE, method, location, message);
-            }
-        }
-    }
-
-    @NonNull
-    private static String getErrorMessage(String methodName) {
-        return "`" + methodName + "` is empty, which could cause " +
-                "insecure network traffic due to trusting arbitrary TLS/SSL " +
-                "certificates presented by peers";
-    }
-
-    private static class ComplexBodyVisitor extends AbstractUastVisitor {
-        private boolean isComplex = false;
-
-        @Override
-        public boolean visitElement(@NotNull UElement node) {
-            if (node instanceof UExpression &&
-                    !(node instanceof UReturnExpression
-                            || node instanceof UBlockExpression
-                            || node instanceof UastEmptyExpression)) {
-                isComplex = true;
-            }
-
-            return isComplex || super.visitElement(node);
-        }
-
-        boolean isComplex() {
-            return isComplex;
-        }
-    }
-
-    // ---- Implements ClassScanner ----
-    // Only used for libraries where we have to analyze bytecode
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    public void checkClass(@NonNull final ClassContext context,
-            @NonNull ClassNode classNode) {
-        if (!context.isFromClassLibrary()) {
-            // Non-library code checked at the AST level
-            return;
-        }
-        if (!classNode.interfaces.contains("javax/net/ssl/X509TrustManager")) {
-            return;
-        }
-        List methodList = classNode.methods;
-        for (Object m : methodList) {
-            MethodNode method = (MethodNode) m;
-            if ("checkServerTrusted".equals(method.name) ||
-                    "checkClientTrusted".equals(method.name)) {
-                InsnList nodes = method.instructions;
-                boolean emptyMethod = true; // Stays true if method doesn't perform any "real"
-                                            // operations
-                for (int i = 0, n = nodes.size(); i < n; i++) {
-                    // Future work: Improve this check to be less sensitive to irrelevant
-                    // instructions/statements/invocations (e.g. System.out.println) by
-                    // looking for calls that could lead to a CertificateException being
-                    // thrown, e.g. throw statement within the method itself or invocation
-                    // of another method that may throw a CertificateException, and only
-                    // reporting an issue if none of these calls are found. ControlFlowGraph
-                    // may be useful here.
-                    AbstractInsnNode instruction = nodes.get(i);
-                    int type = instruction.getType();
-                    if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE &&
-                            !(type == AbstractInsnNode.INSN &&
-                                    instruction.getOpcode() == Opcodes.RETURN)) {
-                        emptyMethod = false;
-                        break;
-                    }
-                }
-                if (emptyMethod) {
-                    Location location = context.getLocation(method, classNode);
-                    context.report(ISSUE, location, getErrorMessage(method.name));
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TypoLookup.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TypoLookup.java
deleted file mode 100644
index 98fa742..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/TypoLookup.java
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.DOT_XML;
-import static com.android.tools.klint.detector.api.LintUtils.assertionsEnabled;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.google.common.base.Charsets;
-import com.google.common.base.Splitter;
-import com.google.common.io.ByteSink;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel.MapMode;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.WeakHashMap;
-
-/**
- * Database of common typos / misspellings.
- */
-public class TypoLookup {
-    private static final TypoLookup NONE = new TypoLookup();
-
-    /** String separating misspellings and suggested replacements in the text file */
-    private static final String WORD_SEPARATOR = "->";  //$NON-NLS-1$
-
-    /** Relative path to the typos database file within the Lint installation */
-    private static final String XML_FILE_PATH = "tools/support/typos-%1$s.txt"; //$NON-NLS-1$
-    private static final String FILE_HEADER = "Typo database used by Android lint\000";
-    private static final int BINARY_FORMAT_VERSION = 2;
-    private static final boolean DEBUG_FORCE_REGENERATE_BINARY = false;
-    private static final boolean DEBUG_SEARCH = false;
-    private static final boolean WRITE_STATS = false;
-    /** Default size to reserve for each API entry when creating byte buffer to build up data */
-    private static final int BYTES_PER_ENTRY = 28;
-
-    private byte[] mData;
-    private int[] mIndices;
-    private int mWordCount;
-
-    private static final WeakHashMap<String, TypoLookup> sInstanceMap =
-            new WeakHashMap<String, TypoLookup>();
-
-    /**
-     * Returns an instance of the Typo database for the given locale
-     *
-     * @param client the client to associate with this database - used only for
-     *            logging. The database object may be shared among repeated
-     *            invocations, and in that case client used will be the one
-     *            originally passed in. In other words, this parameter may be
-     *            ignored if the client created is not new.
-     * @param locale the locale to look up a typo database for (should be a
-     *            language code (ISO 639-1, two lowercase character names)
-     * @param region the region to look up a typo database for (should be a two
-     *            letter ISO 3166-1 alpha-2 country code in upper case) language
-     *            code
-     * @return a (possibly shared) instance of the typo database, or null if its
-     *         data can't be found
-     */
-    @Nullable
-    public static TypoLookup get(@NonNull LintClient client, @NonNull String locale,
-            @Nullable String region) {
-        synchronized (TypoLookup.class) {
-            String key = locale;
-
-            if (region != null && region.length() == 2) { // skip BCP-47 regions
-                // Allow for region-specific dictionaries. See for example
-                // http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences
-                assert region.length() == 2
-                        && Character.isUpperCase(region.charAt(0))
-                        && Character.isUpperCase(region.charAt(1)) : region;
-                // Look for typos-en-rUS.txt etc
-                key = locale + 'r' + region;
-            }
-
-            TypoLookup db = sInstanceMap.get(key);
-            if (db == null) {
-                String path = String.format(XML_FILE_PATH, key);
-                File file = client.findResource(path);
-                if (file == null) {
-                    // AOSP build environment?
-                    String build = System.getenv("ANDROID_BUILD_TOP");   //$NON-NLS-1$
-                    if (build != null) {
-                        file = new File(build, ("sdk/files/" //$NON-NLS-1$
-                                    + path.substring(path.lastIndexOf('/') + 1))
-                                      .replace('/', File.separatorChar));
-                    }
-                }
-
-                if (file == null || !file.exists()) {
-                    //noinspection VariableNotUsedInsideIf
-                    if (region != null) {
-                        // Fall back to the generic locale (non-region-specific) database
-                        return get(client, locale, null);
-                    }
-                    db = NONE;
-                } else {
-                    db = get(client, file);
-                    assert db != null : file;
-                }
-                sInstanceMap.put(key, db);
-            }
-
-            if (db == NONE) {
-                return null;
-            } else {
-                return db;
-            }
-        }
-    }
-
-    /**
-     * Returns an instance of the typo database
-     *
-     * @param client the client to associate with this database - used only for
-     *            logging
-     * @param xmlFile the XML file containing configuration data to use for this
-     *            database
-     * @return a (possibly shared) instance of the typo database, or null
-     *         if its data can't be found
-     */
-    @Nullable
-    private static TypoLookup get(LintClient client, File xmlFile) {
-        if (!xmlFile.exists()) {
-            client.log(null, "The typo database file %1$s does not exist", xmlFile);
-            return null;
-        }
-
-        String name = xmlFile.getName();
-        if (LintUtils.endsWith(name, DOT_XML)) {
-            name = name.substring(0, name.length() - DOT_XML.length());
-        }
-        File cacheDir = client.getCacheDir(true/*create*/);
-        if (cacheDir == null) {
-            cacheDir = xmlFile.getParentFile();
-        }
-
-        File binaryData = new File(cacheDir, name
-                // Incorporate version number in the filename to avoid upgrade filename
-                // conflicts on Windows (such as issue #26663)
-                + '-' + BINARY_FORMAT_VERSION + ".bin"); //$NON-NLS-1$
-
-        if (DEBUG_FORCE_REGENERATE_BINARY) {
-            System.err.println("\nTemporarily regenerating binary data unconditionally \nfrom "
-                    + xmlFile + "\nto " + binaryData);
-            if (!createCache(client, xmlFile, binaryData)) {
-                return null;
-            }
-        } else if (!binaryData.exists() || binaryData.lastModified() < xmlFile.lastModified()) {
-            if (!createCache(client, xmlFile, binaryData)) {
-                return null;
-            }
-        }
-
-        if (!binaryData.exists()) {
-            client.log(null, "The typo database file %1$s does not exist", binaryData);
-            return null;
-        }
-
-        return new TypoLookup(client, xmlFile, binaryData);
-    }
-
-    private static boolean createCache(LintClient client, File xmlFile, File binaryData) {
-        long begin = 0;
-        if (WRITE_STATS) {
-            begin = System.currentTimeMillis();
-        }
-
-        // Read in data
-        List<String> lines;
-        try {
-            lines = Files.readLines(xmlFile, Charsets.UTF_8);
-        } catch (IOException e) {
-            client.log(e, "Can't read typo database file");
-            return false;
-        }
-
-        if (WRITE_STATS) {
-            long end = System.currentTimeMillis();
-            System.out.println("Reading data structures took " + (end - begin) + " ms)");
-        }
-
-        try {
-            writeDatabase(binaryData, lines);
-            return true;
-        } catch (IOException ioe) {
-            client.log(ioe, "Can't write typo cache file");
-        }
-
-        return false;
-    }
-
-    /** Use one of the {@link #get} factory methods instead */
-    private TypoLookup(
-            @NonNull LintClient client,
-            @NonNull File xmlFile,
-            @Nullable File binaryFile) {
-        if (binaryFile != null) {
-            readData(client, xmlFile, binaryFile);
-        }
-    }
-
-    private TypoLookup() {
-    }
-
-    private void readData(@NonNull LintClient client, @NonNull File xmlFile,
-            @NonNull File binaryFile) {
-        if (!binaryFile.exists()) {
-            client.log(null, "%1$s does not exist", binaryFile);
-            return;
-        }
-        long start = System.currentTimeMillis();
-        try {
-            MappedByteBuffer buffer = Files.map(binaryFile, MapMode.READ_ONLY);
-            assert buffer.order() == ByteOrder.BIG_ENDIAN;
-
-            // First skip the header
-            byte[] expectedHeader = FILE_HEADER.getBytes(Charsets.US_ASCII);
-            buffer.rewind();
-            for (byte anExpectedHeader : expectedHeader) {
-                if (anExpectedHeader != buffer.get()) {
-                    client.log(null, "Incorrect file header: not an typo database cache " +
-                                     "file, or a corrupt cache file");
-                    return;
-                }
-            }
-
-            // Read in the format number
-            if (buffer.get() != BINARY_FORMAT_VERSION) {
-                // Force regeneration of new binary data with up to date format
-                if (createCache(client, xmlFile, binaryFile)) {
-                    readData(client, xmlFile, binaryFile); // Recurse
-                }
-
-                return;
-            }
-
-            mWordCount = buffer.getInt();
-
-            // Read in the word table indices;
-            int count = mWordCount;
-            int[] offsets = new int[count];
-
-            // Another idea: I can just store the DELTAS in the file (and add them up
-            // when reading back in) such that it takes just ONE byte instead of four!
-
-            for (int i = 0; i < count; i++) {
-                offsets[i] = buffer.getInt();
-            }
-
-            // No need to read in the rest -- we'll just keep the whole byte array in memory
-            // TODO: Make this code smarter/more efficient.
-            int size = buffer.limit();
-            byte[] b = new byte[size];
-            buffer.rewind();
-            buffer.get(b);
-            mData = b;
-            mIndices = offsets;
-
-            // TODO: We only need to keep the data portion here since we've initialized
-            // the offset array separately.
-            // TODO: Investigate (profile) accessing the byte buffer directly instead of
-            // accessing a byte array.
-        } catch (IOException e) {
-            client.log(e, null);
-        }
-        if (WRITE_STATS) {
-            long end = System.currentTimeMillis();
-            System.out.println("\nRead typo database in " + (end - start)
-                    + " milliseconds.");
-            System.out.println("Size of data table: " + mData.length + " bytes ("
-                    + Integer.toString(mData.length/1024) + "k)\n");
-        }
-    }
-
-    /** See the {@link #readData(LintClient,File,File)} for documentation on the data format. */
-    private static void writeDatabase(File file, List<String> lines) throws IOException {
-        /*
-         * 1. A file header, which is the exact contents of {@link FILE_HEADER} encoded
-         *     as ASCII characters. The purpose of the header is to identify what the file
-         *     is for, for anyone attempting to open the file.
-         * 2. A file version number. If the binary file does not match the reader's expected
-         *     version, it can ignore it (and regenerate the cache from XML).
-         */
-
-        // Drop comments etc
-        List<String> words = new ArrayList<String>(lines.size());
-        for (String line : lines) {
-            if (!line.isEmpty() && Character.isLetter(line.charAt(0))) {
-                int end = line.indexOf(WORD_SEPARATOR);
-                if (end == -1) {
-                    end = line.trim().length();
-                }
-                String typo = line.substring(0, end).trim();
-                String replacements = line.substring(end + WORD_SEPARATOR.length()).trim();
-                if (replacements.isEmpty()) {
-                    // We don't support empty replacements
-                    continue;
-                }
-                String combined = typo + (char) 0 + replacements;
-
-                words.add(combined);
-            }
-        }
-
-        byte[][] wordArrays = new byte[words.size()][];
-        for (int i = 0, n = words.size(); i < n; i++) {
-            String word = words.get(i);
-            wordArrays[i] = word.getBytes(Charsets.UTF_8);
-        }
-        // Sort words, using our own comparator to ensure that it matches the
-        // binary search in getTypos()
-        Comparator<byte[]> comparator = new Comparator<byte[]>() {
-            @Override
-            public int compare(byte[] o1, byte[] o2) {
-                return TypoLookup.compare(o1, 0, (byte) 0, o2, 0, o2.length);
-            }
-        };
-        Arrays.sort(wordArrays, comparator);
-
-        byte[] headerBytes = FILE_HEADER.getBytes(Charsets.US_ASCII);
-        int entryCount = wordArrays.length;
-        int capacity = entryCount * BYTES_PER_ENTRY + headerBytes.length + 5;
-        ByteBuffer buffer = ByteBuffer.allocate(capacity);
-        buffer.order(ByteOrder.BIG_ENDIAN);
-        //  1. A file header, which is the exact contents of {@link FILE_HEADER} encoded
-        //      as ASCII characters. The purpose of the header is to identify what the file
-        //      is for, for anyone attempting to open the file.
-        buffer.put(headerBytes);
-
-        //  2. A file version number. If the binary file does not match the reader's expected
-        //      version, it can ignore it (and regenerate the cache from XML).
-        buffer.put((byte) BINARY_FORMAT_VERSION);
-
-        //  3. The number of words [1 int]
-        buffer.putInt(entryCount);
-
-        //  4. Word offset table (one integer per word, pointing to the byte offset in the
-        //       file (relative to the beginning of the file) where each word begins.
-        //       The words are always sorted alphabetically.
-        int wordOffsetTable = buffer.position();
-
-        // Reserve enough room for the offset table here: we will backfill it with pointers
-        // as we're writing out the data structures below
-        for (int i = 0, n = entryCount; i < n; i++) {
-            buffer.putInt(0);
-        }
-
-        int nextEntry = buffer.position();
-        int nextOffset = wordOffsetTable;
-
-        // 7. Word entry table. Each word entry consists of the word, followed by the byte 0
-        //      as a terminator, followed by a comma separated list of suggestions (which
-        //      may be empty), or a final 0.
-        for (byte[] word : wordArrays) {
-            buffer.position(nextOffset);
-            buffer.putInt(nextEntry);
-            nextOffset = buffer.position();
-            buffer.position(nextEntry);
-
-            buffer.put(word); // already embeds 0 to separate typo from words
-            buffer.put((byte)0);
-
-            nextEntry = buffer.position();
-        }
-
-        int size = buffer.position();
-        assert size <= buffer.limit();
-        buffer.mark();
-
-        if (WRITE_STATS) {
-            System.out.println("Wrote " + words.size() + " word entries");
-            System.out.print("Actual binary size: " + size + " bytes");
-            System.out.println(String.format(" (%.1fM)", size/(1024*1024.f)));
-
-            System.out.println("Allocated size: " + (entryCount * BYTES_PER_ENTRY) + " bytes");
-            System.out.println("Required bytes per entry: " + (size/ entryCount) + " bytes");
-        }
-
-        // Now dump this out as a file
-        // There's probably an API to do this more efficiently; TODO: Look into this.
-        byte[] b = new byte[size];
-        buffer.rewind();
-        buffer.get(b);
-        ByteSink sink = Files.asByteSink(file);
-        sink.write(b);
-    }
-
-    // For debugging only
-    private String dumpEntry(int offset) {
-        if (DEBUG_SEARCH) {
-            int end = offset;
-            while (mData[end] != 0) {
-                end++;
-            }
-            return new String(mData, offset, end - offset, Charsets.UTF_8);
-        } else {
-            return "<disabled>"; //$NON-NLS-1$
-        }
-    }
-
-    /** Comparison function: *only* used for ASCII strings */
-    @VisibleForTesting
-    static int compare(byte[] data, int offset, byte terminator, CharSequence s,
-            int begin, int end) {
-        int i = offset;
-        int j = begin;
-        for (; ; i++, j++) {
-            byte b = data[i];
-            if (b == ' ') {
-                // We've matched up to the space in a split-word typo, such as
-                // in German all zu⇒allzu; here we've matched just past "all".
-                // Rather than terminating, attempt to continue in the buffer.
-                if (j == end) {
-                    int max = s.length();
-                    if (end < max && s.charAt(end) == ' ') {
-                        // Find next word
-                        for (; end < max; end++) {
-                            char c = s.charAt(end);
-                            if (!Character.isLetter(c)) {
-                                if (c == ' ' && end == j) {
-                                    continue;
-                                }
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (j == end) {
-                break;
-            }
-
-            if (b == '*') {
-                // Glob match (only supported at the end)
-                return 0;
-            }
-            char c = s.charAt(j);
-            byte cb = (byte) c;
-            int delta = b - cb;
-            if (delta != 0) {
-                cb = (byte) Character.toLowerCase(c);
-                if (b != cb) {
-                    // Ensure that it has the right sign
-                    b = (byte) Character.toLowerCase(b);
-                    delta = b - cb;
-                    if (delta != 0) {
-                        return delta;
-                    }
-                }
-            }
-        }
-
-        return data[i] - terminator;
-    }
-
-    /** Comparison function used for general UTF-8 encoded strings */
-    @VisibleForTesting
-    static int compare(byte[] data, int offset, byte terminator, byte[] s,
-            int begin, int end) {
-        int i = offset;
-        int j = begin;
-        for (; ; i++, j++) {
-            byte b = data[i];
-            if (b == ' ') {
-                // We've matched up to the space in a split-word typo, such as
-                // in German all zu⇒allzu; here we've matched just past "all".
-                // Rather than terminating, attempt to continue in the buffer.
-                // We've matched up to the space in a split-word typo, such as
-                // in German all zu⇒allzu; here we've matched just past "all".
-                // Rather than terminating, attempt to continue in the buffer.
-                if (j == end) {
-                    int max = s.length;
-                    if (end < max && s[end] == ' ') {
-                        // Find next word
-                        for (; end < max; end++) {
-                            byte cb = s[end];
-                            if (!isLetter(cb)) {
-                                if (cb == ' ' && end == j) {
-                                    continue;
-                                }
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (j == end) {
-                break;
-            }
-            if (b == '*') {
-                // Glob match (only supported at the end)
-                return 0;
-            }
-            byte cb = s[j];
-            int delta = b - cb;
-            if (delta != 0) {
-                cb = toLowerCase(cb);
-                b = toLowerCase(b);
-                delta = b - cb;
-                if (delta != 0) {
-                    return delta;
-                }
-            }
-
-            if (b == terminator || cb == terminator) {
-                return delta;
-            }
-        }
-
-        return data[i] - terminator;
-    }
-
-    /**
-     * Look up whether this word is a typo, and if so, return the typo itself
-     * and one or more likely meanings
-     *
-     * @param text the string containing the word
-     * @param begin the index of the first character in the word
-     * @param end the index of the first character after the word. Note that the
-     *            search may extend <b>beyond</b> this index, if for example the
-     *            word matches a multi-word typo in the dictionary
-     * @return a list of the typo itself followed by the replacement strings if
-     *         the word represents a typo, and null otherwise
-     */
-    @Nullable
-    public List<String> getTypos(@NonNull CharSequence text, int begin, int end) {
-        assert end <= text.length();
-
-        if (assertionsEnabled()) {
-            for (int i = begin; i < end; i++) {
-                char c = text.charAt(i);
-                if (c >= 128) {
-                    assert false : "Call the UTF-8 version of this method instead";
-                    return null;
-                }
-            }
-        }
-
-        int low = 0;
-        int high = mWordCount - 1;
-        while (low <= high) {
-            int middle = (low + high) >>> 1;
-            int offset = mIndices[middle];
-
-            if (DEBUG_SEARCH) {
-                System.out.println("Comparing string " + text +" with entry at " + offset
-                        + ": " + dumpEntry(offset));
-            }
-
-            // Compare the word at the given index.
-            int compare = compare(mData, offset, (byte) 0, text, begin, end);
-
-            if (compare == 0) {
-                offset = mIndices[middle];
-
-                // Don't allow matching uncapitalized words, such as "enlish", when
-                // the dictionary word is capitalized, "Enlish".
-                if (mData[offset] != text.charAt(begin)
-                        && Character.isLowerCase(text.charAt(begin))) {
-                    return null;
-                }
-
-                // Make sure there is a case match; we only want to allow
-                // matching capitalized words to capitalized typos or uncapitalized typos
-                //  (e.g. "Teh" and "teh" to "the"), but not uncapitalized words to capitalized
-                // typos (e.g. "enlish" to "Enlish").
-                String glob = null;
-                for (int i = begin; ; i++) {
-                    byte b = mData[offset++];
-                    if (b == 0) {
-                        offset--;
-                        break;
-                    } else if (b == '*') {
-                        int globEnd = i;
-                        while (globEnd < text.length()
-                                && Character.isLetter(text.charAt(globEnd))) {
-                            globEnd++;
-                        }
-                        glob = text.subSequence(i, globEnd).toString();
-                        break;
-                    }
-                    char c = text.charAt(i);
-                    byte cb = (byte) c;
-                    if (b != cb && i > begin) {
-                        return null;
-                    }
-                }
-
-                return computeSuggestions(mIndices[middle], offset, glob);
-            }
-
-            if (compare < 0) {
-                low = middle + 1;
-            } else if (compare > 0) {
-                high = middle - 1;
-            } else {
-                assert false; // compare == 0 already handled above
-                return null;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Look up whether this word is a typo, and if so, return the typo itself
-     * and one or more likely meanings
-     *
-     * @param utf8Text the string containing the word, encoded as UTF-8
-     * @param begin the index of the first character in the word
-     * @param end the index of the first character after the word. Note that the
-     *            search may extend <b>beyond</b> this index, if for example the
-     *            word matches a multi-word typo in the dictionary
-     * @return a list of the typo itself followed by the replacement strings if
-     *         the word represents a typo, and null otherwise
-     */
-    @Nullable
-    public List<String> getTypos(@NonNull byte[] utf8Text, int begin, int end) {
-        assert end <= utf8Text.length;
-
-        int low = 0;
-        int high = mWordCount - 1;
-        while (low <= high) {
-            int middle = (low + high) >>> 1;
-            int offset = mIndices[middle];
-
-            if (DEBUG_SEARCH) {
-                String s = new String(Arrays.copyOfRange(utf8Text, begin, end), Charsets.UTF_8);
-                System.out.println("Comparing string " + s +" with entry at " + offset
-                        + ": " + dumpEntry(offset));
-                System.out.println("   middle=" + middle + ", low=" + low + ", high=" + high);
-            }
-
-            // Compare the word at the given index.
-            int compare = compare(mData, offset, (byte) 0, utf8Text, begin, end);
-
-            if (DEBUG_SEARCH) {
-                System.out.println(" signum=" + (int)Math.signum(compare) + ", delta=" + compare);
-            }
-
-            if (compare == 0) {
-                offset = mIndices[middle];
-
-                // Don't allow matching uncapitalized words, such as "enlish", when
-                // the dictionary word is capitalized, "Enlish".
-                if (mData[offset] != utf8Text[begin] && isUpperCase(mData[offset])) {
-                    return null;
-                }
-
-                // Make sure there is a case match; we only want to allow
-                // matching capitalized words to capitalized typos or uncapitalized typos
-                //  (e.g. "Teh" and "teh" to "the"), but not uncapitalized words to capitalized
-                // typos (e.g. "enlish" to "Enlish").
-                String glob = null;
-                for (int i = begin; ; i++) {
-                    byte b = mData[offset++];
-                    if (b == 0) {
-                        offset--;
-                        break;
-                    } else if (b == '*') {
-                        int globEnd = i;
-                        while (globEnd < utf8Text.length && isLetter(utf8Text[globEnd])) {
-                            globEnd++;
-                        }
-                        glob = new String(utf8Text, i, globEnd - i, Charsets.UTF_8);
-                        break;
-                    }
-                    byte cb = utf8Text[i];
-                    if (b != cb && i > begin) {
-                        return null;
-                    }
-                }
-
-                return computeSuggestions(mIndices[middle], offset, glob);
-            }
-
-            if (compare < 0) {
-                low = middle + 1;
-            } else if (compare > 0) {
-                high = middle - 1;
-            } else {
-                assert false; // compare == 0 already handled above
-                return null;
-            }
-        }
-
-        return null;
-    }
-
-    private List<String> computeSuggestions(int begin, int offset, String glob) {
-        String typo = new String(mData, begin, offset - begin, Charsets.UTF_8);
-
-        if (glob != null) {
-            typo = typo.replaceAll("\\*", glob); //$NON-NLS-1$
-        }
-
-        assert mData[offset] == 0;
-        offset++;
-        int replacementEnd = offset;
-        while (mData[replacementEnd] != 0) {
-            replacementEnd++;
-        }
-        String replacements = new String(mData, offset, replacementEnd - offset, Charsets.UTF_8);
-        List<String> words = new ArrayList<String>();
-        words.add(typo);
-
-        // The first entry should be the typo itself. We need to pass this back since due
-        // to multi-match words and globbing it could extend beyond the initial word range
-
-        for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(replacements)) {
-            if (glob != null) {
-                // Need to append the glob string to each result
-                words.add(s.replaceAll("\\*", glob)); //$NON-NLS-1$
-            } else {
-                words.add(s);
-            }
-        }
-
-        return words;
-    }
-
-    // "Character" handling for bytes. This assumes that the bytes correspond to Unicode
-    // characters in the ISO 8859-1 range, which is are encoded the same way in UTF-8.
-    // This obviously won't work to for example uppercase to lowercase conversions for
-    // multi byte characters, which means we simply won't catch typos if the dictionaries
-    // contain these. None of the currently included dictionaries do. However, it does
-    // help us properly deal with punctuation and spacing characters.
-
-    static boolean isUpperCase(byte b) {
-        return Character.isUpperCase((char) b);
-    }
-
-    static byte toLowerCase(byte b) {
-        return (byte) Character.toLowerCase((char) b);
-    }
-
-    static boolean isSpace(byte b) {
-        return Character.isWhitespace((char) b);
-    }
-
-    static boolean isLetter(byte b) {
-        // Assume that multi byte characters represent letters in other languages.
-        // Obviously, it could be unusual punctuation etc but letters are more likely
-        // in this context.
-        return Character.isLetter((char) b) || (b & 0x80) != 0;
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeBroadcastReceiverDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeBroadcastReceiverDetector.java
deleted file mode 100644
index c29068e..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeBroadcastReceiverDetector.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_PERMISSION;
-import static com.android.SdkConstants.CLASS_BROADCASTRECEIVER;
-import static com.android.SdkConstants.CLASS_CONTEXT;
-import static com.android.SdkConstants.CLASS_INTENT;
-import static com.android.SdkConstants.TAG_INTENT_FILTER;
-import static com.android.SdkConstants.TAG_RECEIVER;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.annotations.VisibleForTesting;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Detector.XmlScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.google.common.collect.Sets;
-import com.intellij.psi.JavaRecursiveElementVisitor;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiReferenceExpression;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UClass;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.USimpleNameReferenceExpression;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-import org.w3c.dom.Element;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class UnsafeBroadcastReceiverDetector extends Detector
-        implements Detector.UastScanner, XmlScanner {
-
-    /* Description of check implementations:
-     *
-     * UnsafeProtectedBroadcastReceiver check
-     *
-     * If a receiver is declared in the application manifest that has an intent-filter
-     * with an action string that matches a protected-broadcast action string,
-     * then if that receiver has an onReceive method, ensure that the method calls
-     * getAction at least once.
-     *
-     * With this check alone, false positives will occur if the onReceive method
-     * passes the received intent to another method that calls getAction.
-     * We look for any calls to aload_2 within the method bytecode, which could
-     * indicate loading the inputted intent onto the stack to use in a call
-     * to another method. In those cases, still report the issue, but
-     * report in the description that the finding may be a false positive.
-     * An alternative implementation option would be to omit reporting the issue
-     * at all when a call to aload_2 exists.
-     *
-     * UnprotectedSMSBroadcastReceiver check
-     *
-     * If a receiver is declared in AndroidManifest that has an intent-filter
-     * with action string SMS_DELIVER or SMS_RECEIVED, ensure that the
-     * receiver requires callers to have the BROADCAST_SMS permission.
-     *
-     * It is possible that the receiver may check the sender's permission by
-     * calling checkCallingPermission, which could cause a false positive.
-     * However, application developers should still be encouraged to declare
-     * the permission requirement in the manifest where it can be easily
-     * audited.
-     *
-     * Future work: Add checks for other action strings that should require
-     * particular permissions be checked, such as
-     * android.provider.Telephony.WAP_PUSH_DELIVER
-     *
-     * Note that neither of these checks address receivers dynamically created at runtime,
-     * only ones that are declared in the application manifest.
-     */
-
-    public static final Issue ACTION_STRING = Issue.create(
-            "UnsafeProtectedBroadcastReceiver",
-            "Unsafe Protected BroadcastReceiver",
-            "BroadcastReceivers that declare an intent-filter for a protected-broadcast action " +
-            "string must check that the received intent's action string matches the expected " +
-            "value, otherwise it is possible for malicious actors to spoof intents.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            new Implementation(UnsafeBroadcastReceiverDetector.class,
-                    EnumSet.of(Scope.MANIFEST, Scope.JAVA_FILE)));
-
-    public static final Issue BROADCAST_SMS = Issue.create(
-            "UnprotectedSMSBroadcastReceiver",
-            "Unprotected SMS BroadcastReceiver",
-            "BroadcastReceivers that declare an intent-filter for SMS_DELIVER or " +
-            "SMS_RECEIVED must ensure that the caller has the BROADCAST_SMS permission, " +
-            "otherwise it is possible for malicious actors to spoof intents.",
-            Category.SECURITY,
-            6,
-            Severity.WARNING,
-            new Implementation(UnsafeBroadcastReceiverDetector.class,
-                    Scope.MANIFEST_SCOPE));
-
-    /* List of protected broadcast strings. This list must be sorted alphabetically.
-     * Protected broadcast strings are defined by <protected-broadcast> entries in the
-     * manifest of system-level components or applications.
-     * The below list is copied from frameworks/base/core/res/AndroidManifest.xml
-     * and packages/services/Telephony/AndroidManifest.xml .
-     * It should be periodically updated. This list will likely not be complete, since
-     * protected-broadcast entries can be defined elsewhere, but should address
-     * most situations.
-     */
-    @VisibleForTesting
-    static final String[] PROTECTED_BROADCASTS = new String[] {
-            "android.app.action.DEVICE_OWNER_CHANGED",
-            "android.app.action.ENTER_CAR_MODE",
-            "android.app.action.ENTER_DESK_MODE",
-            "android.app.action.EXIT_CAR_MODE",
-            "android.app.action.EXIT_DESK_MODE",
-            "android.app.action.NEXT_ALARM_CLOCK_CHANGED",
-            "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED",
-            "android.appwidget.action.APPWIDGET_DELETED",
-            "android.appwidget.action.APPWIDGET_DISABLED",
-            "android.appwidget.action.APPWIDGET_ENABLED",
-            "android.appwidget.action.APPWIDGET_HOST_RESTORED",
-            "android.appwidget.action.APPWIDGET_RESTORED",
-            "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS",
-            "android.backup.intent.CLEAR",
-            "android.backup.intent.INIT",
-            "android.backup.intent.RUN",
-            "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED",
-            "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED",
-            "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED",
-            "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.adapter.action.DISCOVERY_FINISHED",
-            "android.bluetooth.adapter.action.DISCOVERY_STARTED",
-            "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED",
-            "android.bluetooth.adapter.action.SCAN_MODE_CHANGED",
-            "android.bluetooth.adapter.action.STATE_CHANGED",
-            "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.device.action.ACL_CONNECTED",
-            "android.bluetooth.device.action.ACL_DISCONNECTED",
-            "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED",
-            "android.bluetooth.device.action.ALIAS_CHANGED",
-            "android.bluetooth.device.action.BOND_STATE_CHANGED",
-            "android.bluetooth.device.action.CLASS_CHANGED",
-            "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL",
-            "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY",
-            "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST",
-            "android.bluetooth.device.action.DISAPPEARED",
-            "android.bluetooth.device.action.FOUND",
-            "android.bluetooth.device.action.MAS_INSTANCE",
-            "android.bluetooth.device.action.NAME_CHANGED",
-            "android.bluetooth.device.action.NAME_FAILED",
-            "android.bluetooth.device.action.PAIRING_CANCEL",
-            "android.bluetooth.device.action.PAIRING_REQUEST",
-            "android.bluetooth.device.action.UUID",
-            "android.bluetooth.devicepicker.action.DEVICE_SELECTED",
-            "android.bluetooth.devicepicker.action.LAUNCH",
-            "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT",
-            "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED",
-            "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED",
-            "android.bluetooth.headsetclient.profile.action.AG_EVENT",
-            "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED",
-            "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.headsetclient.profile.action.LAST_VTAG",
-            "android.bluetooth.headsetclient.profile.action.RESULT",
-            "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED",
-            "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS",
-            "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED",
-            "android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED",
-            "android.btopp.intent.action.CONFIRM",
-            "android.btopp.intent.action.HIDE",
-            "android.btopp.intent.action.HIDE_COMPLETE",
-            "android.btopp.intent.action.INCOMING_FILE_NOTIFICATION",
-            "android.btopp.intent.action.LIST",
-            "android.btopp.intent.action.OPEN",
-            "android.btopp.intent.action.OPEN_INBOUND",
-            "android.btopp.intent.action.OPEN_OUTBOUND",
-            "android.btopp.intent.action.RETRY",
-            "android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT",
-            "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED",
-            "android.hardware.usb.action.USB_ACCESSORY_ATTACHED",
-            "android.hardware.usb.action.USB_ACCESSORY_DETACHED",
-            "android.hardware.usb.action.USB_DEVICE_ATTACHED",
-            "android.hardware.usb.action.USB_DEVICE_DETACHED",
-            "android.hardware.usb.action.USB_PORT_CHANGED",
-            "android.hardware.usb.action.USB_STATE",
-            "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED",
-            "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED",
-            "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED",
-            "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED",
-            "android.intent.action.ACTION_IDLE_MAINTENANCE_END",
-            "android.intent.action.ACTION_IDLE_MAINTENANCE_START",
-            "android.intent.action.ACTION_POWER_CONNECTED",
-            "android.intent.action.ACTION_POWER_DISCONNECTED",
-            "android.intent.action.ACTION_SET_RADIO_CAPABILITY_DONE",
-            "android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED",
-            "android.intent.action.ACTION_SHUTDOWN",
-            "android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE",
-            "android.intent.action.ACTION_SUBINFO_RECORD_UPDATED",
-            "android.intent.action.ADVANCED_SETTINGS",
-            "android.intent.action.AIRPLANE_MODE",
-            "android.intent.action.ANY_DATA_STATE",
-            "android.intent.action.APPLICATION_RESTRICTIONS_CHANGED",
-            "android.intent.action.BATTERY_CHANGED",
-            "android.intent.action.BATTERY_LOW",
-            "android.intent.action.BATTERY_OKAY",
-            "android.intent.action.BOOT_COMPLETED",
-            "android.intent.action.BUGREPORT_FINISHED",
-            "android.intent.action.CHARGING",
-            "android.intent.action.CLEAR_DNS_CACHE",
-            "android.intent.action.CONFIGURATION_CHANGED",
-            "android.intent.action.DATE_CHANGED",
-            "android.intent.action.DEVICE_STORAGE_FULL",
-            "android.intent.action.DEVICE_STORAGE_LOW",
-            "android.intent.action.DEVICE_STORAGE_NOT_FULL",
-            "android.intent.action.DEVICE_STORAGE_OK",
-            "android.intent.action.DISCHARGING",
-            "android.intent.action.DOCK_EVENT",
-            "android.intent.action.DREAMING_STARTED",
-            "android.intent.action.DREAMING_STOPPED",
-            "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE",
-            "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE",
-            "android.intent.action.HDMI_PLUGGED",
-            "android.intent.action.HEADSET_PLUG",
-            "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION",
-            "android.intent.action.LOCALE_CHANGED",
-            "android.intent.action.MASTER_CLEAR_NOTIFICATION",
-            "android.intent.action.MEDIA_BAD_REMOVAL",
-            "android.intent.action.MEDIA_CHECKING",
-            "android.intent.action.MEDIA_EJECT",
-            "android.intent.action.MEDIA_MOUNTED",
-            "android.intent.action.MEDIA_NOFS",
-            "android.intent.action.MEDIA_REMOVED",
-            "android.intent.action.MEDIA_SHARED",
-            "android.intent.action.MEDIA_UNMOUNTABLE",
-            "android.intent.action.MEDIA_UNMOUNTED",
-            "android.intent.action.MEDIA_UNSHARED",
-            "android.intent.action.MY_PACKAGE_REPLACED",
-            "android.intent.action.NEW_OUTGOING_CALL",
-            "android.intent.action.PACKAGE_ADDED",
-            "android.intent.action.PACKAGE_CHANGED",
-            "android.intent.action.PACKAGE_DATA_CLEARED",
-            "android.intent.action.PACKAGE_FIRST_LAUNCH",
-            "android.intent.action.PACKAGE_FULLY_REMOVED",
-            "android.intent.action.PACKAGE_INSTALL",
-            "android.intent.action.PACKAGE_NEEDS_VERIFICATION",
-            "android.intent.action.PACKAGE_REMOVED",
-            "android.intent.action.PACKAGE_REPLACED",
-            "android.intent.action.PACKAGE_RESTARTED",
-            "android.intent.action.PACKAGE_VERIFIED",
-            "android.intent.action.PERMISSION_RESPONSE_RECEIVED",
-            "android.intent.action.PHONE_STATE",
-            "android.intent.action.PROXY_CHANGE",
-            "android.intent.action.QUERY_PACKAGE_RESTART",
-            "android.intent.action.REBOOT",
-            "android.intent.action.REQUEST_PERMISSION",
-            "android.intent.action.SCREEN_OFF",
-            "android.intent.action.SCREEN_ON",
-            "android.intent.action.SUB_DEFAULT_CHANGED",
-            "android.intent.action.THERMAL_EVENT",
-            "android.intent.action.TIMEZONE_CHANGED",
-            "android.intent.action.TIME_SET",
-            "android.intent.action.TIME_TICK",
-            "android.intent.action.UID_REMOVED",
-            "android.intent.action.USER_ADDED",
-            "android.intent.action.USER_BACKGROUND",
-            "android.intent.action.USER_FOREGROUND",
-            "android.intent.action.USER_PRESENT",
-            "android.intent.action.USER_REMOVED",
-            "android.intent.action.USER_STARTED",
-            "android.intent.action.USER_STARTING",
-            "android.intent.action.USER_STOPPED",
-            "android.intent.action.USER_STOPPING",
-            "android.intent.action.USER_SWITCHED",
-            "android.internal.policy.action.BURN_IN_PROTECTION",
-            "android.location.GPS_ENABLED_CHANGE",
-            "android.location.GPS_FIX_CHANGE",
-            "android.location.MODE_CHANGED",
-            "android.location.PROVIDERS_CHANGED",
-            "android.media.ACTION_SCO_AUDIO_STATE_UPDATED",
-            "android.media.AUDIO_BECOMING_NOISY",
-            "android.media.MASTER_MUTE_CHANGED_ACTION",
-            "android.media.MASTER_VOLUME_CHANGED_ACTION",
-            "android.media.RINGER_MODE_CHANGED",
-            "android.media.SCO_AUDIO_STATE_CHANGED",
-            "android.media.VIBRATE_SETTING_CHANGED",
-            "android.media.VOLUME_CHANGED_ACTION",
-            "android.media.action.HDMI_AUDIO_PLUG",
-            "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED",
-            "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED",
-            "android.net.conn.CAPTIVE_PORTAL",
-            "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
-            "android.net.conn.CONNECTIVITY_CHANGE",
-            "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE",
-            "android.net.conn.DATA_ACTIVITY_CHANGE",
-            "android.net.conn.INET_CONDITION_ACTION",
-            "android.net.conn.NETWORK_CONDITIONS_MEASURED",
-            "android.net.conn.TETHER_STATE_CHANGED",
-            "android.net.nsd.STATE_CHANGED",
-            "android.net.proxy.PAC_REFRESH",
-            "android.net.scoring.SCORER_CHANGED",
-            "android.net.scoring.SCORE_NETWORKS",
-            "android.net.wifi.CONFIGURED_NETWORKS_CHANGE",
-            "android.net.wifi.LINK_CONFIGURATION_CHANGED",
-            "android.net.wifi.RSSI_CHANGED",
-            "android.net.wifi.SCAN_RESULTS",
-            "android.net.wifi.STATE_CHANGE",
-            "android.net.wifi.WIFI_AP_STATE_CHANGED",
-            "android.net.wifi.WIFI_CREDENTIAL_CHANGED",
-            "android.net.wifi.WIFI_SCAN_AVAILABLE",
-            "android.net.wifi.WIFI_STATE_CHANGED",
-            "android.net.wifi.p2p.CONNECTION_STATE_CHANGE",
-            "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE",
-            "android.net.wifi.p2p.PEERS_CHANGED",
-            "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED",
-            "android.net.wifi.p2p.STATE_CHANGED",
-            "android.net.wifi.p2p.THIS_DEVICE_CHANGED",
-            "android.net.wifi.supplicant.CONNECTION_CHANGE",
-            "android.net.wifi.supplicant.STATE_CHANGE",
-            "android.nfc.action.LLCP_LINK_STATE_CHANGED",
-            "android.nfc.action.TRANSACTION_DETECTED",
-            "android.nfc.handover.intent.action.HANDOVER_STARTED",
-            "android.nfc.handover.intent.action.TRANSFER_DONE",
-            "android.nfc.handover.intent.action.TRANSFER_PROGRESS",
-            "android.os.UpdateLock.UPDATE_LOCK_CHANGED",
-            "android.os.action.DEVICE_IDLE_MODE_CHANGED",
-            "android.os.action.POWER_SAVE_MODE_CHANGED",
-            "android.os.action.POWER_SAVE_MODE_CHANGING",
-            "android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED",
-            "android.os.action.POWER_SAVE_WHITELIST_CHANGED",
-            "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED",
-            "android.os.action.SETTING_RESTORED",
-            "android.telecom.action.DEFAULT_DIALER_CHANGED",
-            "com.android.bluetooth.pbap.authcancelled",
-            "com.android.bluetooth.pbap.authchall",
-            "com.android.bluetooth.pbap.authresponse",
-            "com.android.bluetooth.pbap.userconfirmtimeout",
-            "com.android.nfc_extras.action.AID_SELECTED",
-            "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED",
-            "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED",
-            "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP",
-            "com.android.server.WifiManager.action.START_PNO",
-            "com.android.server.WifiManager.action.START_SCAN",
-            "com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION",
-    };
-
-    private static final Set<String> PROTECTED_BROADCAST_SET =
-            Sets.newHashSet(PROTECTED_BROADCASTS);
-
-    private final Set<String> mReceiversWithProtectedBroadcastIntentFilter = new HashSet<String>();
-
-    public UnsafeBroadcastReceiverDetector() {
-    }
-
-    // ---- Implements XmlScanner ----
-
-    @Override
-    public Collection<String> getApplicableElements() {
-        return Collections.singletonList(TAG_RECEIVER);
-    }
-
-    @Override
-    public void visitElement(@NonNull XmlContext context,
-            @NonNull Element element) {
-        String tag = element.getTagName();
-        if (TAG_RECEIVER.equals(tag)) {
-            String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
-            String permission = element.getAttributeNS(ANDROID_URI, ATTR_PERMISSION);
-            // If no permission attribute, then if any exists at the application
-            // element, it applies
-            if (permission == null || permission.isEmpty()) {
-                Element parent = (Element) element.getParentNode();
-                permission = parent.getAttributeNS(ANDROID_URI, ATTR_PERMISSION);
-            }
-            List<Element> children = LintUtils.getChildren(element);
-            for (Element child : children) {
-                String tagName = child.getTagName();
-                if (TAG_INTENT_FILTER.equals(tagName)) {
-                    if (name.startsWith(".")) {
-                        name = context.getProject().getPackage() + name;
-                    }
-                    name = name.replace('$', '.');
-                    List<Element> children2 = LintUtils.getChildren(child);
-                    for (Element child2 : children2) {
-                        if ("action".equals(child2.getTagName())) {
-                            String actionName = child2.getAttributeNS(
-                                    ANDROID_URI, ATTR_NAME);
-                            if (("android.provider.Telephony.SMS_DELIVER".equals(actionName) ||
-                                    "android.provider.Telephony.SMS_RECEIVED".
-                                        equals(actionName)) &&
-                                    !"android.permission.BROADCAST_SMS".equals(permission)) {
-                                context.report(
-                                        BROADCAST_SMS,
-                                        element,
-                                        context.getLocation(element),
-                                        "BroadcastReceivers that declare an intent-filter for " +
-                                        "SMS_DELIVER or SMS_RECEIVED must ensure that the " +
-                                        "caller has the BROADCAST_SMS permission, otherwise it " +
-                                        "is possible for malicious actors to spoof intents.");
-                            }
-                            else if (PROTECTED_BROADCAST_SET.contains(actionName)) {
-                                mReceiversWithProtectedBroadcastIntentFilter.add(name);
-                            }
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return mReceiversWithProtectedBroadcastIntentFilter.isEmpty()
-                ? null : Collections.singletonList(CLASS_BROADCASTRECEIVER);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        String name = declaration.getName();
-        if (name == null) {
-            // anonymous classes can't be the ones referenced in the manifest
-            return;
-        }
-        String qualifiedName = declaration.getQualifiedName();
-        if (qualifiedName == null) {
-            return;
-        }
-        if (!mReceiversWithProtectedBroadcastIntentFilter.contains(qualifiedName)) {
-            return;
-        }
-        JavaEvaluator evaluator = context.getEvaluator();
-        for (PsiMethod method : declaration.findMethodsByName("onReceive", false)) {
-            if (evaluator.parametersMatch(method, CLASS_CONTEXT, CLASS_INTENT)) {
-                checkOnReceive(context, method);
-            }
-        }
-    }
-
-    private static void checkOnReceive(@NonNull JavaContext context,
-            @NonNull PsiMethod method) {
-        // Search for call to getAction but also search for references to aload_2,
-        // which indicates that the method is making use of the received intent in
-        // some way.
-        //
-        // If the onReceive method doesn't call getAction but does make use of
-        // the received intent, it is possible that it is passing it to another
-        // method that might be performing the getAction check, so we warn that the
-        // finding may be a false positive. (An alternative option would be to not
-        // report a finding at all in this case.)
-        PsiParameter parameter = method.getParameterList().getParameters()[1];
-        OnReceiveVisitor visitor = new OnReceiveVisitor(context.getEvaluator(), parameter);
-        context.getUastContext().getMethodBody(method).accept(visitor);
-        if (!visitor.getCallsGetAction()) {
-            String report;
-            if (!visitor.getUsesIntent()) {
-                report = "This broadcast receiver declares an intent-filter for a protected " +
-                        "broadcast action string, which can only be sent by the system, " +
-                        "not third-party applications. However, the receiver's onReceive " +
-                        "method does not appear to call getAction to ensure that the " +
-                        "received Intent's action string matches the expected value, " +
-                        "potentially making it possible for another actor to send a " +
-                        "spoofed intent with no action string or a different action " +
-                        "string and cause undesired behavior.";
-            } else {
-                // An alternative implementation option is to not report a finding at all in
-                // this case, if we are worried about false positives causing confusion or
-                // resulting in developers ignoring other lint warnings.
-                report = "This broadcast receiver declares an intent-filter for a protected " +
-                        "broadcast action string, which can only be sent by the system, " +
-                        "not third-party applications. However, the receiver's onReceive " +
-                        "method does not appear to call getAction to ensure that the " +
-                        "received Intent's action string matches the expected value, " +
-                        "potentially making it possible for another actor to send a " +
-                        "spoofed intent with no action string or a different action " +
-                        "string and cause undesired behavior. In this case, it is " +
-                        "possible that the onReceive method passed the received Intent " +
-                        "to another method that checked the action string. If so, this " +
-                        "finding can safely be ignored.";
-            }
-            Location location = context.getNameLocation(method);
-            context.report(ACTION_STRING, method, location, report);
-        }
-    }
-
-    private static class OnReceiveVisitor extends AbstractUastVisitor {
-        @NonNull private final JavaEvaluator mEvaluator;
-        @Nullable private final PsiParameter mParameter;
-        private boolean mCallsGetAction;
-        private boolean mUsesIntent;
-
-        public OnReceiveVisitor(@NonNull JavaEvaluator context, @Nullable PsiParameter parameter) {
-            mEvaluator = context;
-            mParameter = parameter;
-        }
-
-        public boolean getCallsGetAction() {
-            return mCallsGetAction;
-        }
-
-        public boolean getUsesIntent() {
-            return mUsesIntent;
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (!mCallsGetAction && UastExpressionUtils.isMethodCall(node)) {
-                PsiMethod method = node.resolve();
-                if (method != null && "getAction".equals(method.getName()) &&
-                        mEvaluator.isMemberInSubClassOf(method, CLASS_INTENT, false)) {
-                    mCallsGetAction = true;
-                }
-            }
-            return super.visitCallExpression(node);
-        }
-
-        @Override
-        public boolean visitSimpleNameReferenceExpression(USimpleNameReferenceExpression node) {
-            if (!mUsesIntent && mParameter != null) {
-                PsiElement resolved = node.resolve();
-                if (mParameter.equals(resolved)) {
-                    mUsesIntent = true;
-                }
-            }
-            return super.visitSimpleNameReferenceExpression(node);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeNativeCodeDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeNativeCodeDetector.java
deleted file mode 100644
index f64cb6f..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnsafeNativeCodeDetector.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2015 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.klint.checks;
-
-import static com.android.SdkConstants.DOT_NATIVE_LIBS;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Project;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.Speed;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-public class UnsafeNativeCodeDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            UnsafeNativeCodeDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    public static final Issue LOAD = Issue.create(
-            "UnsafeDynamicallyLoadedCode",
-            "`load` used to dynamically load code",
-            "Dynamically loading code from locations other than the application's library " +
-            "directory or the Android platform's built-in library directories is dangerous, " +
-            "as there is an increased risk that the code could have been tampered with. " +
-            "Applications should use `loadLibrary` when possible, which provides increased " +
-            "assurance that libraries are loaded from one of these safer locations. " +
-            "Application developers should use the features of their development " +
-            "environment to place application native libraries into the lib directory " +
-            "of their compiled APKs.",
-            Category.SECURITY,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    public static final Issue UNSAFE_NATIVE_CODE_LOCATION = Issue.create(
-            "UnsafeNativeCodeLocation", //$NON-NLS-1$
-            "Native code outside library directory",
-            "In general, application native code should only be placed in the application's " +
-            "library directory, not in other locations such as the res or assets directories. " +
-            "Placing the code in the library directory provides increased assurance that the " +
-            "code will not be tampered with after application installation. Application " +
-            "developers should use the features of their development environment to place " +
-            "application native libraries into the lib directory of their compiled " +
-            "APKs. Embedding non-shared library native executables into applications should " +
-            "be avoided when possible.",
-            Category.SECURITY,
-            4,
-            Severity.WARNING,
-            IMPLEMENTATION);
-
-    private static final String RUNTIME_CLASS = "java.lang.Runtime"; //$NON-NLS-1$
-    private static final String SYSTEM_CLASS = "java.lang.System"; //$NON-NLS-1$
-
-    private static final byte[] ELF_MAGIC_VALUE = { (byte) 0x7F, (byte) 0x45, (byte) 0x4C, (byte) 0x46 };
-
-    @NonNull
-    @Override
-    public Speed getSpeed() {
-        return Speed.NORMAL;
-    }
-
-    // ---- Implements Detector.UastScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        // Identify calls to Runtime.load() and System.load()
-        return Collections.singletonList("load");
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        // Report calls to Runtime.load() and System.load()
-        if ("load".equals(method.getName())) {
-            JavaEvaluator evaluator = context.getEvaluator();
-            if (evaluator.isMemberInSubClassOf(method, RUNTIME_CLASS, false) ||
-                    evaluator.isMemberInSubClassOf(method, SYSTEM_CLASS, false)) {
-                context.report(LOAD, call, context.getUastLocation(call),
-                        "Dynamically loading code using `load` is risky, please use " +
-                                "`loadLibrary` instead when possible");
-            }
-        }
-    }
-
-    // ---- Look for code in resource and asset directories ----
-
-    @Override
-    public void afterCheckLibraryProject(@NonNull Context context) {
-        if (!context.getProject().getReportIssues()) {
-            // If this is a library project not being analyzed, ignore it
-            return;
-        }
-
-        checkResourceFolders(context, context.getProject());
-    }
-
-    @Override
-    public void afterCheckProject(@NonNull Context context) {
-        if (!context.getProject().getReportIssues()) {
-            // If this is a library project not being analyzed, ignore it
-            return;
-        }
-
-        checkResourceFolders(context, context.getProject());
-    }
-
-    private static boolean isNativeCode(File file) {
-        if (!file.isFile()) {
-            return false;
-        }
-
-        try {
-            FileInputStream fis = new FileInputStream(file);
-            try {
-                byte[] bytes = new byte[4];
-                int length = fis.read(bytes);
-                return (length == 4) && (Arrays.equals(ELF_MAGIC_VALUE, bytes));
-            } finally {
-                fis.close();
-            }
-        } catch (IOException ex) {
-            return false;
-        }
-    }
-
-    private static void checkResourceFolders(Context context, @NonNull Project project) {
-        if (!context.getScope().contains(Scope.RESOURCE_FOLDER)) {
-            // Don't do work when doing in-editor analysis of Java files
-            return;
-        }
-        List<File> resourceFolders = project.getResourceFolders();
-        for (File res : resourceFolders) {
-            File[] folders = res.listFiles();
-            if (folders != null) {
-                for (File typeFolder : folders) {
-                    if (typeFolder.getName().startsWith(SdkConstants.FD_RES_RAW)) {
-                        File[] rawFiles = typeFolder.listFiles();
-                        if (rawFiles != null) {
-                            for (File rawFile : rawFiles) {
-                                checkFile(context, rawFile);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        List<File> assetFolders = project.getAssetFolders();
-        for (File assetFolder : assetFolders) {
-            File[] assets = assetFolder.listFiles();
-            if (assets != null) {
-                for (File asset : assets) {
-                    checkFile(context, asset);
-                }
-            }
-        }
-    }
-
-    private static void checkFile(@NonNull Context context, @NonNull File file) {
-        if (isNativeCode(file)) {
-            if (LintUtils.endsWith(file.getPath(), DOT_NATIVE_LIBS)) {
-                context.report(UNSAFE_NATIVE_CODE_LOCATION, Location.create(file),
-                        "Shared libraries should not be placed in the res or assets " +
-                        "directories. Please use the features of your development " +
-                        "environment to place shared libraries in the lib directory of " +
-                        "the compiled APK.");
-            } else {
-                context.report(UNSAFE_NATIVE_CODE_LOCATION, Location.create(file),
-                        "Embedding non-shared library native executables into applications " +
-                        "should be avoided when possible, as there is an increased risk that " +
-                        "the executables could be tampered with after installation. Instead, " +
-                        "native code should be placed in a shared library, and the features of " +
-                        "the development environment should be used to place the shared library " +
-                        "in the lib directory of the compiled APK.");
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewConstructorDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewConstructorDetector.java
deleted file mode 100644
index a7b57c1..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewConstructorDetector.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_ATTRIBUTE_SET;
-import static com.android.SdkConstants.CLASS_CONTEXT;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.ClassContext;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameter;
-import com.intellij.psi.PsiParameterList;
-import com.intellij.psi.PsiType;
-
-import org.jetbrains.uast.UClass;
-import org.jetbrains.org.objectweb.asm.tree.ClassNode;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for custom views that do not define the view constructors needed by UI builders
- */
-public class ViewConstructorDetector extends Detector implements Detector.UastScanner {
-    /** The main issue discovered by this detector */
-    public static final Issue ISSUE = Issue.create(
-            "ViewConstructor", //$NON-NLS-1$
-            "Missing View constructors for XML inflation",
-
-            "Some layout tools (such as the Android layout editor) need to " +
-            "find a constructor with one of the following signatures:\n" +
-            "* `View(Context context)`\n" +
-            "* `View(Context context, AttributeSet attrs)`\n" +
-            "* `View(Context context, AttributeSet attrs, int defStyle)`\n" +
-            "\n" +
-            "If your custom view needs to perform initialization which does not apply when " +
-            "used in a layout editor, you can surround the given code with a check to " +
-            "see if `View#isInEditMode()` is false, since that method will return `false` " +
-            "at runtime but true within a user interface editor.",
-
-            Category.USABILITY,
-            3,
-            Severity.WARNING,
-            new Implementation(
-                    ViewConstructorDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link ViewConstructorDetector} check */
-    public ViewConstructorDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    private static boolean isXmlConstructor(
-            @NonNull JavaEvaluator evaluator,
-            @NonNull PsiMethod method) {
-        // Accept
-        //   android.content.Context
-        //   android.content.Context,android.util.AttributeSet
-        //   android.content.Context,android.util.AttributeSet,int
-        PsiParameterList parameterList = method.getParameterList();
-        int argumentCount = parameterList.getParametersCount();
-        if (argumentCount == 0 || argumentCount > 3) {
-            return false;
-        }
-        PsiParameter[] parameters = parameterList.getParameters();
-        if (!evaluator.typeMatches(parameters[0].getType(), CLASS_CONTEXT)) {
-            return false;
-        }
-        if (argumentCount == 1) {
-            return true;
-        }
-        if (!evaluator.typeMatches(parameters[1].getType(), CLASS_ATTRIBUTE_SET)) {
-            return false;
-        }
-        //noinspection SimplifiableIfStatement
-        if (argumentCount == 2) {
-            return true;
-        }
-        return PsiType.INT.equals(parameters[2].getType());
-    }
-
-    @Nullable
-    @Override
-    public List<String> applicableSuperClasses() {
-        return Collections.singletonList(SdkConstants.CLASS_VIEW);
-    }
-
-    @Override
-    public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
-        // Only applies to concrete classes
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (evaluator.isAbstract(declaration) || declaration instanceof PsiAnonymousClass) {
-            // Ignore abstract classes
-            return;
-        }
-
-        if (declaration.getContainingClass() != null &&
-                !evaluator.isStatic(declaration)) {
-            // Ignore inner classes that aren't static: we can't create these
-            // anyway since we'd need the outer instance
-            return;
-        }
-
-        boolean found = false;
-        for (PsiMethod constructor : declaration.getConstructors()) {
-            if (isXmlConstructor(evaluator, constructor)) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            String message = String.format(
-                    "Custom view `%1$s` is missing constructor used by tools: "
-                            + "`(Context)` or `(Context,AttributeSet)` "
-                            + "or `(Context,AttributeSet,int)`",
-                    declaration.getName());
-            Location location = context.getUastNameLocation(declaration);
-            context.reportUast(ISSUE, declaration, location, message  /*data*/);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java
deleted file mode 100644
index 94fc4986..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2014 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_VIEW;
-import static com.android.SdkConstants.CLASS_VIEWGROUP;
-import static com.android.tools.klint.client.api.JavaParser.TYPE_INT;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.collect.Lists;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UIfExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.USwitchExpression;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.util.UastExpressionUtils;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Looks for ListView scrolling performance: should use view holder pattern
- */
-public class ViewHolderDetector extends Detector implements Detector.UastScanner {
-
-    private static final Implementation IMPLEMENTATION = new Implementation(
-            ViewHolderDetector.class,
-            Scope.JAVA_FILE_SCOPE);
-
-    /** Using a view inflater unconditionally in an AdapterView */
-    public static final Issue ISSUE = Issue.create(
-            "ViewHolder", //$NON-NLS-1$
-            "View Holder Candidates",
-
-            "When implementing a view Adapter, you should avoid unconditionally inflating a " +
-            "new layout; if an available item is passed in for reuse, you should try to " +
-            "use that one instead. This helps make for example ListView scrolling much " +
-            "smoother.",
-
-            Category.PERFORMANCE,
-            5,
-            Severity.WARNING,
-            IMPLEMENTATION)
-            .addMoreInfo(
-            "http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder");
-
-    private static final String GET_VIEW = "getView";  //$NON-NLS-1$
-    static final String INFLATE = "inflate";           //$NON-NLS-1$
-
-    /** Constructs a new {@link ViewHolderDetector} check */
-    public ViewHolderDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(UMethod.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new ViewAdapterVisitor(context);
-    }
-
-    private static class ViewAdapterVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        public ViewAdapterVisitor(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitMethod(UMethod method) {
-            if (isViewAdapterMethod(mContext, method)) {
-                InflationVisitor visitor = new InflationVisitor(mContext);
-                method.accept(visitor);
-                visitor.finish();
-            }
-            return super.visitMethod(method);
-        }
-
-        /**
-         * Returns true if this method looks like it's overriding android.widget.Adapter's getView
-         * method: getView(int position, View convertView, ViewGroup parent)
-         */
-        private static boolean isViewAdapterMethod(JavaContext context, PsiMethod node) {
-            JavaEvaluator evaluator = context.getEvaluator();
-            return GET_VIEW.equals(node.getName()) && evaluator.parametersMatch(node,
-                    TYPE_INT, CLASS_VIEW, CLASS_VIEWGROUP);
-        }
-    }
-
-    private static class InflationVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-        private List<UElement> mNodes;
-        private boolean mHaveConditional;
-
-        public InflationVisitor(JavaContext context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitCallExpression(UCallExpression node) {
-            if (UastExpressionUtils.isMethodCall(node)) {
-                checkMethodCall(node);
-            }
-            return super.visitCallExpression(node);
-        }
-
-        private void checkMethodCall(UCallExpression node) {
-            UExpression receiver = node.getReceiver();
-            if (receiver != null) {
-                String methodName = node.getMethodName();
-                if (INFLATE.equals(methodName)
-                        && node.getValueArgumentCount() >= 1) {
-                    // See if we're inside a conditional
-                    boolean insideIf = false;
-                    //noinspection unchecked
-                    if (UastUtils.getParentOfType(node, true, UIfExpression.class, 
-                            USwitchExpression.class) != null) {
-                        insideIf = true;
-                        mHaveConditional = true;
-                    }
-                    if (!insideIf) {
-                        // Rather than reporting immediately, we only report if we didn't
-                        // find any conditionally executed inflate statements in the method.
-                        // This is because there are cases where getView method is complicated
-                        // and inflates not just the top level layout but also children
-                        // of the view, and we don't want to flag these. (To be more accurate
-                        // should perform flow analysis and only report unconditional inflation
-                        // of layouts that wind up flowing to the return value; that requires
-                        // more work, and this simple heuristic is good enough for nearly all test
-                        // cases I've come across.
-                        if (mNodes == null) {
-                            mNodes = Lists.newArrayList();
-                        }
-                        mNodes.add(node);
-                    }
-                }
-            }
-        }
-
-        public void finish() {
-            if (!mHaveConditional && mNodes != null) {
-                for (UElement node : mNodes) {
-                    String message = "Unconditional layout inflation from view adapter: "
-                            + "Should use View Holder pattern (use recycled view passed "
-                            + "into this method as the second parameter) for smoother "
-                            + "scrolling";
-                    mContext.report(ISSUE, node, mContext.getUastLocation(node), message);
-                }
-            }
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTagDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTagDetector.java
deleted file mode 100644
index 93ea1dd..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTagDetector.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_VIEW;
-import static com.android.tools.klint.checks.CleanupDetector.CURSOR_CLS;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TypeEvaluator;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiType;
-
-import com.intellij.psi.util.InheritanceUtil;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for missing view tag detectors
- */
-public class ViewTagDetector extends Detector implements Detector.UastScanner {
-    /** Using setTag and leaking memory */
-    public static final Issue ISSUE = Issue.create(
-            "ViewTag", //$NON-NLS-1$
-            "Tagged object leaks",
-
-            "Prior to Android 4.0, the implementation of `View.setTag(int, Object)` would " +
-            "store the objects in a static map, where the values were strongly referenced. " +
-            "This means that if the object contains any references pointing back to the " +
-            "context, the context (which points to pretty much everything else) will leak. " +
-            "If you pass a view, the view provides a reference to the context " +
-            "that created it. Similarly, view holders typically contain a view, and cursors " +
-            "are sometimes also associated with views.",
-
-            Category.PERFORMANCE,
-            6,
-            Severity.WARNING,
-            new Implementation(
-                    ViewTagDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link ViewTagDetector} */
-    public ViewTagDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-    @Nullable
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("setTag");
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        // The leak behavior is fixed in ICS:
-        // http://code.google.com/p/android/issues/detail?id=18273
-        if (context.getMainProject().getMinSdk() >= 14) {
-            return;
-        }
-
-        JavaEvaluator evaluator = context.getEvaluator();
-        if (!evaluator.isMemberInSubClassOf(method, CLASS_VIEW, false)) {
-            return;
-        }
-        
-        List<UExpression> arguments = call.getValueArguments();
-        if (arguments.size() != 2) {
-            return;
-        }
-        UExpression tagArgument = arguments.get(1);
-        if (tagArgument == null) {
-            return;
-        }
-
-        PsiType type = TypeEvaluator.evaluate(context, tagArgument);
-        if ((!(type instanceof PsiClassType))) {
-            return;
-        }
-        PsiClass typeClass = ((PsiClassType) type).resolve();
-        if (typeClass == null) {
-            return;
-        }
-
-        String objectType;
-        if (InheritanceUtil.isInheritor(typeClass, false, CLASS_VIEW)) {
-            objectType = "views";
-        } else if (InheritanceUtil.isInheritor(typeClass, false, CURSOR_CLS)) {
-            objectType = "cursors";
-        } else if (typeClass.getName() != null && typeClass.getName().endsWith("ViewHolder")) {
-            objectType = "view holders";
-        } else {
-            return;
-        }
-        String message = String.format("Avoid setting %1$s as values for `setTag`: " +
-                        "Can lead to memory leaks in versions older than Android 4.0",
-                objectType);
-
-        context.report(ISSUE, call, context.getUastLocation(tagArgument), message);
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTypeDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTypeDetector.java
deleted file mode 100644
index d29ca09..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewTypeDetector.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceFile;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.resources.ResourceUrl;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.detector.api.*;
-import com.android.utils.XmlUtils;
-import com.google.common.base.Joiner;
-import com.google.common.collect.*;
-import com.intellij.psi.PsiClassType;
-import com.intellij.psi.PsiType;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.visitor.UastVisitor;
-import org.w3c.dom.*;
-
-import java.io.File;
-import java.util.*;
-
-import static com.android.SdkConstants.*;
-
-/** Detector for finding inconsistent usage of views and casts
- * <p>
- * TODO: Check findFragmentById
- * <pre>
- * ((ItemListFragment) getSupportFragmentManager()
- *   .findFragmentById(R.id.item_list))
- *   .setActivateOnItemClick(true);
- * </pre>
- * Here we should check the {@code <fragment>} tag pointed to by the id, and
- * check its name or class attributes to make sure the cast is compatible with
- * the named fragment class!
- */
-public class ViewTypeDetector extends ResourceXmlDetector implements Detector.UastScanner {
-    /** Mismatched view types */
-    @SuppressWarnings("unchecked")
-    public static final Issue ISSUE = Issue.create(
-            "WrongViewCast", //$NON-NLS-1$
-            "Mismatched view type",
-            "Keeps track of the view types associated with ids and if it finds a usage of " +
-            "the id in the Java code it ensures that it is treated as the same type.",
-            Category.CORRECTNESS,
-            9,
-            Severity.FATAL,
-            new Implementation(
-                    ViewTypeDetector.class,
-                    EnumSet.of(Scope.ALL_RESOURCE_FILES, Scope.ALL_JAVA_FILES),
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Flag used to do no work if we're running in incremental mode in a .java file without
-     * a client supporting project resources */
-    private Boolean mIgnore = null;
-
-    private final Map<String, Object> mIdToViewTag = new HashMap<String, Object>(50);
-
-    @NonNull
-    @Override
-    public Speed getSpeed() {
-        return Speed.SLOW;
-    }
-
-    @Override
-    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
-        return folderType == ResourceFolderType.LAYOUT;
-    }
-
-    @Override
-    public Collection<String> getApplicableAttributes() {
-        return Collections.singletonList(ATTR_ID);
-    }
-
-    @Override
-    public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
-        String view = attribute.getOwnerElement().getTagName();
-        String value = attribute.getValue();
-        String id = null;
-        if (value.startsWith(ID_PREFIX)) {
-            id = value.substring(ID_PREFIX.length());
-        } else if (value.startsWith(NEW_ID_PREFIX)) {
-            id = value.substring(NEW_ID_PREFIX.length());
-        } // else: could be @android id
-
-        if (id != null) {
-            if (view.equals(VIEW_TAG)) {
-                view = attribute.getOwnerElement().getAttribute(ATTR_CLASS);
-            }
-
-            Object existing = mIdToViewTag.get(id);
-            if (existing == null) {
-                mIdToViewTag.put(id, view);
-            } else if (existing instanceof String) {
-                String existingString = (String) existing;
-                if (!existingString.equals(view)) {
-                    // Convert to list
-                    List<String> list = new ArrayList<String>(2);
-                    list.add((String) existing);
-                    list.add(view);
-                    mIdToViewTag.put(id, list);
-                }
-            } else if (existing instanceof List<?>) {
-                @SuppressWarnings("unchecked")
-                List<String> list = (List<String>) existing;
-                if (!list.contains(view)) {
-                    list.add(view);
-                }
-            }
-        }
-    }
-
-    // ---- Implements Detector.JavaScanner ----
-
-    @Override
-    public List<String> getApplicableMethodNames() {
-        return Collections.singletonList("findViewById"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression call, @NonNull UMethod method) {
-        LintClient client = context.getClient();
-        if (mIgnore == Boolean.TRUE) {
-            return;
-        } else if (mIgnore == null) {
-            mIgnore = !context.getScope().contains(Scope.ALL_RESOURCE_FILES) &&
-                    !client.supportsProjectResources();
-            if (mIgnore) {
-                return;
-            }
-        }
-        assert method.getName().equals("findViewById");
-        UElement node = LintUtils.skipParentheses(call);
-        while (node != null && node.getUastParent() instanceof UParenthesizedExpression) {
-            node = node.getUastParent();
-        }
-        if (node.getUastParent() instanceof UBinaryExpressionWithType) {
-            UBinaryExpressionWithType cast = (UBinaryExpressionWithType) node.getUastParent();
-            PsiType type = cast.getType();
-            String castType = null;
-            if (type instanceof PsiClassType) {
-                castType = type.getCanonicalText();
-            }
-            if (castType == null) {
-                return;
-            }
-
-            List<UExpression> args = call.getValueArguments();
-            if (args.size() == 1) {
-                UExpression first = args.get(0);
-                ResourceUrl resourceUrl = ResourceEvaluator.getResource(context, first);
-                if (resourceUrl != null && resourceUrl.type == ResourceType.ID &&
-                        !resourceUrl.framework) {
-                    String id = resourceUrl.name;
-
-                    if (client.supportsProjectResources()) {
-                        AbstractResourceRepository resources = client
-                                .getProjectResources(context.getMainProject(), true);
-                        if (resources == null) {
-                            return;
-                        }
-
-                        List<ResourceItem> items = resources.getResourceItem(ResourceType.ID,
-                                id);
-                        if (items != null && !items.isEmpty()) {
-                            Set<String> compatible = Sets.newHashSet();
-                            for (ResourceItem item : items) {
-                                Collection<String> tags = getViewTags(context, item);
-                                if (tags != null) {
-                                    compatible.addAll(tags);
-                                }
-                            }
-                            if (!compatible.isEmpty()) {
-                                ArrayList<String> layoutTypes = Lists.newArrayList(compatible);
-                                checkCompatible(context, castType, null, layoutTypes, cast);
-                            }
-                        }
-                    } else {
-                        Object types = mIdToViewTag.get(id);
-                        if (types instanceof String) {
-                            String layoutType = (String) types;
-                            checkCompatible(context, castType, layoutType, null, cast);
-                        } else if (types instanceof List<?>) {
-                            @SuppressWarnings("unchecked")
-                            List<String> layoutTypes = (List<String>) types;
-                            checkCompatible(context, castType, null, layoutTypes, cast);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Nullable
-    protected Collection<String> getViewTags(
-            @NonNull Context context,
-            @NonNull ResourceItem item) {
-        // Check view tag in this file. Can I do it cheaply? Try with
-        // an XML pull parser. Or DOM if we have multiple resources looked
-        // up?
-        ResourceFile source = item.getSource();
-        if (source != null) {
-            File file = source.getFile();
-            Multimap<String,String> map = getIdToTagsIn(context, file);
-            if (map != null) {
-                return map.get(item.getName());
-            }
-        }
-
-        return null;
-    }
-
-
-    private Map<File, Multimap<String, String>> mFileIdMap;
-
-    @Nullable
-    private Multimap<String, String> getIdToTagsIn(@NonNull Context context, @NonNull File file) {
-        if (!file.getPath().endsWith(DOT_XML)) {
-            return null;
-        }
-        if (mFileIdMap == null) {
-            mFileIdMap = Maps.newHashMap();
-        }
-        Multimap<String, String> map = mFileIdMap.get(file);
-        if (map == null) {
-            map = ArrayListMultimap.create();
-            mFileIdMap.put(file, map);
-
-            String xml = context.getClient().readFile(file);
-            // TODO: Use pull parser instead for better performance!
-            Document document = XmlUtils.parseDocumentSilently(xml, true);
-            if (document != null && document.getDocumentElement() != null) {
-                addViewTags(map, document.getDocumentElement());
-            }
-        }
-        return map;
-    }
-
-    private static void addViewTags(Multimap<String, String> map, Element element) {
-        String id = element.getAttributeNS(ANDROID_URI, ATTR_ID);
-        if (id != null && !id.isEmpty()) {
-            id = LintUtils.stripIdPrefix(id);
-            if (!map.containsEntry(id, element.getTagName())) {
-                map.put(id, element.getTagName());
-            }
-        }
-
-        NodeList children = element.getChildNodes();
-        for (int i = 0, n = children.getLength(); i < n; i++) {
-            Node child = children.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                addViewTags(map, (Element) child);
-            }
-        }
-    }
-
-    /** Check if the view and cast type are compatible */
-    private static void checkCompatible(JavaContext context, String castType, String layoutType,
-            List<String> layoutTypes, UBinaryExpressionWithType node) {
-        assert layoutType == null || layoutTypes == null; // Should only specify one or the other
-        boolean compatible = true;
-        if (layoutType != null) {
-            if (!layoutType.equals(castType)
-                    && !context.getSdkInfo().isSubViewOf(castType, layoutType)) {
-                compatible = false;
-            }
-        } else {
-            compatible = false;
-            assert layoutTypes != null;
-            for (String type : layoutTypes) {
-                if (type.equals(castType)
-                        || context.getSdkInfo().isSubViewOf(castType, type)) {
-                    compatible = true;
-                    break;
-                }
-            }
-        }
-
-        if (!compatible) {
-            if (layoutType == null) {
-                layoutType = Joiner.on("|").join(layoutTypes);
-            }
-            String message = String.format(
-                    "Unexpected cast to `%1$s`: layout tag was `%2$s`",
-                    castType.substring(castType.lastIndexOf('.') + 1), layoutType);
-            context.report(ISSUE, node, context.getUastLocation(node), message);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongCallDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongCallDetector.java
deleted file mode 100644
index 65a2209..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongCallDetector.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2012 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.klint.checks;
-
-import static com.android.SdkConstants.CLASS_VIEW;
-import static com.android.tools.klint.checks.JavaPerformanceDetector.ON_DRAW;
-import static com.android.tools.klint.checks.JavaPerformanceDetector.ON_LAYOUT;
-import static com.android.tools.klint.checks.JavaPerformanceDetector.ON_MEASURE;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.LintUtils;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.intellij.psi.PsiMethod;
-
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UExpression;
-import org.jetbrains.uast.UMethod;
-import org.jetbrains.uast.USuperExpression;
-import org.jetbrains.uast.UastUtils;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Checks for cases where the wrong call is being made
- */
-public class WrongCallDetector extends Detector implements Detector.UastScanner {
-    /** Calling the wrong method */
-    public static final Issue ISSUE = Issue.create(
-            "WrongCall", //$NON-NLS-1$
-            "Using wrong draw/layout method",
-
-            "Custom views typically need to call `measure()` on their children, not `onMeasure`. " +
-            "Ditto for onDraw, onLayout, etc.",
-
-            Category.CORRECTNESS,
-            6,
-            Severity.FATAL,
-            new Implementation(
-                    WrongCallDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link WrongCallDetector} */
-    public WrongCallDetector() {
-    }
-
-    // ---- Implements UastScanner ----
-
-    @Override
-    @Nullable
-    public List<String> getApplicableMethodNames() {
-        return Arrays.asList(
-                ON_DRAW,
-                ON_MEASURE,
-                ON_LAYOUT
-        );
-    }
-
-    @Override
-    public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor,
-            @NonNull UCallExpression node, @NonNull UMethod calledMethod) {
-        // Call is only allowed if it is both only called on the super class (invoke special)
-        // as well as within the same overriding method (e.g. you can't call super.onLayout
-        // from the onMeasure method)
-        UExpression operand = node.getReceiver();
-        if (!(operand instanceof USuperExpression)) {
-            report(context, node, calledMethod);
-            return;
-        }
-
-        PsiMethod method = UastUtils.getParentOfType(node, UMethod.class, true);
-        if (method != null) {
-            String callName = node.getMethodName();
-            if (callName != null && !callName.equals(method.getName())) {
-                report(context, node, calledMethod);
-            }
-        }
-    }
-
-    private static void report(
-            @NonNull JavaContext context,
-            @NonNull UCallExpression node,
-            @NonNull PsiMethod method) {
-        // Make sure the call is on a view
-        if (!context.getEvaluator().isMemberInSubClassOf(method, CLASS_VIEW, false)) {
-            return;
-        }
-
-        String name = method.getName();
-        String suggestion = Character.toLowerCase(name.charAt(2)) + name.substring(3);
-        String message = String.format(
-                // Keep in sync with {@link #getOldValue} and {@link #getNewValue} below!
-                "Suspicious method call; should probably call \"`%1$s`\" rather than \"`%2$s`\"",
-                suggestion, name);
-        context.report(ISSUE, node, context.getUastNameLocation(node), message);
-    }
-
-    /**
-     * Given an error message produced by this lint detector for the given issue type,
-     * returns the old value to be replaced in the source code.
-     * <p>
-     * Intended for IDE quickfix implementations.
-     *
-     * @param errorMessage the error message associated with the error
-     * @param format the format of the error message
-     * @return the corresponding old value, or null if not recognized
-     */
-    @Nullable
-    public static String getOldValue(@NonNull String errorMessage, @NonNull TextFormat format) {
-        errorMessage = format.toText(errorMessage);
-        return LintUtils.findSubstring(errorMessage, "than \"", "\"");
-    }
-
-    /**
-     * Given an error message produced by this lint detector for the given issue type,
-     * returns the new value to be put into the source code.
-     * <p>
-     * Intended for IDE quickfix implementations.
-     *
-     * @param errorMessage the error message associated with the error
-     * @param format the format of the error message
-     * @return the corresponding new value, or null if not recognized
-     */
-    @Nullable
-    public static String getNewValue(@NonNull String errorMessage, @NonNull TextFormat format) {
-        errorMessage = format.toText(errorMessage);
-        return LintUtils.findSubstring(errorMessage, "call \"", "\"");
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java
deleted file mode 100644
index 6d3f85f..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 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.klint.checks;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.detector.api.Category;
-import com.android.tools.klint.detector.api.Detector;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Scope;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UImportStatement;
-import org.jetbrains.uast.visitor.AbstractUastVisitor;
-import org.jetbrains.uast.visitor.UastVisitor;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Checks for "import android.R", which seems to be a common source of confusion
- * (see for example http://stackoverflow.com/questions/885009/r-cannot-be-resolved-android-error
- * and many other forums).
- * <p>
- * The root cause is probably this (from http://source.android.com/source/using-eclipse.html) :
- * <blockquote> Note: Eclipse sometimes likes to add an import android.R
- * statement at the top of your files that use resources, especially when you
- * ask eclipse to sort or otherwise manage imports. This will cause your make to
- * break. Look out for these erroneous import statements and delete them.
- * </blockquote>
- */
-public class WrongImportDetector extends Detector implements Detector.UastScanner {
-    /** Is android.R being imported? */
-    public static final Issue ISSUE = Issue.create(
-            "SuspiciousImport", //$NON-NLS-1$
-            "'`import android.R`' statement",
-            "Importing `android.R` is usually not intentional; it sometimes happens when " +
-            "you use an IDE and ask it to automatically add imports at a time when your " +
-            "project's R class it not present.\n" +
-            "\n" +
-            "Once the import is there you might get a lot of \"confusing\" error messages " +
-            "because of course the fields available on `android.R` are not the ones you'd " +
-            "expect from just looking at your own `R` class.",
-            Category.CORRECTNESS,
-            9,
-            Severity.WARNING,
-            new Implementation(
-                    WrongImportDetector.class,
-                    Scope.JAVA_FILE_SCOPE));
-
-    /** Constructs a new {@link WrongImportDetector} check */
-    public WrongImportDetector() {
-    }
-
-    // ---- Implements JavaScanner ----
-
-
-    @Nullable
-    @Override
-    public List<Class<? extends UElement>> getApplicableUastTypes() {
-        return Collections.<Class<? extends UElement>>singletonList(UImportStatement.class);
-    }
-
-    @Nullable
-    @Override
-    public UastVisitor createUastVisitor(@NonNull JavaContext context) {
-        return new ImportVisitor(context);
-    }
-
-    private static class ImportVisitor extends AbstractUastVisitor {
-        private final JavaContext mContext;
-
-        private ImportVisitor(JavaContext context) {
-            super();
-            mContext = context;
-        }
-
-        @Override
-        public boolean visitImportStatement(UImportStatement statement) {
-            PsiElement resolved = statement.resolve();
-            if (resolved instanceof PsiClass) {
-                String qualifiedName = ((PsiClass) resolved).getQualifiedName();
-                if ("android.R".equals(qualifiedName)) {
-                    Location location = mContext.getUastLocation(statement);
-                    mContext.report(ISSUE, statement, location,
-                            "Don't include `android.R` here; use a fully qualified name for "
-                                    + "each usage instead");
-                }
-            }
-            
-            return super.visitImportStatement(statement);
-        }
-    }
-}
diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/api-versions-support-library.xml b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/api-versions-support-library.xml
deleted file mode 100644
index faa8970..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/api-versions-support-library.xml
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 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.
--->
-<!-- This file is generated by ApiLookupTest#generateSupportLibraryFile() -->
-<api version="2">
-    <class name="android/support/design/internal/ForegroundLinearLayout" since="7">
-        <extends name="android/support/v7/widget/LinearLayoutCompat" />
-        <method name="drawableHotspotChanged(FF)V" since="7" />
-        <method name="getForeground()Landroid/graphics/drawable/Drawable;" since="7" />
-        <method name="getForegroundGravity()I" since="7" />
-        <method name="jumpDrawablesToCurrentState()V" since="7" />
-        <method name="setForeground(Landroid/graphics/drawable/Drawable;)V" since="7" />
-        <method name="setForegroundGravity(I)V" since="7" />
-    </class>
-    <class name="android/support/design/widget/CoordinatorLayout" since="7">
-        <extends name="android/view/ViewGroup" />
-        <method name="getNestedScrollAxes()I" since="7" />
-        <method name="onNestedFling(Landroid/view/View;FFZ)Z" since="7" />
-        <method name="onNestedPreFling(Landroid/view/View;FF)Z" since="7" />
-        <method name="onNestedPreScroll(Landroid/view/View;II[I)V" since="7" />
-        <method name="onNestedScroll(Landroid/view/View;IIII)V" since="7" />
-        <method name="onNestedScrollAccepted(Landroid/view/View;Landroid/view/View;I)V" since="7" />
-        <method name="onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z" since="7" />
-        <method name="onStopNestedScroll(Landroid/view/View;)V" since="7" />
-    </class>
-    <class name="android/support/design/widget/FloatingActionButton" since="7">
-        <extends name="android/widget/ImageButton" />
-        <method name="getBackgroundTintList()Landroid/content/res/ColorStateList;" since="7" />
-        <method name="getBackgroundTintMode()Landroid/graphics/PorterDuff$Mode;" since="7" />
-        <method name="jumpDrawablesToCurrentState()V" since="7" />
-        <method name="setBackgroundTintList(Landroid/content/res/ColorStateList;)V" since="7" />
-        <method name="setBackgroundTintMode(Landroid/graphics/PorterDuff$Mode;)V" since="7" />
-    </class>
-    <class name="android/support/design/widget/TextInputLayout" since="7">
-        <extends name="android/widget/LinearLayout" />
-        <method name="&lt;init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V" since="7" />
-    </class>
-    <class name="android/support/v17/leanback/transition/FadeAndShortSlide" since="17">
-        <extends name="android/transition/Visibility" />
-        <method name="&lt;init>()V" since="17" />
-        <method name="addListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;" since="17" />
-        <method name="captureEndValues(Landroid/transition/TransitionValues;)V" since="17" />
-        <method name="captureStartValues(Landroid/transition/TransitionValues;)V" since="17" />
-        <method name="clone()Landroid/transition/Transition;" since="17" />
-        <method name="clone()Ljava/lang/Object;" since="17" />
-        <method name="onAppear(Landroid/view/ViewGroup;Landroid/view/View;Landroid/transition/TransitionValues;Landroid/transition/TransitionValues;)Landroid/animation/Animator;" since="17" />
-        <method name="onDisappear(Landroid/view/ViewGroup;Landroid/view/View;Landroid/transition/TransitionValues;Landroid/transition/TransitionValues;)Landroid/animation/Animator;" since="17" />
-        <method name="removeListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;" since="17" />
-        <method name="setEpicenterCallback(Landroid/transition/Transition$EpicenterCallback;)V" since="17" />
-    </class>
-    <class name="android/support/v17/leanback/transition/SlideNoPropagation" since="17">
-        <extends name="android/transition/Slide" />
-        <method name="&lt;init>()V" since="17" />
-        <method name="&lt;init>(I)V" since="17" />
-        <method name="&lt;init>(Landroid/content/Context;Landroid/util/AttributeSet;)V" since="17" />
-        <method name="setSlideEdge(I)V" since="17" />
-    </class>
-    <class name="android/support/v4/view/ViewPager" since="4">
-        <extends name="android/view/ViewGroup" />
-        <method name="canScrollHorizontally(I)Z" since="4" />
-    </class>
-    <class name="android/support/v4/widget/DrawerLayout" since="4">
-        <extends name="android/view/ViewGroup" />
-        <method name="onRtlPropertiesChanged(I)V" since="4" />
-    </class>
-    <class name="android/support/v4/widget/NestedScrollView" since="4">
-        <extends name="android/widget/FrameLayout" />
-        <method name="dispatchNestedFling(FFZ)Z" since="4" />
-        <method name="dispatchNestedPreFling(FF)Z" since="4" />
-        <method name="dispatchNestedPreScroll(II[I[I)Z" since="4" />
-        <method name="dispatchNestedScroll(IIII[I)Z" since="4" />
-        <method name="getNestedScrollAxes()I" since="4" />
-        <method name="hasNestedScrollingParent()Z" since="4" />
-        <method name="isNestedScrollingEnabled()Z" since="4" />
-        <method name="onGenericMotionEvent(Landroid/view/MotionEvent;)Z" since="4" />
-        <method name="onNestedFling(Landroid/view/View;FFZ)Z" since="4" />
-        <method name="onNestedPreFling(Landroid/view/View;FF)Z" since="4" />
-        <method name="onNestedPreScroll(Landroid/view/View;II[I)V" since="4" />
-        <method name="onNestedScroll(Landroid/view/View;IIII)V" since="4" />
-        <method name="onNestedScrollAccepted(Landroid/view/View;Landroid/view/View;I)V" since="4" />
-        <method name="onOverScrolled(IIZZ)V" since="4" />
-        <method name="onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z" since="4" />
-        <method name="onStopNestedScroll(Landroid/view/View;)V" since="4" />
-        <method name="setNestedScrollingEnabled(Z)V" since="4" />
-        <method name="shouldDelayChildPressedState()Z" since="4" />
-        <method name="startNestedScroll(I)Z" since="4" />
-        <method name="stopNestedScroll()V" since="4" />
-    </class>
-    <class name="android/support/v4/widget/SwipeRefreshLayout" since="4">
-        <extends name="android/view/ViewGroup" />
-        <method name="dispatchNestedFling(FFZ)Z" since="4" />
-        <method name="dispatchNestedPreFling(FF)Z" since="4" />
-        <method name="dispatchNestedPreScroll(II[I[I)Z" since="4" />
-        <method name="dispatchNestedScroll(IIII[I)Z" since="4" />
-        <method name="getNestedScrollAxes()I" since="4" />
-        <method name="hasNestedScrollingParent()Z" since="4" />
-        <method name="isNestedScrollingEnabled()Z" since="4" />
-        <method name="onNestedFling(Landroid/view/View;FFZ)Z" since="4" />
-        <method name="onNestedPreFling(Landroid/view/View;FF)Z" since="4" />
-        <method name="onNestedPreScroll(Landroid/view/View;II[I)V" since="4" />
-        <method name="onNestedScroll(Landroid/view/View;IIII)V" since="4" />
-        <method name="onNestedScrollAccepted(Landroid/view/View;Landroid/view/View;I)V" since="4" />
-        <method name="onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z" since="4" />
-        <method name="onStopNestedScroll(Landroid/view/View;)V" since="4" />
-        <method name="setNestedScrollingEnabled(Z)V" since="4" />
-        <method name="startNestedScroll(I)Z" since="4" />
-        <method name="stopNestedScroll()V" since="4" />
-    </class>
-    <class name="android/support/v7/app/AppCompatDialog" since="7">
-        <extends name="android/app/Dialog" />
-        <method name="invalidateOptionsMenu()V" since="7" />
-    </class>
-    <class name="android/support/v7/app/MediaRouteButton" since="7">
-        <extends name="android/view/View" />
-        <method name="jumpDrawablesToCurrentState()V" since="7" />
-    </class>
-    <class name="android/support/v7/graphics/drawable/DrawableWrapper" since="7">
-        <extends name="android/graphics/drawable/Drawable" />
-        <method name="isAutoMirrored()Z" since="7" />
-        <method name="jumpToCurrentState()V" since="7" />
-        <method name="setAutoMirrored(Z)V" since="7" />
-        <method name="setHotspot(FF)V" since="7" />
-        <method name="setHotspotBounds(IIII)V" since="7" />
-        <method name="setTint(I)V" since="7" />
-        <method name="setTintList(Landroid/content/res/ColorStateList;)V" since="7" />
-        <method name="setTintMode(Landroid/graphics/PorterDuff$Mode;)V" since="7" />
-    </class>
-    <class name="android/support/v7/internal/widget/PreferenceImageView" since="7">
-        <extends name="android/widget/ImageView" />
-        <method name="getMaxHeight()I" since="7" />
-        <method name="getMaxWidth()I" since="7" />
-    </class>
-    <class name="android/support/v7/view/SupportActionModeWrapper" since="7">
-        <extends name="android/view/ActionMode" />
-        <method name="finish()V" since="7" />
-        <method name="getCustomView()Landroid/view/View;" since="7" />
-        <method name="getMenu()Landroid/view/Menu;" since="7" />
-        <method name="getMenuInflater()Landroid/view/MenuInflater;" since="7" />
-        <method name="getSubtitle()Ljava/lang/CharSequence;" since="7" />
-        <method name="getTag()Ljava/lang/Object;" since="7" />
-        <method name="getTitle()Ljava/lang/CharSequence;" since="7" />
-        <method name="getTitleOptionalHint()Z" since="7" />
-        <method name="invalidate()V" since="7" />
-        <method name="isTitleOptional()Z" since="7" />
-        <method name="setCustomView(Landroid/view/View;)V" since="7" />
-        <method name="setSubtitle(I)V" since="7" />
-        <method name="setSubtitle(Ljava/lang/CharSequence;)V" since="7" />
-        <method name="setTag(Ljava/lang/Object;)V" since="7" />
-        <method name="setTitle(I)V" since="7" />
-        <method name="setTitle(Ljava/lang/CharSequence;)V" since="7" />
-        <method name="setTitleOptionalHint(Z)V" since="7" />
-    </class>
-    <class name="android/support/v7/view/menu/ActionMenuItemView" since="7">
-        <extends name="android/support/v7/widget/AppCompatTextView" />
-        <method name="onConfigurationChanged(Landroid/content/res/Configuration;)V" since="7" />
-    </class>
-    <class name="android/support/v7/view/menu/ListMenuItemView" since="7">
-        <extends name="android/widget/LinearLayout" />
-        <method name="&lt;init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/ActionBarContainer" since="7">
-        <extends name="android/widget/FrameLayout" />
-        <method name="jumpDrawablesToCurrentState()V" since="7" />
-        <method name="startActionModeForChild(Landroid/view/View;Landroid/view/ActionMode$Callback;)Landroid/view/ActionMode;" since="7" />
-    </class>
-    <class name="android/support/v7/widget/ActionBarContextView" since="7">
-        <extends name="android/support/v7/widget/AbsActionBarView" />
-        <method name="onHoverEvent(Landroid/view/MotionEvent;)Z" since="7" />
-        <method name="onInitializeAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V" since="7" />
-        <method name="shouldDelayChildPressedState()Z" since="7" />
-    </class>
-    <class name="android/support/v7/widget/ActionBarOverlayLayout" since="7">
-        <extends name="android/view/ViewGroup" />
-        <method name="getNestedScrollAxes()I" since="7" />
-        <method name="onConfigurationChanged(Landroid/content/res/Configuration;)V" since="7" />
-        <method name="onNestedFling(Landroid/view/View;FFZ)Z" since="7" />
-        <method name="onNestedPreFling(Landroid/view/View;FF)Z" since="7" />
-        <method name="onNestedPreScroll(Landroid/view/View;II[I)V" since="7" />
-        <method name="onNestedScroll(Landroid/view/View;IIII)V" since="7" />
-        <method name="onNestedScrollAccepted(Landroid/view/View;Landroid/view/View;I)V" since="7" />
-        <method name="onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z" since="7" />
-        <method name="onStopNestedScroll(Landroid/view/View;)V" since="7" />
-        <method name="onWindowSystemUiVisibilityChanged(I)V" since="7" />
-        <method name="shouldDelayChildPressedState()Z" since="7" />
-    </class>
-    <class name="android/support/v7/widget/ActionMenuView" since="7">
-        <extends name="android/support/v7/widget/LinearLayoutCompat" />
-        <method name="onConfigurationChanged(Landroid/content/res/Configuration;)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/AppCompatButton" since="7">
-        <extends name="android/widget/Button" />
-        <method name="onInitializeAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V" since="7" />
-        <method name="onInitializeAccessibilityNodeInfo(Landroid/view/accessibility/AccessibilityNodeInfo;)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/AppCompatPopupWindow" since="7">
-        <extends name="android/widget/PopupWindow" />
-        <method name="showAsDropDown(Landroid/view/View;III)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/AppCompatSpinner" since="7">
-        <extends name="android/widget/Spinner" />
-        <method name="&lt;init>(Landroid/content/Context;I)V" since="7" />
-        <method name="&lt;init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V" since="7" />
-        <method name="getDropDownHorizontalOffset()I" since="7" />
-        <method name="getDropDownVerticalOffset()I" since="7" />
-        <method name="getDropDownWidth()I" since="7" />
-        <method name="getPopupBackground()Landroid/graphics/drawable/Drawable;" since="7" />
-        <method name="getPopupContext()Landroid/content/Context;" since="7" />
-        <method name="setDropDownHorizontalOffset(I)V" since="7" />
-        <method name="setDropDownVerticalOffset(I)V" since="7" />
-        <method name="setDropDownWidth(I)V" since="7" />
-        <method name="setPopupBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V" since="7" />
-        <method name="setPopupBackgroundResource(I)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/CardView" since="7">
-        <extends name="android/widget/FrameLayout" />
-        <method name="setPaddingRelative(IIII)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/LinearLayoutCompat" since="7">
-        <extends name="android/view/ViewGroup" />
-        <method name="onInitializeAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V" since="7" />
-        <method name="onInitializeAccessibilityNodeInfo(Landroid/view/accessibility/AccessibilityNodeInfo;)V" since="7" />
-        <method name="shouldDelayChildPressedState()Z" since="7" />
-    </class>
-    <class name="android/support/v7/widget/RecyclerView" since="7">
-        <extends name="android/view/ViewGroup" />
-        <method name="dispatchNestedFling(FFZ)Z" since="7" />
-        <method name="dispatchNestedPreFling(FF)Z" since="7" />
-        <method name="dispatchNestedPreScroll(II[I[I)Z" since="7" />
-        <method name="dispatchNestedScroll(IIII[I)Z" since="7" />
-        <method name="hasNestedScrollingParent()Z" since="7" />
-        <method name="isAttachedToWindow()Z" since="7" />
-        <method name="isNestedScrollingEnabled()Z" since="7" />
-        <method name="onGenericMotionEvent(Landroid/view/MotionEvent;)Z" since="7" />
-        <method name="setNestedScrollingEnabled(Z)V" since="7" />
-        <method name="startNestedScroll(I)Z" since="7" />
-        <method name="stopNestedScroll()V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/ScrollingTabContainerView" since="7">
-        <extends name="android/widget/HorizontalScrollView" />
-        <method name="onConfigurationChanged(Landroid/content/res/Configuration;)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/SwitchCompat" since="7">
-        <extends name="android/widget/CompoundButton" />
-        <method name="drawableHotspotChanged(FF)V" since="7" />
-        <method name="jumpDrawablesToCurrentState()V" since="7" />
-        <method name="onInitializeAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V" since="7" />
-        <method name="onInitializeAccessibilityNodeInfo(Landroid/view/accessibility/AccessibilityNodeInfo;)V" since="7" />
-        <method name="onPopulateAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V" since="7" />
-    </class>
-    <class name="android/support/v7/widget/Toolbar" since="7">
-        <extends name="android/view/ViewGroup" />
-        <method name="onHoverEvent(Landroid/view/MotionEvent;)Z" since="7" />
-        <method name="onRtlPropertiesChanged(I)V" since="7" />
-    </class>
-    <!-- Referenced Super Classes -->
-    <class name="android/support/v7/widget/AbsActionBarView" since="7">
-        <extends name="android/view/ViewGroup" />
-    </class>
-    <class name="android/support/v7/widget/AppCompatTextView" since="7">
-        <extends name="android/widget/TextView" />
-    </class>
-</api>
\ No newline at end of file
diff --git a/plugins/lint/lint-idea/lint-idea.iml b/plugins/lint/lint-idea/lint-idea.iml
deleted file mode 100644
index 55aac4b..0000000
--- a/plugins/lint/lint-idea/lint-idea.iml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module" module-name="lint-api" />
-    <orderEntry type="module" module-name="lint-checks" />
-    <orderEntry type="library" name="kotlin-runtime" level="project" />
-    <orderEntry type="library" name="kotlin-reflect" level="project" />
-    <orderEntry type="library" name="idea-full" level="project" />
-    <orderEntry type="module" module-name="uast-kotlin" />
-    <orderEntry type="library" name="android-plugin" level="project" />
-    <orderEntry type="module" module-name="android-annotations" />
-    <orderEntry type="module" module-name="frontend" />
-    <orderEntry type="module" module-name="idea-analysis" />
-    <orderEntry type="module" module-name="idea-core" />
-    <orderEntry type="module" module-name="idea" />
-    <orderEntry type="module" module-name="idea-android" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidInspectionExtensionsFactory.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidInspectionExtensionsFactory.java
deleted file mode 100644
index f7da140..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidInspectionExtensionsFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.intellij.codeInspection.HTMLComposer;
-import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
-import com.intellij.codeInspection.lang.HTMLComposerExtension;
-import com.intellij.codeInspection.lang.InspectionExtensionsFactory;
-import com.intellij.codeInspection.lang.RefManagerExtension;
-import com.intellij.codeInspection.reference.RefManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class AndroidInspectionExtensionsFactory extends InspectionExtensionsFactory {
-  @Override
-  public GlobalInspectionContextExtension createGlobalInspectionContextExtension() {
-    return new AndroidLintGlobalInspectionContext();
-  }
-
-  @Nullable
-  @Override
-  public RefManagerExtension createRefManagerExtension(RefManager refManager) {
-    return null;
-  }
-
-  @Nullable
-  @Override
-  public HTMLComposerExtension createHTMLComposerExtension(HTMLComposer composer) {
-    return null;
-  }
-
-  @Override
-  public boolean isToCheckMember(@NotNull PsiElement element, @NotNull String id) {
-    return true;
-  }
-
-  @Override
-  public String getSuppressedInspectionIdsIn(@NotNull PsiElement element) {
-    return null;
-  }
-
-  @Override
-  public boolean isProjectConfiguredToRunInspections(@NotNull Project project, boolean online) {
-    return true;
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintExternalAnnotator.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintExternalAnnotator.java
deleted file mode 100644
index d00ebe5..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintExternalAnnotator.java
+++ /dev/null
@@ -1,414 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.client.api.IssueRegistry;
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.LintRequest;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Scope;
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.DaemonBundle;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInsight.intention.HighPriorityAction;
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.CustomEditInspectionToolsSettingsAction;
-import com.intellij.codeInspection.ex.DisableInspectionToolAction;
-import com.intellij.lang.annotation.Annotation;
-import com.intellij.lang.annotation.AnnotationHolder;
-import com.intellij.lang.annotation.ExternalAnnotator;
-import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.actionSystem.IdeActions;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.keymap.Keymap;
-import com.intellij.openapi.keymap.KeymapManager;
-import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.*;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.xml.util.XmlStringUtil;
-import org.jetbrains.android.compiler.AndroidCompileUtil;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.android.util.AndroidBundle;
-import org.jetbrains.android.util.AndroidCommonUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.idea.KotlinFileType;
-
-import javax.swing.*;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-
-import static com.android.SdkConstants.*;
-import static com.android.tools.klint.detector.api.TextFormat.HTML;
-import static com.android.tools.klint.detector.api.TextFormat.RAW;
-
-public class AndroidLintExternalAnnotator extends ExternalAnnotator<State, State> {
-  static final boolean INCLUDE_IDEA_SUPPRESS_ACTIONS = false;
-  static final boolean IS_UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode();
-
-  @Nullable
-  @Override
-  public State collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) {
-    return collectInformation(file);
-  }
-
-  @Override
-  public State collectInformation(@NotNull PsiFile file) {
-    final Module module = ModuleUtilCore.findModuleForPsiElement(file);
-    if (module == null) {
-      return null;
-    }
-
-    final AndroidFacet facet = AndroidFacet.getInstance(module);
-    if (facet == null && !IntellijLintProject.hasAndroidModule(module.getProject())) {
-      return null;
-    }
-
-    final VirtualFile vFile = file.getVirtualFile();
-    if (vFile == null) {
-      return null;
-    }
-
-    final FileType fileType = file.getFileType();
-
-    if (fileType == FileTypes.PLAIN_TEXT) {
-      if (!AndroidCommonUtils.PROGUARD_CFG_FILE_NAME.equals(file.getName()) &&
-          !AndroidCompileUtil.OLD_PROGUARD_CFG_FILE_NAME.equals(file.getName())) {
-        return null;
-      }
-    }
-    else if (fileType != KotlinFileType.INSTANCE && fileType != StdFileTypes.PROPERTIES) {
-      return null;
-    }
-
-    final List<Issue> issues = getIssuesFromInspections(file.getProject(), file);
-    if (issues.size() == 0) {
-      return null;
-    }
-    return new State(module, vFile, file.getText(), issues);
-  }
-
-  @Override
-  public State doAnnotate(final State state) {
-    final IntellijLintClient client = IntellijLintClient.forEditor(state);
-    try {
-      final LintDriver lint = new LintDriver(new IntellijLintIssueRegistry(), client);
-
-      EnumSet<Scope> scope;
-      VirtualFile mainFile = state.getMainFile();
-      final FileType fileType = mainFile.getFileType();
-      String name = mainFile.getName();
-      if (fileType == StdFileTypes.XML) {
-        if (name.equals(ANDROID_MANIFEST_XML)) {
-          scope = Scope.MANIFEST_SCOPE;
-        } else {
-          scope = Scope.RESOURCE_FILE_SCOPE;
-        }
-      } else if (fileType == KotlinFileType.INSTANCE) {
-        scope = Scope.JAVA_FILE_SCOPE;
-      } else if (name.equals(OLD_PROGUARD_FILE) || name.equals(FN_PROJECT_PROGUARD_FILE)) {
-        scope = EnumSet.of(Scope.PROGUARD_FILE);
-      } else if (fileType == StdFileTypes.PROPERTIES) {
-        scope = Scope.PROPERTY_SCOPE;
-      } else {
-        // #collectionInformation above should have prevented this
-        assert false;
-        return state;
-      }
-
-      Project project = state.getModule().getProject();
-      if (project.isDisposed()) {
-        return state;
-      }
-
-      List<VirtualFile> files = Collections.singletonList(mainFile);
-      final LintRequest request = new IntellijLintRequest(
-              client, project, files, Collections.singletonList(state.getModule()), true /* incremental */);
-      request.setScope(scope);
-
-      if (!IS_UNIT_TEST_MODE) {
-        ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(new Runnable() {
-          @Override
-          public void run() {
-            lint.analyze(request);
-          }
-        });
-      }
-      else {
-        lint.analyze(request);
-      }
-    }
-    finally {
-      Disposer.dispose(client);
-    }
-    return state;
-  }
-
-  @NotNull
-  static List<Issue> getIssuesFromInspections(@NotNull Project project, @Nullable PsiElement context) {
-    final List<Issue> result = new ArrayList<Issue>();
-    final IssueRegistry fullRegistry = new IntellijLintIssueRegistry();
-
-    for (Issue issue : fullRegistry.getIssues()) {
-      final String inspectionShortName = AndroidLintInspectionBase.getInspectionShortNameByIssue(project, issue);
-      if (inspectionShortName == null) {
-        continue;
-      }
-
-      final HighlightDisplayKey key = HighlightDisplayKey.find(inspectionShortName);
-      if (key == null) {
-        continue;
-      }
-
-      final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
-      final boolean enabled = context != null ? profile.isToolEnabled(key, context) : profile.isToolEnabled(key);
-
-      if (!enabled) {
-        continue;
-      } else if (!issue.isEnabledByDefault()) {
-        // If an issue is marked as not enabled by default, lint won't run it, even if it's in the set
-        // of issues provided by an issue registry. Since in the IDE we're enforcing the enabled-state via
-        // inspection profiles, mark the issue as enabled to allow users to turn on a lint check directly
-        // via the inspections UI.
-        issue.setEnabledByDefault(true);
-      }
-      result.add(issue);
-    }
-    return result;
-  }
-
-  @Override
-  public void apply(@NotNull PsiFile file, State state, @NotNull AnnotationHolder holder) {
-    if (state.isDirty()) {
-      return;
-    }
-    final Project project = file.getProject();
-
-    for (ProblemData problemData : state.getProblems()) {
-      final Issue issue = problemData.getIssue();
-      final String message = problemData.getMessage();
-      final TextRange range = problemData.getTextRange();
-
-      if (range.getStartOffset() == range.getEndOffset()) {
-        continue;
-      }
-
-      final Pair<AndroidLintInspectionBase, HighlightDisplayLevel> pair =
-        AndroidLintUtil.getHighlighLevelAndInspection(project, issue, file);
-      if (pair == null) {
-        continue;
-      }
-      final AndroidLintInspectionBase inspection = pair.getFirst();
-      HighlightDisplayLevel displayLevel = pair.getSecond();
-
-      if (inspection != null) {
-        final HighlightDisplayKey key = HighlightDisplayKey.find(inspection.getShortName());
-
-        if (key != null) {
-          final PsiElement startElement = file.findElementAt(range.getStartOffset());
-          final PsiElement endElement = file.findElementAt(range.getEndOffset() - 1);
-
-          if (startElement != null && endElement != null && !inspection.isSuppressedFor(startElement)) {
-            if (problemData.getConfiguredSeverity() != null) {
-              HighlightDisplayLevel configuredLevel =
-                AndroidLintInspectionBase.toHighlightDisplayLevel(problemData.getConfiguredSeverity());
-              if (configuredLevel != null) {
-                displayLevel = configuredLevel;
-              }
-            }
-            final Annotation annotation = createAnnotation(holder, message, range, displayLevel, issue);
-
-            for (AndroidLintQuickFix fix : inspection.getQuickFixes(startElement, endElement, message)) {
-              if (fix.isApplicable(startElement, endElement, AndroidQuickfixContexts.EditorContext.TYPE)) {
-                annotation.registerFix(new MyFixingIntention(fix, startElement, endElement));
-              }
-            }
-
-            for (IntentionAction intention : inspection.getIntentions(startElement, endElement)) {
-              annotation.registerFix(intention);
-            }
-
-            String id = key.getID();
-            if (IntellijLintIssueRegistry.CUSTOM_ERROR == issue
-                || IntellijLintIssueRegistry.CUSTOM_WARNING == issue) {
-              Issue original = IntellijLintClient.findCustomIssue(message);
-              if (original != null) {
-                id = original.getId();
-              }
-            }
-
-            annotation.registerFix(new SuppressLintIntentionAction(id, startElement));
-            annotation.registerFix(new MyDisableInspectionFix(key));
-            annotation.registerFix(new MyEditInspectionToolsSettingsAction(key, inspection));
-
-            if (INCLUDE_IDEA_SUPPRESS_ACTIONS) {
-              final SuppressQuickFix[] suppressActions = inspection.getBatchSuppressActions(startElement);
-              for (SuppressQuickFix action : suppressActions) {
-                if (action.isAvailable(project, startElement)) {
-                  ProblemHighlightType type = annotation.getHighlightType();
-                  annotation.registerFix(action, null, key, InspectionManager.getInstance(project).createProblemDescriptor(
-                    startElement, endElement, message, type, true, LocalQuickFix.EMPTY_ARRAY));
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  @SuppressWarnings("deprecation")
-  @NotNull
-  private Annotation createAnnotation(@NotNull AnnotationHolder holder,
-                                      @NotNull String message,
-                                      @NotNull TextRange range,
-                                      @NotNull HighlightDisplayLevel displayLevel,
-                                      @NotNull Issue issue) {
-    // Convert from inspection severity to annotation severity
-    HighlightSeverity severity;
-    if (displayLevel == HighlightDisplayLevel.ERROR) {
-      severity = HighlightSeverity.ERROR;
-    } else if (displayLevel == HighlightDisplayLevel.WARNING) {
-      severity = HighlightSeverity.WARNING;
-    } else if (displayLevel == HighlightDisplayLevel.WEAK_WARNING) {
-      severity = HighlightSeverity.WEAK_WARNING;
-    } else if (displayLevel == HighlightDisplayLevel.INFO) {
-      severity = HighlightSeverity.INFO;
-    } else {
-      severity = HighlightSeverity.WARNING;
-    }
-
-    String link = " <a "
-        +"href=\"#lint/" + issue.getId() + "\""
-        + (UIUtil.isUnderDarcula() ? " color=\"7AB4C9\" " : "")
-        +">" + DaemonBundle.message("inspection.extended.description")
-        +"</a> " + getShowMoreShortCut();
-    String tooltip = XmlStringUtil.wrapInHtml(RAW.convertTo(message, HTML) + link);
-
-    return holder.createAnnotation(severity, range, message, tooltip);
-  }
-
-  // Based on similar code in the LocalInspectionsPass constructor
-  private String myShortcutText;
-  private String getShowMoreShortCut() {
-    if (myShortcutText == null) {
-      final KeymapManager keymapManager = KeymapManager.getInstance();
-      if (keymapManager != null) {
-        final Keymap keymap = keymapManager.getActiveKeymap();
-        myShortcutText =
-          keymap == null ? "" : "(" + KeymapUtil.getShortcutsText(keymap.getShortcuts(IdeActions.ACTION_SHOW_ERROR_DESCRIPTION)) + ")";
-      }
-      else {
-        myShortcutText = "";
-      }
-    }
-
-    return myShortcutText;
-  }
-
-  private static class MyDisableInspectionFix implements IntentionAction, Iconable {
-    private final DisableInspectionToolAction myDisableInspectionToolAction;
-
-    private MyDisableInspectionFix(@NotNull HighlightDisplayKey key) {
-      myDisableInspectionToolAction = new DisableInspectionToolAction(key);
-    }
-
-    @NotNull
-    @Override
-    public String getText() {
-      return "Disable inspection";
-    }
-
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return getText();
-    }
-
-    @Override
-    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
-      return true;
-    }
-
-    @Override
-    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
-      myDisableInspectionToolAction.invoke(project, editor, file);
-    }
-
-    @Override
-    public boolean startInWriteAction() {
-      return myDisableInspectionToolAction.startInWriteAction();
-    }
-
-    @Override
-    public Icon getIcon(@IconFlags int flags) {
-      return myDisableInspectionToolAction.getIcon(flags);
-    }
-  }
-
-  public static class MyFixingIntention implements IntentionAction, HighPriorityAction {
-    private final AndroidLintQuickFix myQuickFix;
-    private final PsiElement myStartElement;
-    private final PsiElement myEndElement;
-
-    public MyFixingIntention(@NotNull AndroidLintQuickFix quickFix, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
-      myQuickFix = quickFix;
-      myStartElement = startElement;
-      myEndElement = endElement;
-    }
-
-    @NotNull
-    @Override
-    public String getText() {
-      return myQuickFix.getName();
-    }
-
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return AndroidBundle.message("android.lint.quickfixes.family");
-    }
-
-    @Override
-    public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
-      return true;
-    }
-
-    @Override
-    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
-      FileModificationService.getInstance().prepareFileForWrite(file);
-      myQuickFix.apply(myStartElement, myEndElement, AndroidQuickfixContexts.EditorContext.getInstance(editor));
-    }
-
-    @Override
-    public boolean startInWriteAction() {
-      return true;
-    }
-  }
-
-  private static class MyEditInspectionToolsSettingsAction extends CustomEditInspectionToolsSettingsAction {
-    private MyEditInspectionToolsSettingsAction(@NotNull HighlightDisplayKey key, @NotNull final AndroidLintInspectionBase inspection) {
-      super(key, new Computable<String>() {
-        @Override
-        public String compute() {
-          return "Edit '" + inspection.getDisplayName() + "' inspection settings";
-        }
-      });
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintGlobalInspectionContext.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintGlobalInspectionContext.java
deleted file mode 100644
index 93e5243..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintGlobalInspectionContext.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.client.api.LintDriver;
-import com.android.tools.klint.client.api.LintRequest;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Scope;
-import com.google.common.collect.Lists;
-import com.intellij.analysis.AnalysisScope;
-import com.intellij.codeInspection.GlobalInspectionContext;
-import com.intellij.codeInspection.ex.InspectionToolWrapper;
-import com.intellij.codeInspection.ex.Tools;
-import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
-import com.intellij.facet.ProjectFacetManager;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.util.ProgressWrapper;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.SearchScope;
-import com.intellij.util.containers.HashMap;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.util.*;
-
-class AndroidLintGlobalInspectionContext implements GlobalInspectionContextExtension<AndroidLintGlobalInspectionContext> {
-  static final Key<AndroidLintGlobalInspectionContext> ID = Key.create("AndroidLintGlobalInspectionContext");
-  private Map<Issue, Map<File, List<ProblemData>>> myResults;
-
-  @NotNull
-  @Override
-  public Key<AndroidLintGlobalInspectionContext> getID() {
-    return ID;
-  }
-
-  @Override
-  public void performPreRunActivities(@NotNull List<Tools> globalTools, @NotNull List<Tools> localTools, @NotNull final GlobalInspectionContext context) {
-    final Project project = context.getProject();
-
-    if (!ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)) {
-      return;
-    }
-
-    final List<Issue> issues = AndroidLintExternalAnnotator.getIssuesFromInspections(project, null);
-    if (issues.size() == 0) {
-      return;
-    }
-
-    final Map<Issue, Map<File, List<ProblemData>>> problemMap = new HashMap<Issue, Map<File, List<ProblemData>>>();
-    final AnalysisScope scope = context.getRefManager().getScope();
-    if (scope == null) {
-      return;
-    }
-
-    final IntellijLintClient client = IntellijLintClient.forBatch(project, problemMap, scope, issues);
-    final LintDriver lint = new LintDriver(new IntellijLintIssueRegistry(), client);
-
-    final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
-    if (indicator != null) {
-      ProgressWrapper.unwrap(indicator).setText("Running Android Lint");
-    }
-
-    EnumSet<Scope> lintScope;
-    //noinspection ConstantConditions
-    if (!IntellijLintProject.SUPPORT_CLASS_FILES) {
-      lintScope = EnumSet.copyOf(Scope.ALL);
-      // Can't run class file based checks
-      lintScope.remove(Scope.CLASS_FILE);
-      lintScope.remove(Scope.ALL_CLASS_FILES);
-      lintScope.remove(Scope.JAVA_LIBRARIES);
-    } else {
-      lintScope = Scope.ALL;
-    }
-
-    List<VirtualFile> files = null;
-    final List<Module> modules = Lists.newArrayList();
-
-    int scopeType = scope.getScopeType();
-    switch (scopeType) {
-      case AnalysisScope.MODULE: {
-        SearchScope searchScope = scope.toSearchScope();
-        if (searchScope instanceof ModuleWithDependenciesScope) {
-          ModuleWithDependenciesScope s = (ModuleWithDependenciesScope)searchScope;
-          if (!s.isSearchInLibraries()) {
-            modules.add(s.getModule());
-          }
-        }
-        break;
-      }
-      case AnalysisScope.FILE:
-      case AnalysisScope.VIRTUAL_FILES:
-      case AnalysisScope.UNCOMMITTED_FILES: {
-        files = Lists.newArrayList();
-        SearchScope searchScope = scope.toSearchScope();
-        if (searchScope instanceof LocalSearchScope) {
-          final LocalSearchScope localSearchScope = (LocalSearchScope)searchScope;
-          final PsiElement[] elements = localSearchScope.getScope();
-          final List<VirtualFile> finalFiles = files;
-
-          ApplicationManager.getApplication().runReadAction(new Runnable() {
-            @Override
-            public void run() {
-              for (PsiElement element : elements) {
-                if (element instanceof PsiFile) { // should be the case since scope type is FILE
-                  Module module = ModuleUtilCore.findModuleForPsiElement(element);
-                  if (module != null && !modules.contains(module)) {
-                    modules.add(module);
-                  }
-                  VirtualFile virtualFile = ((PsiFile)element).getVirtualFile();
-                  if (virtualFile != null) {
-                    finalFiles.add(virtualFile);
-                  }
-                }
-              }
-            }
-          });
-        } else {
-          final List<VirtualFile> finalList = files;
-          scope.accept(new PsiElementVisitor() {
-            @Override
-            public void visitFile(PsiFile file) {
-              VirtualFile virtualFile = file.getVirtualFile();
-              if (virtualFile != null) {
-                finalList.add(virtualFile);
-              }
-            }
-          });
-        }
-        if (files.isEmpty()) {
-          files = null;
-        } else {
-          // Lint will compute it lazily based on actual files in the request
-          lintScope = null;
-        }
-        break;
-      }
-      case AnalysisScope.PROJECT: {
-        modules.addAll(Arrays.asList(ModuleManager.getInstance(project).getModules()));
-        break;
-      }
-      case AnalysisScope.CUSTOM:
-      case AnalysisScope.MODULES:
-      case AnalysisScope.DIRECTORY: {
-        // Handled by the getNarrowedComplementaryScope case below
-        break;
-      }
-
-      case AnalysisScope.INVALID:
-        break;
-      default:
-        Logger.getInstance(this.getClass()).warn("Unexpected inspection scope " + scope + ", " + scopeType);
-    }
-
-    if (modules.isEmpty()) {
-      for (Module module : ModuleManager.getInstance(project).getModules()) {
-        if (scope.containsModule(module)) {
-          modules.add(module);
-        }
-      }
-
-      if (modules.isEmpty() && files != null) {
-        for (VirtualFile file : files) {
-          Module module = ModuleUtilCore.findModuleForFile(file, project);
-          if (module != null && !modules.contains(module)) {
-            modules.add(module);
-          }
-        }
-      }
-
-      if (modules.isEmpty()) {
-        AnalysisScope narrowed = scope.getNarrowedComplementaryScope(project);
-        for (Module module : ModuleManager.getInstance(project).getModules()) {
-          if (narrowed.containsModule(module)) {
-            modules.add(module);
-          }
-        }
-      }
-    }
-
-    LintRequest request = new IntellijLintRequest(client, project, files, modules, false);
-    request.setScope(lintScope);
-
-    lint.analyze(request);
-
-    myResults = problemMap;
-  }
-
-  @Nullable
-  public Map<Issue, Map<File, List<ProblemData>>> getResults() {
-    return myResults;
-  }
-
-  @Override
-  public void performPostRunActivities(@NotNull List<InspectionToolWrapper> inspections, @NotNull final GlobalInspectionContext context) {
-  }
-
-  @Override
-  public void cleanup() {
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java
deleted file mode 100644
index 8a7424a..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.concurrency.GuardedBy;
-import com.android.tools.klint.detector.api.*;
-import com.intellij.analysis.AnalysisScope;
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.InspectionToolWrapper;
-import com.intellij.lang.annotation.ProblemGroup;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.containers.HashMap;
-import org.jetbrains.android.util.AndroidBundle;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
-
-import java.io.File;
-import java.util.*;
-
-import static com.android.tools.klint.detector.api.TextFormat.*;
-import static com.intellij.xml.CommonXmlStrings.HTML_END;
-import static com.intellij.xml.CommonXmlStrings.HTML_START;
-
-public abstract class AndroidLintInspectionBase extends GlobalInspectionTool {
-  private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.inspections.lint.AndroidLintInspectionBase");
-
-  private static final Object ISSUE_MAP_LOCK = new Object();
-
-  @GuardedBy("ISSUE_MAP_LOCK")
-  private static volatile Map<Issue, String> ourIssue2InspectionShortName;
-
-  protected final Issue myIssue;
-  private final String[] myGroupPath;
-  private final String myDisplayName;
-
-  protected AndroidLintInspectionBase(@NotNull String displayName, @NotNull Issue issue) {
-    myIssue = issue;
-
-    final Category category = issue.getCategory();
-
-    myGroupPath = ArrayUtil.mergeArrays(new String[]{AndroidBundle.message("android.inspections.group.name"),
-      AndroidBundle.message("android.lint.inspections.subgroup.name")}, computeAllNames(category));
-    myDisplayName = displayName;
-  }
-
-  @NotNull
-  public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
-    return getQuickFixes(message);
-  }
-
-  @NotNull
-  public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
-    return AndroidLintQuickFix.EMPTY_ARRAY;
-  }
-
-  @NotNull
-  public IntentionAction[] getIntentions(@NotNull PsiElement startElement, @NotNull PsiElement endElement) {
-    return IntentionAction.EMPTY_ARRAY;
-  }
-
-  @Override
-  public boolean isGraphNeeded() {
-    return false;
-  }
-
-  @NotNull
-  private LocalQuickFix[] getLocalQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
-    final AndroidLintQuickFix[] fixes = getQuickFixes(startElement, endElement, message);
-    final LocalQuickFix[] result = new LocalQuickFix[fixes.length];
-
-    for (int i = 0; i < fixes.length; i++) {
-      if (fixes[i].isApplicable(startElement, endElement, AndroidQuickfixContexts.BatchContext.TYPE)) {
-        result[i] = new MyLocalQuickFix(fixes[i]);
-      }
-    }
-    return result;
-  }
-
-  @Override
-  public void runInspection(@NotNull AnalysisScope scope,
-                            @NotNull final InspectionManager manager,
-                            @NotNull final GlobalInspectionContext globalContext,
-                            @NotNull final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
-    final AndroidLintGlobalInspectionContext androidLintContext = globalContext.getExtension(AndroidLintGlobalInspectionContext.ID);
-    if (androidLintContext == null) {
-      return;
-    }
-
-    final Map<Issue, Map<File, List<ProblemData>>> problemMap = androidLintContext.getResults();
-    if (problemMap == null) {
-      return;
-    }
-
-    final Map<File, List<ProblemData>> file2ProblemList = problemMap.get(myIssue);
-    if (file2ProblemList == null) {
-      return;
-    }
-
-    for (final Map.Entry<File, List<ProblemData>> entry : file2ProblemList.entrySet()) {
-      final File file = entry.getKey();
-      final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-
-      if (vFile == null) {
-        continue;
-      }
-      ApplicationManager.getApplication().runReadAction(new Runnable() {
-        @Override
-        public void run() {
-          final PsiManager psiManager = PsiManager.getInstance(globalContext.getProject());
-          final PsiFile psiFile = psiManager.findFile(vFile);
-
-          if (psiFile != null) {
-            final ProblemDescriptor[] descriptors = computeProblemDescriptors(psiFile, manager, entry.getValue());
-
-            if (descriptors.length > 0) {
-              problemDescriptionsProcessor.addProblemElement(globalContext.getRefManager().getReference(psiFile), descriptors);
-            }
-          } else if (vFile.isDirectory()) {
-            final PsiDirectory psiDirectory = psiManager.findDirectory(vFile);
-
-            if (psiDirectory != null) {
-              final ProblemDescriptor[] descriptors = computeProblemDescriptors(psiDirectory, manager, entry.getValue());
-
-              if (descriptors.length > 0) {
-                problemDescriptionsProcessor.addProblemElement(globalContext.getRefManager().getReference(psiDirectory), descriptors);
-              }
-            }
-          }
-        }
-      });
-    }
-  }
-
-  @NotNull
-  private ProblemDescriptor[] computeProblemDescriptors(@NotNull PsiElement psiFile,
-                                                        @NotNull InspectionManager manager,
-                                                        @NotNull List<ProblemData> problems) {
-    final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>();
-
-    for (ProblemData problemData : problems) {
-      final String originalMessage = problemData.getMessage();
-
-      // We need to have explicit <html> and </html> tags around the text; inspection infrastructure
-      // such as the {@link com.intellij.codeInspection.ex.DescriptorComposer} will call
-      // {@link com.intellij.xml.util.XmlStringUtil.isWrappedInHtml}. See issue 177283 for uses.
-      // Note that we also need to use HTML with unicode characters here, since the HTML display
-      // in the inspections view does not appear to support numeric code character entities.
-      String formattedMessage = HTML_START + RAW.convertTo(originalMessage, HTML_WITH_UNICODE) + HTML_END;
-
-      // The inspections UI does not correctly handle
-
-      final TextRange range = problemData.getTextRange();
-
-      if (range.getStartOffset() == range.getEndOffset()) {
-
-        if (psiFile instanceof PsiBinaryFile || psiFile instanceof PsiDirectory) {
-          final LocalQuickFix[] fixes = getLocalQuickFixes(psiFile, psiFile, originalMessage);
-          result.add(new NonTextFileProblemDescriptor((PsiFileSystemItem)psiFile, formattedMessage, fixes));
-        } else if (!isSuppressedFor(psiFile)) {
-          result.add(manager.createProblemDescriptor(psiFile, formattedMessage, false,
-                                                     getLocalQuickFixes(psiFile, psiFile, originalMessage),
-                                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
-        }
-      }
-      else {
-        final PsiElement startElement = psiFile.findElementAt(range.getStartOffset());
-        final PsiElement endElement = psiFile.findElementAt(range.getEndOffset() - 1);
-
-        if (startElement != null && endElement != null && !isSuppressedFor(startElement)) {
-          result.add(manager.createProblemDescriptor(startElement, endElement, formattedMessage,
-                                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false,
-                                                     getLocalQuickFixes(startElement, endElement, originalMessage)));
-        }
-      }
-    }
-    return result.toArray(new ProblemDescriptor[result.size()]);
-  }
-
-  @NotNull
-  @Override
-  public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
-    if (AndroidLintExternalAnnotator.INCLUDE_IDEA_SUPPRESS_ACTIONS) {
-      final List<SuppressQuickFix> result = new ArrayList<SuppressQuickFix>();
-      result.addAll(Arrays.asList(BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()))));
-      result.addAll(Arrays.asList(new XmlSuppressableInspectionTool.SuppressTagStatic(getShortName()),
-                                  new XmlSuppressableInspectionTool.SuppressForFile(getShortName())));
-      return result.toArray(new SuppressQuickFix[result.size()]);
-    } else {
-      return new SuppressQuickFix[0];
-    }
-  }
-
-  @TestOnly
-  public static void invalidateInspectionShortName2IssueMap() {
-    ourIssue2InspectionShortName = null;
-  }
-
-  public static String getInspectionShortNameByIssue(@NotNull Project project, @NotNull Issue issue) {
-    synchronized (ISSUE_MAP_LOCK) {
-      if (ourIssue2InspectionShortName == null) {
-        ourIssue2InspectionShortName = new HashMap<Issue, String>();
-
-        final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
-
-        for (InspectionToolWrapper e : profile.getInspectionTools(null)) {
-          final String shortName = e.getShortName();
-
-          if (shortName.startsWith("AndroidKLint")) {
-            final InspectionProfileEntry entry = e.getTool();
-            if (entry instanceof AndroidLintInspectionBase) {
-              final Issue s = ((AndroidLintInspectionBase)entry).getIssue();
-              ourIssue2InspectionShortName.put(s, shortName);
-            }
-          }
-        }
-      }
-      return ourIssue2InspectionShortName.get(issue);
-    }
-  }
-
-  @NotNull
-  private static String[] computeAllNames(@NotNull Category category) {
-    final List<String> result = new ArrayList<String>();
-
-    Category c = category;
-
-    while (c != null) {
-      final String name = c.getName();
-
-      if (name == null) {
-        return ArrayUtil.EMPTY_STRING_ARRAY;
-      }
-      result.add(name);
-      c = c.getParent();
-    }
-    return ArrayUtil.reverseArray(ArrayUtil.toStringArray(result));
-  }
-
-  @Nls
-  @NotNull
-  @Override
-  public String getGroupDisplayName() {
-    return AndroidBundle.message("android.lint.inspections.group.name");
-  }
-
-  @NotNull
-  @Override
-  public String[] getGroupPath() {
-    return myGroupPath;
-  }
-
-  @Nls
-  @NotNull
-  @Override
-  public String getDisplayName() {
-    return myDisplayName;
-  }
-
-  @SuppressWarnings("deprecation")
-  @Override
-  public String getStaticDescription() {
-    StringBuilder sb = new StringBuilder(1000);
-    sb.append("<html><body>");
-    sb.append(myIssue.getBriefDescription(HTML));
-    sb.append("<br><br>");
-    sb.append(myIssue.getExplanation(HTML));
-    List<String> urls = myIssue.getMoreInfo();
-    if (!urls.isEmpty()) {
-      boolean separated = false;
-      for (String url : urls) {
-        if (!myIssue.getExplanation(RAW).contains(url)) {
-          if (!separated) {
-            sb.append("<br><br>");
-            separated = true;
-          } else {
-            sb.append("<br>");
-          }
-          sb.append("<a href=\"");
-          sb.append(url);
-          sb.append("\">");
-          sb.append(url);
-          sb.append("</a>");
-        }
-      }
-    }
-    sb.append("</body></html>");
-
-    return sb.toString();
-  }
-
-  @Override
-  public boolean isEnabledByDefault() {
-    return myIssue.isEnabledByDefault();
-  }
-
-  @NotNull
-  @Override
-  public String getShortName() {
-    return InspectionProfileEntry.getShortName(getClass().getSimpleName());
-  }
-
-  @NotNull
-  @Override
-  public HighlightDisplayLevel getDefaultLevel() {
-    final Severity defaultSeverity = myIssue.getDefaultSeverity();
-    if (defaultSeverity == null) {
-      return HighlightDisplayLevel.WARNING;
-    }
-    final HighlightDisplayLevel displayLevel = toHighlightDisplayLevel(defaultSeverity);
-    return displayLevel != null ? displayLevel : HighlightDisplayLevel.WARNING;
-  }
-
-  @Nullable
-  static HighlightDisplayLevel toHighlightDisplayLevel(@NotNull Severity severity) {
-    switch (severity) {
-      case ERROR:
-        return HighlightDisplayLevel.ERROR;
-      case FATAL:
-        return HighlightDisplayLevel.ERROR;
-      case WARNING:
-        return HighlightDisplayLevel.WARNING;
-      case INFORMATIONAL:
-        return HighlightDisplayLevel.WEAK_WARNING;
-      case IGNORE:
-        return null;
-      default:
-        LOG.error("Unknown severity " + severity);
-        return null;
-    }
-  }
-
-  /** Returns true if the given analysis scope is adequate for single-file analysis */
-  private static boolean isSingleFileScope(EnumSet<Scope> scopes) {
-    if (scopes.size() != 1) {
-      return false;
-    }
-    final Scope scope = scopes.iterator().next();
-    return scope == Scope.JAVA_FILE || scope == Scope.RESOURCE_FILE || scope == Scope.MANIFEST
-           || scope == Scope.PROGUARD_FILE || scope == Scope.OTHER;
-  }
-
-  @Override
-  public boolean worksInBatchModeOnly() {
-    Implementation implementation = myIssue.getImplementation();
-    if (isSingleFileScope(implementation.getScope())) {
-      return false;
-    }
-    for (EnumSet<Scope> scopes : implementation.getAnalysisScopes()) {
-      if (isSingleFileScope(scopes)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @NotNull
-  public Issue getIssue() {
-    return myIssue;
-  }
-
-  static class MyLocalQuickFix implements LocalQuickFix {
-    private final AndroidLintQuickFix myLintQuickFix;
-
-    MyLocalQuickFix(@NotNull AndroidLintQuickFix lintQuickFix) {
-      myLintQuickFix = lintQuickFix;
-    }
-
-    @NotNull
-    @Override
-    public String getName() {
-      return myLintQuickFix.getName();
-    }
-
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return AndroidBundle.message("android.lint.quickfixes.family");
-    }
-
-    @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      myLintQuickFix.apply(descriptor.getStartElement(), descriptor.getEndElement(), AndroidQuickfixContexts.BatchContext.getInstance());
-    }
-  }
-
-  /**
-   * A {@link com.intellij.codeInspection.ProblemDescriptor} for image and directory files. This is
-   * necessary because the {@link InspectionManager}'s createProblemDescriptor methods
-   * all use {@link com.intellij.codeInspection.ProblemDescriptorBase} where in the constructor
-   * it insists that the start and end {@link PsiElement} instances must have a valid
-   * <b>text</b> range, which does not apply for images.
-   * <p>
-   * This custom descriptor allows the batch lint analysis to correctly handle lint errors
-   * associated with image files (such as the various {@link com.android.tools.lint.checks.IconDetector}
-   * warnings), as well as directory errors (such as incorrect locale folders),
-   * and clicking on them will navigate to the correct icon.
-   */
-  private static class NonTextFileProblemDescriptor implements ProblemDescriptor {
-    private final PsiFileSystemItem myFile;
-    private final String myMessage;
-    private final LocalQuickFix[] myFixes;
-    private ProblemGroup myGroup;
-
-    public NonTextFileProblemDescriptor(@NotNull PsiFileSystemItem file, @NotNull String message, @NotNull LocalQuickFix[] fixes) {
-      myFile = file;
-      myMessage = message;
-      myFixes = fixes;
-    }
-
-    @Override
-    public PsiElement getPsiElement() {
-      return myFile;
-    }
-
-    @Override
-    public PsiElement getStartElement() {
-      return myFile;
-    }
-
-    @Override
-    public PsiElement getEndElement() {
-      return myFile;
-    }
-
-    @Override
-    public TextRange getTextRangeInElement() {
-      return new TextRange(0, 0);
-    }
-
-    @Override
-    public int getLineNumber() {
-      return 0;
-    }
-
-    @NotNull
-    @Override
-    public ProblemHighlightType getHighlightType() {
-      return ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
-    }
-
-    @Override
-    public boolean isAfterEndOfLine() {
-      return false;
-    }
-
-    @Override
-    public void setTextAttributes(TextAttributesKey key) {
-    }
-
-    @Nullable
-    @Override
-    public ProblemGroup getProblemGroup() {
-      return myGroup;
-    }
-
-    @Override
-    public void setProblemGroup(@Nullable ProblemGroup problemGroup) {
-      myGroup = problemGroup;
-    }
-
-    @Override
-    public boolean showTooltip() {
-      return false;
-    }
-
-    @NotNull
-    @Override
-    public String getDescriptionTemplate() {
-      return myMessage;
-    }
-
-    @Nullable
-    @Override
-    public QuickFix[] getFixes() {
-      return myFixes;
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionToolProvider.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionToolProvider.java
deleted file mode 100644
index a74bd02..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionToolProvider.java
+++ /dev/null
@@ -1,757 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.checks.*;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.lint.detector.api.TextFormat;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.search.GlobalSearchScope;
-import org.jetbrains.android.util.AndroidBundle;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.regex.Pattern;
-
-import static com.android.tools.klint.checks.ApiDetector.REQUIRES_API_ANNOTATION;
-import static com.android.tools.klint.checks.FragmentDetector.ISSUE;
-
-/**
- * Registrations for all the various Lint rules as local IDE inspections, along with quickfixes for many of them
- */
-public class AndroidLintInspectionToolProvider {
-  public static class AndroidKLintCustomErrorInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCustomErrorInspection() {
-      super("Error from Custom Lint Check", IntellijLintIssueRegistry.CUSTOM_ERROR);
-    }
-  }
-
-  public static class AndroidKLintCustomWarningInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCustomWarningInspection() {
-      super("Warning from Custom Lint Check", IntellijLintIssueRegistry.CUSTOM_WARNING);
-    }
-
-  }
-
-  public static class AndroidKLintInconsistentLayoutInspection extends AndroidLintInspectionBase {
-    public AndroidKLintInconsistentLayoutInspection() {
-      super(AndroidBundle.message("android.lint.inspections.inconsistent.layout"), LayoutConsistencyDetector.INCONSISTENT_IDS);
-    }
-  }
-
-  public static class AndroidKLintIconExpectedSizeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconExpectedSizeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.expected.size"), IconDetector.ICON_EXPECTED_SIZE);
-    }
-  }
-
-  public static class AndroidKLintIconDipSizeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconDipSizeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.dip.size"), IconDetector.ICON_DIP_SIZE);
-    }
-  }
-
-  public static class AndroidKLintIconLocationInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconLocationInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.location"), IconDetector.ICON_LOCATION);
-    }
-  }
-
-  public static class AndroidKLintIconDensitiesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconDensitiesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.densities"), IconDetector.ICON_DENSITIES);
-    }
-  }
-
-  public static class AndroidKLintIconMissingDensityFolderInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconMissingDensityFolderInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.missing.density.folder"), IconDetector.ICON_MISSING_FOLDER);
-    }
-  }
-
-  public static class AndroidKLintIconMixedNinePatchInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconMixedNinePatchInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.mixed.nine.patch"), IconDetector.ICON_MIX_9PNG);
-    }
-  }
-
-  public static class AndroidKLintFloatMathInspection extends AndroidLintInspectionBase {
-    public AndroidKLintFloatMathInspection() {
-      super("Using FloatMath instead of Math", MathDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintGetInstanceInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGetInstanceInspection() {
-      super(AndroidBundle.message("android.lint.inspections.get.instance"), CipherGetInstanceDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintGifUsageInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGifUsageInspection() {
-      super(AndroidBundle.message("android.lint.inspections.gif.usage"), IconDetector.GIF_USAGE);
-    }
-  }
-
-  public static class AndroidKLintIconDuplicatesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconDuplicatesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.duplicates"), IconDetector.DUPLICATES_NAMES);
-    }
-  }
-
-  public static class AndroidKLintIconDuplicatesConfigInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconDuplicatesConfigInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.duplicates.config"), IconDetector.DUPLICATES_CONFIGURATIONS);
-    }
-  }
-
-  public static class AndroidKLintIconNoDpiInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconNoDpiInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.no.dpi"), IconDetector.ICON_NODPI);
-    }
-  }
-
-  public static class AndroidKLintOverdrawInspection extends AndroidLintInspectionBase {
-    public AndroidKLintOverdrawInspection() {
-      super(AndroidBundle.message("android.lint.inspections.overdraw"), OverdrawDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintMissingSuperCallInspection extends AndroidLintInspectionBase {
-    public AndroidKLintMissingSuperCallInspection() {
-      super(AndroidBundle.message("android.lint.inspections.missing.super.call"), CallSuperDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintUnprotectedSMSBroadcastReceiverInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnprotectedSMSBroadcastReceiverInspection() {
-      super(AndroidBundle.message("android.lint.inspections.unprotected.smsbroadcast.receiver"), UnsafeBroadcastReceiverDetector.BROADCAST_SMS);
-    }
-
-  }
-
-  public static class AndroidKLintUnusedAttributeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnusedAttributeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.unused.attribute"), ApiDetector.UNUSED);
-    }
-
-  }
-
-  public static class AndroidKLintAlwaysShowActionInspection extends AndroidLintInspectionBase {
-    public AndroidKLintAlwaysShowActionInspection() {
-      super(AndroidBundle.message("android.lint.inspections.always.show.action"), AlwaysShowActionDetector.ISSUE);
-    }
-
-  }
-
-  public static class AndroidKLintAppCompatMethodInspection extends AndroidLintInspectionBase {
-    public AndroidKLintAppCompatMethodInspection() {
-      super(AndroidBundle.message("android.lint.inspections.app.compat.method"), AppCompatCallDetector.ISSUE);
-    }
-
-  }
-  
-  public static class AndroidKLintGoogleAppIndexingUrlErrorInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGoogleAppIndexingUrlErrorInspection() {
-      super("URL not supported by app for Google App Indexing", AppIndexingApiDetector.ISSUE_URL_ERROR);
-    }
-
-  }
-
-  public static class AndroidKLintGoogleAppIndexingWarningInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGoogleAppIndexingWarningInspection() {
-      super("Missing support for Google App Indexing", AppIndexingApiDetector.ISSUE_APP_INDEXING);
-    }
-
-  }
-
-  public static class AndroidKLintGoogleAppIndexingApiWarningInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGoogleAppIndexingApiWarningInspection() {
-      super("Missing support for Google App Indexing Api", AppIndexingApiDetector.ISSUE_APP_INDEXING_API);
-    }
-
-  }
-
-  public static class AndroidKLintStringFormatCountInspection extends AndroidLintInspectionBase {
-    public AndroidKLintStringFormatCountInspection() {
-      super(AndroidBundle.message("android.lint.inspections.string.format.count"), StringFormatDetector.ARG_COUNT);
-    }
-  }
-
-  public static class AndroidKLintStringFormatMatchesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintStringFormatMatchesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.string.format.matches"), StringFormatDetector.ARG_TYPES);
-    }
-  }
-
-  public static class AndroidKLintStringFormatInvalidInspection extends AndroidLintInspectionBase {
-    public AndroidKLintStringFormatInvalidInspection() {
-      super(AndroidBundle.message("android.lint.inspections.string.format.invalid"), StringFormatDetector.INVALID);
-    }
-  }
-  
-  public static class AndroidKLintWrongViewCastInspection extends AndroidLintInspectionBase {
-    public AndroidKLintWrongViewCastInspection() {
-      super(AndroidBundle.message("android.lint.inspections.wrong.view.cast"), ViewTypeDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintCommitTransactionInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCommitTransactionInspection() {
-      super(AndroidBundle.message("android.lint.inspections.commit.transaction"), CleanupDetector.COMMIT_FRAGMENT);
-    }
-  }
-  
-  public static class AndroidKLintBadHostnameVerifierInspection extends AndroidLintInspectionBase {
-    public AndroidKLintBadHostnameVerifierInspection() {
-      super("Insecure HostnameVerifier", BadHostnameVerifierDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintBatteryLifeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintBatteryLifeInspection() {
-      super("Battery Life Issues", BatteryDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintHandlerLeakInspection extends AndroidLintInspectionBase {
-    public AndroidKLintHandlerLeakInspection() {
-      super(AndroidBundle.message("android.lint.inspections.handler.leak"), HandlerDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintDrawAllocationInspection extends AndroidLintInspectionBase {
-    public AndroidKLintDrawAllocationInspection() {
-      super(AndroidBundle.message("android.lint.inspections.draw.allocation"), JavaPerformanceDetector.PAINT_ALLOC);
-    }
-  }
-
-  public static class AndroidKLintUseSparseArraysInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUseSparseArraysInspection() {
-      super(AndroidBundle.message("android.lint.inspections.use.sparse.arrays"), JavaPerformanceDetector.USE_SPARSE_ARRAY);
-    }
-  }
-
-  public static class AndroidKLintUseValueOfInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUseValueOfInspection() {
-      super(AndroidBundle.message("android.lint.inspections.use.value.of"), JavaPerformanceDetector.USE_VALUE_OF);
-    }
-
-  }
-
-  public static class AndroidKLintPackageManagerGetSignaturesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintPackageManagerGetSignaturesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.package.manager.get.signatures"), GetSignaturesDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintParcelClassLoaderInspection extends AndroidLintInspectionBase {
-    public AndroidKLintParcelClassLoaderInspection() {
-      super("Default Parcel Class Loader", ReadParcelableDetector.ISSUE);
-    }
-
-  }
-
-  public static class AndroidKLintParcelCreatorInspection extends AndroidLintInspectionBase {
-    public AndroidKLintParcelCreatorInspection() {
-      super(AndroidBundle.message("android.lint.inspections.parcel.creator"), ParcelDetector.ISSUE);
-    }
-    @NotNull
-    @Override
-    public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
-        return new AndroidLintQuickFix[]{ new ParcelableQuickFix() };
-    }
-  }
-
-  public static class AndroidKLintPluralsCandidateInspection extends AndroidLintInspectionBase {
-    public AndroidKLintPluralsCandidateInspection() {
-      super(AndroidBundle.message("android.lint.inspections.plurals.candidate"), StringFormatDetector.POTENTIAL_PLURAL);
-    }
-  }
-
-  public static class AndroidKLintPrivateResourceInspection extends AndroidLintInspectionBase {
-    public AndroidKLintPrivateResourceInspection() {
-      super(AndroidBundle.message("android.lint.inspections.private.resource"), PrivateResourceDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintSdCardPathInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSdCardPathInspection() {
-      super(AndroidBundle.message("android.lint.inspections.sd.card.path"), SdCardDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintSuspiciousImportInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSuspiciousImportInspection() {
-      super(AndroidBundle.message("android.lint.inspections.suspicious.import"), WrongImportDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintSQLiteStringInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSQLiteStringInspection() {
-      super(AndroidBundle.message("android.lint.inspections.sqlite.string"), SQLiteDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintDefaultLocaleInspection extends AndroidLintInspectionBase {
-    public AndroidKLintDefaultLocaleInspection() {
-      super("Implied default locale in case conversion", LocaleDetector.STRING_LOCALE);
-    }
-  }
-
-  public static class AndroidKLintValidFragmentInspection extends AndroidLintInspectionBase {
-    public AndroidKLintValidFragmentInspection() {
-      super(AndroidBundle.message("android.lint.inspections.valid.fragment"), ISSUE);
-    }
-  }
-
-  public static class AndroidKLintViewConstructorInspection extends AndroidLintInspectionBase {
-    public AndroidKLintViewConstructorInspection() {
-      super(AndroidBundle.message("android.lint.inspections.view.constructor"), ViewConstructorDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintViewHolderInspection extends AndroidLintInspectionBase {
-    public AndroidKLintViewHolderInspection() {
-      super(AndroidBundle.message("android.lint.inspections.view.holder"), ViewHolderDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintViewTagInspection extends AndroidLintInspectionBase {
-    public AndroidKLintViewTagInspection() {
-      super("Tagged object leaks", ViewTagDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintMergeRootFrameInspection extends AndroidLintInspectionBase {
-    public AndroidKLintMergeRootFrameInspection() {
-      super(AndroidBundle.message("android.lint.inspections.merge.root.frame"), MergeRootFrameLayoutDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintExportedServiceInspection extends AndroidLintInspectionBase {
-    public AndroidKLintExportedServiceInspection() {
-      super(AndroidBundle.message("android.lint.inspections.exported.service"), SecurityDetector.EXPORTED_SERVICE);
-    }
-
-  }
-
-  public static class AndroidKLintGrantAllUrisInspection extends AndroidLintInspectionBase {
-    public AndroidKLintGrantAllUrisInspection() {
-      super(AndroidBundle.message("android.lint.inspections.grant.all.uris"), SecurityDetector.OPEN_PROVIDER);
-    }
-  }
-
-  public static class AndroidKLintWorldWriteableFilesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintWorldWriteableFilesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.world.writeable.files"), SecurityDetector.WORLD_WRITEABLE);
-    }
-  }
-
-  public static class AndroidKLintSSLCertificateSocketFactoryCreateSocketInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSSLCertificateSocketFactoryCreateSocketInspection() {
-      super(AndroidBundle.message("android.lint.inspections.sslcertificate.socket.factory.create.socket"), SslCertificateSocketFactoryDetector.CREATE_SOCKET);
-    }
-  }
-
-  public static class AndroidKLintSSLCertificateSocketFactoryGetInsecureInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSSLCertificateSocketFactoryGetInsecureInspection() {
-      super(AndroidBundle.message("android.lint.inspections.sslcertificate.socket.factory.get.insecure"), SslCertificateSocketFactoryDetector.GET_INSECURE);
-    }
-  }
-
-  public static class AndroidKLintSwitchIntDefInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSwitchIntDefInspection() {
-      super("Missing @IntDef in Switch", AnnotationDetector.SWITCH_TYPE_DEF);
-    }
-
-  }
-
-  public static class AndroidKLintTrustAllX509TrustManagerInspection extends AndroidLintInspectionBase {
-    public AndroidKLintTrustAllX509TrustManagerInspection() {
-      super("Insecure TLS/SSL trust manager", TrustAllX509TrustManagerDetector.ISSUE);
-    }
-  }
-
-  private abstract static class AndroidKLintTypographyInspectionBase extends AndroidLintInspectionBase {
-    public AndroidKLintTypographyInspectionBase(String displayName, Issue issue) {
-      super(displayName, issue);
-    }
-
-  }
-
-  public static class AndroidKLintNewApiInspection extends AndroidLintInspectionBase {
-    public AndroidKLintNewApiInspection() {
-      super(AndroidBundle.message("android.lint.inspections.new.api"), ApiDetector.UNSUPPORTED);
-    }
-
-    @NotNull
-    @Override
-    public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
-      return getApiQuickFixes(startElement, endElement, message);
-    }
-
-    @NotNull
-    public static AndroidLintQuickFix[] getApiQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
-      int api = ApiDetector.getRequiredVersion(TextFormat.RAW.toText(message));
-      if (api == -1) {
-        return AndroidLintQuickFix.EMPTY_ARRAY;
-      }
-
-      Project project = startElement.getProject();
-      if (JavaPsiFacade.getInstance(project).findClass(REQUIRES_API_ANNOTATION, GlobalSearchScope.allScope(project)) != null) {
-        return new AndroidLintQuickFix[] {
-                new AddTargetApiQuickFix(api, true),
-                new AddTargetApiQuickFix(api, false),
-                new AddTargetVersionCheckQuickFix(api)
-        };
-      }
-
-      return new AndroidLintQuickFix[] {
-              new AddTargetApiQuickFix(api, false),
-              new AddTargetVersionCheckQuickFix(api)
-      };
-    }
-  }
-
-  public static class AndroidKLintInlinedApiInspection extends AndroidLintInspectionBase {
-    public AndroidKLintInlinedApiInspection() {
-      super(AndroidBundle.message("android.lint.inspections.inlined.api"), ApiDetector.INLINED);
-    }
-
-    @NotNull
-    @Override
-    public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
-      return AndroidKLintNewApiInspection.getApiQuickFixes(startElement, endElement, message);
-    }
-  }
-
-  public static class AndroidKLintOverrideInspection extends AndroidLintInspectionBase {
-    public AndroidKLintOverrideInspection() {
-      super(AndroidBundle.message("android.lint.inspections.override"), ApiDetector.OVERRIDE);
-    }
-
-  }
-
-  private static final Pattern QUOTED_PARAMETER = Pattern.compile("`.+:(.+)=\"(.*)\"`");
-
-  public static class AndroidKLintRtlCompatInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRtlCompatInspection() {
-      super(AndroidBundle.message("android.lint.inspections.rtl.compat"), RtlDetector.COMPAT);
-    }
-
-
-  }
-  public static class AndroidKLintRtlEnabledInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRtlEnabledInspection() {
-      super(AndroidBundle.message("android.lint.inspections.rtl.enabled"), RtlDetector.ENABLED);
-    }
-  }
-  public static class AndroidKLintRtlHardcodedInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRtlHardcodedInspection() {
-      super(AndroidBundle.message("android.lint.inspections.rtl.hardcoded"), RtlDetector.USE_START);
-    }
-  }
-  public static class AndroidKLintRtlSymmetryInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRtlSymmetryInspection() {
-      super(AndroidBundle.message("android.lint.inspections.rtl.symmetry"), RtlDetector.SYMMETRY);
-    }
-  }
-
-  // Missing the following issues, because they require classfile analysis:
-  // FloatMath, FieldGetter, Override, OnClick, ViewTag, DefaultLocale, SimpleDateFormat,
-  // Registered, MissingRegistered, Instantiatable, HandlerLeak, ValidFragment, SecureRandom,
-  // ViewConstructor, Wakelock, Recycle, CommitTransaction, WrongCall, DalvikOverride
-
-  // I think DefaultLocale is already handled by a regular IDEA code check.
-
-  public static class AndroidKLintAddJavascriptInterfaceInspection extends AndroidLintInspectionBase {
-    public AndroidKLintAddJavascriptInterfaceInspection() {
-      super(AndroidBundle.message("android.lint.inspections.add.javascript.interface"), AddJavascriptInterfaceDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintAllowAllHostnameVerifierInspection extends AndroidLintInspectionBase {
-    public AndroidKLintAllowAllHostnameVerifierInspection() {
-      super("Insecure HostnameVerifier", AllowAllHostnameVerifierDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintCommitPrefEditsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCommitPrefEditsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.commit.pref.edits"), CleanupDetector.SHARED_PREF);
-    }
-
-  }
-
-  public static class AndroidKLintCustomViewStyleableInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCustomViewStyleableInspection() {
-      super(AndroidBundle.message("android.lint.inspections.custom.view.styleable"), CustomViewDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintCutPasteIdInspection extends AndroidLintInspectionBase {
-    public AndroidKLintCutPasteIdInspection() {
-      super(AndroidBundle.message("android.lint.inspections.cut.paste.id"), CutPasteDetector.ISSUE);
-    }
-  }
-  public static class AndroidKLintEasterEggInspection extends AndroidLintInspectionBase {
-    public AndroidKLintEasterEggInspection() {
-      super(AndroidBundle.message("android.lint.inspections.easter.egg"), CommentDetector.EASTER_EGG);
-    }
-  }
-  public static class AndroidKLintExportedContentProviderInspection extends AndroidLintInspectionBase {
-    public AndroidKLintExportedContentProviderInspection() {
-      super(AndroidBundle.message("android.lint.inspections.exported.content.provider"), SecurityDetector.EXPORTED_PROVIDER);
-    }
-
-  }
-  public static class AndroidKLintExportedPreferenceActivityInspection extends AndroidLintInspectionBase {
-    public AndroidKLintExportedPreferenceActivityInspection() {
-      super(AndroidBundle.message("android.lint.inspections.exported.preference.activity"), PreferenceActivityDetector.ISSUE);
-    }
-  }
-  public static class AndroidKLintExportedReceiverInspection extends AndroidLintInspectionBase {
-    public AndroidKLintExportedReceiverInspection() {
-      super(AndroidBundle.message("android.lint.inspections.exported.receiver"), SecurityDetector.EXPORTED_RECEIVER);
-    }
-
-  }
-  public static class AndroidKLintIconColorsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconColorsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.colors"), IconDetector.ICON_COLORS);
-    }
-  }
-  public static class AndroidKLintIconExtensionInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconExtensionInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.extension"), IconDetector.ICON_EXTENSION);
-    }
-  }
-  public static class AndroidKLintIconLauncherShapeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconLauncherShapeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.launcher.shape"), IconDetector.ICON_LAUNCHER_SHAPE);
-    }
-  }
-  public static class AndroidKLintIconXmlAndPngInspection extends AndroidLintInspectionBase {
-    public AndroidKLintIconXmlAndPngInspection() {
-      super(AndroidBundle.message("android.lint.inspections.icon.xml.and.png"), IconDetector.ICON_XML_AND_PNG);
-    }
-  }
-  
-  public static class AndroidKLintAuthLeakInspection extends AndroidLintInspectionBase {
-    public AndroidKLintAuthLeakInspection() {
-      super("Code could contain an credential leak", StringAuthLeakDetector.AUTH_LEAK);
-    }
-  }
-
-  public static class AndroidKLintInflateParamsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintInflateParamsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.inflate.params"), LayoutInflationDetector.ISSUE);
-    }
-  }
-  
-  public static class AndroidKLintInvalidUsesTagAttributeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintInvalidUsesTagAttributeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.invalid.uses.tag.attribute"), AndroidAutoDetector.INVALID_USES_TAG_ISSUE);
-    }
-  }
-
-  public static class AndroidKLintJavascriptInterfaceInspection extends AndroidLintInspectionBase {
-    public AndroidKLintJavascriptInterfaceInspection() {
-      super(AndroidBundle.message("android.lint.inspections.javascript.interface"), JavaScriptInterfaceDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintLocalSuppressInspection extends AndroidLintInspectionBase {
-    public AndroidKLintLocalSuppressInspection() {
-      super(AndroidBundle.message("android.lint.inspections.local.suppress"), AnnotationDetector.INSIDE_METHOD);
-    }
-  }
-
-  public static class AndroidKLintLogConditionalInspection extends AndroidLintInspectionBase {
-    public AndroidKLintLogConditionalInspection() {
-      super(AndroidBundle.message("android.lint.inspections.log.conditional"), LogDetector.CONDITIONAL);
-    }
-  }
-
-  public static class AndroidKLintLogTagMismatchInspection extends AndroidLintInspectionBase {
-    public AndroidKLintLogTagMismatchInspection() {
-      super(AndroidBundle.message("android.lint.inspections.log.tag.mismatch"), LogDetector.WRONG_TAG);
-    }
-  }
-
-  public static class AndroidKLintLongLogTagInspection extends AndroidLintInspectionBase {
-    public AndroidKLintLongLogTagInspection() {
-      super(AndroidBundle.message("android.lint.inspections.long.log.tag"), LogDetector.LONG_TAG);
-    }
-  }
-
-  public static class AndroidKLintMissingIntentFilterForMediaSearchInspection extends AndroidLintInspectionBase {
-    public AndroidKLintMissingIntentFilterForMediaSearchInspection() {
-      super(AndroidBundle.message("android.lint.inspections.missing.intent.filter.for.media.search"),
-            AndroidAutoDetector.MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH);
-    }
-  }
-
-  public static class AndroidKLintMissingMediaBrowserServiceIntentFilterInspection extends AndroidLintInspectionBase {
-    public AndroidKLintMissingMediaBrowserServiceIntentFilterInspection() {
-      super(AndroidBundle.message("android.lint.inspections.missing.media.browser.service.intent.filter"),
-            AndroidAutoDetector.MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE);
-    }
-  }
-
-  public static class AndroidKLintMissingOnPlayFromSearchInspection extends AndroidLintInspectionBase {
-    public AndroidKLintMissingOnPlayFromSearchInspection() {
-      super(AndroidBundle.message("android.lint.inspections.missing.on.play.from.search"),
-            AndroidAutoDetector.MISSING_ON_PLAY_FROM_SEARCH);
-    }
-  }
-
-  public static class AndroidKLintOverrideAbstractInspection extends AndroidLintInspectionBase {
-    public AndroidKLintOverrideAbstractInspection() {
-      super(AndroidBundle.message("android.lint.inspections.override.abstract"), OverrideConcreteDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintRecycleInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRecycleInspection() {
-      super(AndroidBundle.message("android.lint.inspections.recycle"), CleanupDetector.RECYCLE_RESOURCE);
-    }
-  }
-
-  public static class AndroidKLintRecyclerViewInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRecyclerViewInspection() {
-      super("RecyclerView Problems", RecyclerViewDetector.FIXED_POSITION);
-    }
-  }
-
-  public static class AndroidKLintRegisteredInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRegisteredInspection() {
-      super(AndroidBundle.message("android.lint.inspections.registered"), RegistrationDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintRequiredSizeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintRequiredSizeInspection() {
-      super(AndroidBundle.message("android.lint.inspections.required.size"), RequiredAttributeDetector.ISSUE);
-    }
-  }
-  public static class AndroidKLintSecureRandomInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSecureRandomInspection() {
-      super("Using a fixed seed with SecureRandom", SecureRandomDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintServiceCastInspection extends AndroidLintInspectionBase {
-    public AndroidKLintServiceCastInspection() {
-      super(AndroidBundle.message("android.lint.inspections.service.cast"), ServiceCastDetector.ISSUE);
-    }
-  }
-  public static class AndroidKLintSetJavaScriptEnabledInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSetJavaScriptEnabledInspection() {
-      super(AndroidBundle.message("android.lint.inspections.set.java.script.enabled"), SetJavaScriptEnabledDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintSetTextI18nInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSetTextI18nInspection() {
-      super(AndroidBundle.message("android.lint.inspections.set.text.i18n"), SetTextDetector.SET_TEXT_I18N);
-    }
-  }
-
-  public static class AndroidKLintSetWorldReadableInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSetWorldReadableInspection() {
-      super(AndroidBundle.message("android.lint.inspections.set.world.readable"), SecurityDetector.SET_READABLE);
-    }
-  }
-
-  public static class AndroidKLintSetWorldWritableInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSetWorldWritableInspection() {
-      super(AndroidBundle.message("android.lint.inspections.set.world.writable"), SecurityDetector.SET_WRITABLE);
-    }
-  }
-
-  public static class AndroidKLintShiftFlagsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintShiftFlagsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.shift.flags"), AnnotationDetector.FLAG_STYLE);
-    }
-  }
-
-  public static class AndroidKLintShortAlarmInspection extends AndroidLintInspectionBase {
-    public AndroidKLintShortAlarmInspection() {
-      super(AndroidBundle.message("android.lint.inspections.short.alarm"), AlarmDetector.ISSUE);
-    }
-  }
-
-  public static class AndroidKLintShowToastInspection extends AndroidLintInspectionBase {
-    public AndroidKLintShowToastInspection() {
-      super(AndroidBundle.message("android.lint.inspections.show.toast"), ToastDetector.ISSUE);
-    }
-  }
-  
-  public static class AndroidKLintSimpleDateFormatInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSimpleDateFormatInspection() {
-      super(AndroidBundle.message("android.lint.inspections.simple.date.format"), DateFormatDetector.DATE_FORMAT);
-    }
-  }
-
-  // Maybe not relevant
-  public static class AndroidKLintStopShipInspection extends AndroidLintInspectionBase {
-    public AndroidKLintStopShipInspection() {
-      super(AndroidBundle.message("android.lint.inspections.stop.ship"), CommentDetector.STOP_SHIP);
-    }
-
-  }
-
-  public static class AndroidKLintSupportAnnotationUsageInspection extends AndroidLintInspectionBase {
-    public AndroidKLintSupportAnnotationUsageInspection() {
-      super("Incorrect support annotation usage", AnnotationDetector.ANNOTATION_USAGE);
-    }
-  }
-
-  public static class AndroidKLintUniqueConstantsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUniqueConstantsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.unique.constants"), AnnotationDetector.UNIQUE);
-    }
-  }
-
-  public static class AndroidKLintUnlocalizedSmsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnlocalizedSmsInspection() {
-      super(AndroidBundle.message("android.lint.inspections.unlocalized.sms"), NonInternationalizedSmsDetector.ISSUE);
-    }
-  }
-  public static class AndroidKLintWorldReadableFilesInspection extends AndroidLintInspectionBase {
-    public AndroidKLintWorldReadableFilesInspection() {
-      super(AndroidBundle.message("android.lint.inspections.world.readable.files"), SecurityDetector.WORLD_READABLE);
-    }
-  }
-  public static class AndroidKLintWrongCallInspection extends AndroidLintInspectionBase {
-    public AndroidKLintWrongCallInspection() {
-      super(AndroidBundle.message("android.lint.inspections.wrong.call"), WrongCallDetector.ISSUE);
-    }
-
-  }
-
-  public static class AndroidKLintPendingBindingsInspection extends AndroidLintInspectionBase {
-    public AndroidKLintPendingBindingsInspection() {
-      super("Missing Pending Bindings", RecyclerViewDetector.DATA_BINDER);
-    }
-  }
-
-  public static class AndroidKLintUnsafeDynamicallyLoadedCodeInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnsafeDynamicallyLoadedCodeInspection() {
-      super("load used to dynamically load code", UnsafeNativeCodeDetector.LOAD);
-    }
-  }
-
-  public static class AndroidKLintUnsafeNativeCodeLocationInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnsafeNativeCodeLocationInspection() {
-      super("Native code outside library directory", UnsafeNativeCodeDetector.UNSAFE_NATIVE_CODE_LOCATION);
-    }
-  }
-
-  public static class AndroidKLintUnsafeProtectedBroadcastReceiverInspection extends AndroidLintInspectionBase {
-    public AndroidKLintUnsafeProtectedBroadcastReceiverInspection() {
-      super("Unsafe Protected BroadcastReceiver", UnsafeBroadcastReceiverDetector.ACTION_STRING);
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintQuickFix.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintQuickFix.java
deleted file mode 100644
index 967631a..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintQuickFix.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
-public interface AndroidLintQuickFix {
-  AndroidLintQuickFix[] EMPTY_ARRAY = new AndroidLintQuickFix[0];
-  
-  void apply(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.Context context);
-
-  boolean isApplicable(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.ContextType contextType);
-
-  @NotNull
-  String getName();
-}
-
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintUtil.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintUtil.java
deleted file mode 100644
index 9c727a9..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.detector.api.Issue;
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInspection.InspectionProfile;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class AndroidLintUtil {
-  @NonNls static final String ATTR_VALUE_VERTICAL = "vertical";
-  @NonNls static final String ATTR_VALUE_WRAP_CONTENT = "wrap_content";
-  @NonNls static final String ATTR_LAYOUT_HEIGHT = "layout_height";
-  @NonNls static final String ATTR_LAYOUT_WIDTH = "layout_width";
-  @NonNls static final String ATTR_ORIENTATION = "orientation";
-
-  private AndroidLintUtil() {
-  }
-
-  @Nullable
-  public static Pair<AndroidLintInspectionBase, HighlightDisplayLevel> getHighlighLevelAndInspection(@NotNull Project project,
-                                                                                                     @NotNull Issue issue,
-                                                                                                     @NotNull PsiElement context) {
-    final String inspectionShortName = AndroidLintInspectionBase.getInspectionShortNameByIssue(project, issue);
-    if (inspectionShortName == null) {
-      return null;
-    }
-
-    final HighlightDisplayKey key = HighlightDisplayKey.find(inspectionShortName);
-    if (key == null) {
-      return null;
-    }
-
-    final InspectionProfile profile = InspectionProjectProfileManager.getInstance(context.getProject()).getInspectionProfile();
-    if (!profile.isToolEnabled(key, context)) {
-      if (!issue.isEnabledByDefault()) {
-        // Lint will skip issues (and not report them) for issues that have been disabled,
-        // except for those issues that are explicitly enabled via Gradle. Therefore, if
-        // we get this far, lint has found this issue to be explicitly enabled, so we let
-        // that setting override a local enabled/disabled state in the IDE profile.
-      } else {
-        return null;
-      }
-    }
-
-    final AndroidLintInspectionBase inspection = (AndroidLintInspectionBase)profile.getUnwrappedTool(inspectionShortName, context);
-    if (inspection == null) return null;
-    final HighlightDisplayLevel errorLevel = profile.getErrorLevel(key, context);
-    return Pair.create(inspection,
-                       errorLevel != null ? errorLevel : HighlightDisplayLevel.WARNING);
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidQuickfixContexts.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidQuickfixContexts.java
deleted file mode 100644
index f4c9238..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidQuickfixContexts.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.intellij.openapi.editor.Editor;
-import org.jetbrains.annotations.NotNull;
-
-public class AndroidQuickfixContexts {
-  public static abstract class Context {
-    private final ContextType myType;
-
-    private Context(@NotNull ContextType type) {
-      myType = type;
-    }
-
-    @NotNull
-    public ContextType getType() {
-      return myType;
-    }
-  }
-
-  public static class ContextType {
-    private ContextType() {
-    }
-  }
-
-  public static class BatchContext extends Context {
-    public static final ContextType TYPE = new ContextType();
-    private static final BatchContext INSTANCE = new BatchContext();
-
-    private BatchContext() {
-      super(TYPE);
-    }
-
-    @NotNull
-    public static BatchContext getInstance() {
-      return INSTANCE;
-    }
-  }
-
-  public static class EditorContext extends Context {
-    public static final ContextType TYPE = new ContextType();
-    private final Editor myEditor;
-
-    private EditorContext(@NotNull Editor editor) {
-      super(TYPE);
-      myEditor = editor;
-    }
-
-    @NotNull
-    public Editor getEditor() {
-      return myEditor;
-    }
-
-    @NotNull
-    public static EditorContext getInstance(@NotNull Editor editor) {
-      return new EditorContext(editor);
-    }
-  }
-
-  public static class DesignerContext extends Context {
-    public static final ContextType TYPE = new ContextType();
-    private static final DesignerContext INSTANCE = new DesignerContext();
-
-    private DesignerContext() {
-      super(TYPE);
-    }
-
-    @NotNull
-    public static DesignerContext getInstance() {
-      return INSTANCE;
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiConverter.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiConverter.java
deleted file mode 100644
index d0b29f0..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiConverter.java
+++ /dev/null
@@ -1,1302 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.xml.*;
-import com.intellij.util.containers.HashMap;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.w3c.dom.*;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Converter which takes a PSI hierarchy for an XML file or document, and
- * creates a corresponding W3C DOM tree. It attempts to delegate as much
- * as possible to the original PSI tree. Note also that the {@link #getTextRange(Node)}}
- * method allows us to look up source offsets for the DOM nodes (which plain XML
- * DOM parsers do not).
- * <p>
- * NOTE: The tree may not be semantically equivalent to the XML PSI structure; this
- * converter only attempts to make the DOM correct as far as Lint cares (meaning that it
- * only worries about the details Lint cares about; currently this means it only wraps elements,
- * text and comment nodes.)
- */
-class DomPsiConverter {
-  private DomPsiConverter() {
-  }
-
-  /**
-   * Convert the given {@link XmlFile} to a DOM tree
-   *
-   * @param xmlFile the file to be converted
-   * @return a corresponding W3C DOM tree
-   */
-  @Nullable
-  public static Document convert(@NotNull XmlFile xmlFile) {
-    try {
-      XmlDocument xmlDocument = xmlFile.getDocument();
-      if (xmlDocument == null) {
-        return null;
-      }
-
-      return convert(xmlDocument);
-    }
-    catch (ProcessCanceledException e) {
-      // Ignore: common occurrence, e.g. we're running lint as part of an editor background
-      // and while lint is running the user switches files: the inspections framework will
-      // then cancel the process from within the PSI machinery (which asks the progress manager
-      // periodically whether the operation is cancelled) and we find ourselves here
-      return null;
-    }
-    catch (Exception e) {
-      String path = xmlFile.getName();
-      VirtualFile virtualFile = xmlFile.getVirtualFile();
-      if (virtualFile != null) {
-        path = virtualFile.getPath();
-      }
-      throw new RuntimeException("Could not convert file " + path, e);
-    }
-  }
-
-  /**
-   * Convert the given {@link XmlDocument} to a DOM tree
-   *
-   * @param document the document to be converted
-   * @return a corresponding W3C DOM tree
-   */
-  @Nullable
-  private static Document convert(@NotNull XmlDocument document)  {
-    return new DomDocument(document);
-  }
-
-  /** Gets the {@link TextRange} for a {@link Node} created with this converter */
-  @NotNull
-  public static TextRange getTextRange(@NotNull Node node) {
-    assert node instanceof DomNode;
-    DomNode domNode = (DomNode)node;
-    XmlElement element = domNode.myElement;
-
-    // For elements, don't highlight the entire element range; instead, just
-    // highlight the element name
-    if (node.getNodeType() == Node.ELEMENT_NODE) {
-      return getTextNameRange(node);
-    }
-
-    return element.getTextRange();
-  }
-
-  /** Gets the {@link TextRange} for a {@link Node} created with this converter */
-  @NotNull
-  public static TextRange getTextNameRange(@NotNull Node node) {
-    assert node instanceof DomNode;
-    DomNode domNode = (DomNode)node;
-    XmlElement element = domNode.myElement;
-
-    // For elements and attributes, don't highlight the entire element range; instead, just
-    // highlight the element name
-    if (node.getNodeType() == Node.ELEMENT_NODE && element instanceof XmlTag) {
-      String tag = node.getNodeName();
-      int index = element.getText().indexOf(tag);
-      if (index != -1) {
-        TextRange textRange = element.getTextRange();
-        int start = textRange.getStartOffset() + index;
-        return new TextRange(start, start + tag.length());
-      }
-    } else if (node.getNodeType() == Node.ATTRIBUTE_NODE && element instanceof XmlAttribute) {
-      XmlElement nameElement = ((XmlAttribute)element).getNameElement();
-      if (nameElement != null) {
-        return nameElement.getTextRange();
-      }
-    }
-
-    return element.getTextRange();
-  }
-
-  /** Gets the {@link TextRange} for the value region of a {@link Node} created with this converter */
-  @NotNull
-  public static TextRange getTextValueRange(@NotNull Node node) {
-    assert node instanceof DomNode;
-    DomNode domNode = (DomNode)node;
-    XmlElement element = domNode.myElement;
-    TextRange textRange = element.getTextRange();
-
-    // For attributes, don't highlight the entire element range; instead, just
-    // highlight the value range
-    if (node.getNodeType() == Node.ATTRIBUTE_NODE && element instanceof XmlAttribute) {
-      XmlAttributeValue valueElement = ((XmlAttribute)element).getValueElement();
-      if (valueElement != null) {
-        return valueElement.getValueTextRange();
-      }
-    }
-
-    return textRange;
-  }
-
-  private static final NodeList EMPTY = new NodeList() {
-    @NotNull
-    @Override
-    public Node item(int i) {
-      throw new IllegalArgumentException();
-    }
-
-    @Override
-    public int getLength() {
-      return 0;
-    }
-  };
-
-  @Nullable
-  private static final NamedNodeMap EMPTY_ATTRIBUTES = new NamedNodeMap() {
-    @Override
-    public int getLength() {
-      return 0;
-    }
-
-    @Nullable
-    @Override
-    public Node getNamedItem(String s) {
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public Node getNamedItemNS(String s, String s2) throws DOMException {
-      return null;
-    }
-
-    @NotNull
-    @Override
-    public Node setNamedItem(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Node removeNamedItem(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Node item(int i) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Nullable
-    @Override
-    public Node setNamedItemNS(Node node) throws DOMException {
-      return null;
-    }
-
-    @NotNull
-    @Override
-    public Node removeNamedItemNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-  };
-
-  private static class DomNodeList implements NodeList {
-    protected final List<DomNode> myChildren = new ArrayList<DomNode>();
-
-    @NotNull
-    @Override
-    public Node item(int i) {
-      return myChildren.get(i);
-    }
-
-    @Override
-    public int getLength() {
-      return myChildren.size();
-    }
-
-    void add(@NotNull DomNode node) {
-      int size = myChildren.size();
-      if (size > 0) {
-        DomNode last = myChildren.get(size - 1);
-        node.myPrevious = last;
-        last.myNext = node;
-      }
-      myChildren.add(node);
-    }
-  }
-
-  private static class DomNamedNodeMap implements NamedNodeMap {
-    @NotNull protected final Map<String, DomNode> myMap;
-    @NotNull protected final Map<String, Map<String, DomNode>> myNsMap;
-    @NotNull protected final List<DomNode> mItems;
-
-    private DomNamedNodeMap(@NotNull DomElement element, @NotNull XmlAttribute[] attributes) {
-      int count = attributes.length;
-      int namespaceCount = 0;
-      for (XmlAttribute attribute : attributes) {
-        if (!attribute.getNamespace().isEmpty()) {
-          namespaceCount++;
-        }
-      }
-      myMap = new HashMap<String, DomNode>(count - namespaceCount);
-      myNsMap = new HashMap<String, Map<String, DomNode>>(namespaceCount);
-      mItems = new ArrayList<DomNode>(count);
-
-      assert element.myOwner != null; // True for elements, not true for non-Element nodes
-      for (XmlAttribute attribute : attributes) {
-        DomAttr attr = new DomAttr(element.myOwner, element, attribute);
-        mItems.add(attr);
-        String namespace = attribute.getNamespace();
-        if (!namespace.isEmpty()) {
-          Map<String, DomNode> map = myNsMap.get(namespace);
-          if (map == null) {
-            map = new HashMap<String, DomNode>();
-            myNsMap.put(namespace, map);
-          }
-          map.put(attribute.getLocalName(), attr);
-        } else {
-          myMap.put(attribute.getName(), attr);
-        }
-      }
-    }
-
-    @Override
-    public Node item(int i) {
-      return mItems.get(i);
-    }
-
-    @Override
-    public int getLength() {
-      return mItems.size();
-    }
-
-    @Override
-    public Node getNamedItem(@NotNull String s) {
-      return myMap.get(s);
-    }
-
-    @Nullable
-    @Override
-    public Node getNamedItemNS(@NotNull String namespace, @NotNull String name) throws DOMException {
-      Map<String, DomNode> map = myNsMap.get(namespace);
-      if (map != null) {
-        return map.get(name);
-      }
-      return null;
-    }
-
-    @NotNull
-    @Override
-    public Node setNamedItem(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node removeNamedItem(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node setNamedItemNS(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node removeNamedItemNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-  }
-
-  @SuppressWarnings({"UnusedParameters", "UnusedDeclaration"}) // Specifies methods shared by children
-  private static abstract class DomNode implements Node {
-    @Nullable protected final Document myOwner;
-    @Nullable protected final DomNode myParent;
-    @NotNull protected final XmlElement myElement;
-    @Nullable protected NodeList myChildren;
-    @Nullable protected DomNode myNext;
-    @Nullable protected DomNode myPrevious;
-
-    protected DomNode(@Nullable Document owner, @Nullable DomNode parent, @NotNull XmlElement element) {
-      myOwner = owner;
-      myParent = parent;
-      myElement = element;
-    }
-
-    @Nullable
-    @Override
-    public Node getParentNode() {
-      return myParent;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getChildNodes() {
-      if (myChildren == null) {
-        PsiElement[] children = myElement.getChildren();
-        if (children.length > 0) {
-          DomNodeList list = new DomNodeList();
-          myChildren = list;
-          // True except for in DomDocument, which has custom getChildNodes
-          assert myOwner != null;
-
-          for (PsiElement child : children) {
-            if (child instanceof XmlTag) {
-              list.add(new DomElement(myOwner, this, (XmlTag) child));
-            } else if (child instanceof XmlText) {
-              list.add(new DomText(myOwner, this, (XmlText) child));
-            } else if (child instanceof XmlComment) {
-              list.add(new DomComment(myOwner, this, (XmlComment) child));
-            } else {
-              // Skipping other types for now; lint doesn't care about them.
-              // TODO: Consider whether we need CDATA.
-            }
-          }
-        } else {
-          myChildren = EMPTY;
-        }
-      }
-      return myChildren;
-    }
-
-    @Nullable
-    @Override
-    public Node getFirstChild() {
-      NodeList childNodes = getChildNodes();
-      if (childNodes.getLength() > 0) {
-        return childNodes.item(0);
-      }
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public Node getLastChild() {
-      NodeList childNodes = getChildNodes();
-      if (childNodes.getLength() > 0) {
-        return childNodes.item(0);
-      }
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public Node getPreviousSibling() {
-      return myPrevious;
-    }
-
-    @Nullable
-    @Override
-    public Node getNextSibling() {
-      return myNext;
-    }
-
-    @Nullable
-    @Override
-    public NamedNodeMap getAttributes() {
-      throw new UnsupportedOperationException(); // Only supported on elements
-    }
-
-    @Nullable
-    @Override
-    public Document getOwnerDocument() {
-      return myOwner;
-    }
-
-    @Override
-    public void setNodeValue(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node insertBefore(Node node, Node node2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node replaceChild(Node node, Node node2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node removeChild(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node appendChild(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public boolean hasChildNodes() {
-      return getChildNodes().getLength() > 0;
-    }
-
-    @NotNull
-    @Override
-    public Node cloneNode(boolean b) {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void normalize() {
-    }
-
-    @Override
-    public boolean isSupported(String s, String s2) {
-      return false;
-    }
-
-    @NotNull
-    @Override
-    public String getNamespaceURI() {
-      throw new UnsupportedOperationException(); // Only supported on elements in lint
-    }
-
-    @NotNull
-    @Override
-    public String getPrefix() {
-      throw new UnsupportedOperationException(); // Only supported on elements in lint
-    }
-
-    @Override
-    public void setPrefix(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Nullable
-    @Override
-    public String getLocalName() {
-      return null;
-    }
-
-    @Override
-    public boolean hasAttributes() {
-      return false;
-    }
-
-    @Nullable
-    @Override
-    public String getBaseURI() {
-      return null;
-    }
-
-    @Override
-    public short compareDocumentPosition(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public String getTextContent() throws DOMException {
-      return myElement.getText();
-    }
-
-    @Override
-    public void setTextContent(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public boolean isSameNode(Node node) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public String lookupPrefix(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public boolean isDefaultNamespace(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public String lookupNamespaceURI(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public boolean isEqualNode(Node node) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Object getFeature(String s, String s2) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Object setUserData(String s, Object o, UserDataHandler userDataHandler) {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Object getUserData(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    // From CharacterData
-
-    @NotNull
-    public String getData() throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public void setData(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public int getLength() {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    public String substringData(int i, int i2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public void appendData(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public void insertData(int i, String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public void deleteData(int i, int i2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    public void replaceData(int i, int i2, String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-  }
-
-  private static class DomDocument extends DomNode implements Document {
-    @NotNull private final XmlDocument myPsiDocument;
-    @Nullable private DomElement myRoot;
-
-    private DomDocument(@NotNull XmlDocument document) {
-      super(null, null, document);
-      myPsiDocument = document;
-    }
-
-    // From org.w3c.dom.Node:
-
-    @Nullable
-    @Override
-    public String getNodeName() {
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public String getNodeValue() throws DOMException {
-      return null;
-    }
-
-    @Override
-    public short getNodeType() {
-      return Node.DOCUMENT_NODE;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getChildNodes() {
-      if (myChildren == null) {
-        DomNodeList list = new DomNodeList();
-        myChildren = list;
-        DomNode documentElement = (DomNode)getDocumentElement();
-        if (documentElement != null) {
-          list.add(documentElement);
-        }
-      }
-
-      return myChildren;
-    }
-
-    // From org.w3c.dom.Document:
-
-    @NotNull
-    @Override
-    public DocumentType getDoctype() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public DOMImplementation getImplementation() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Nullable
-    @Override
-    public Element getDocumentElement() {
-      if (myRoot == null) {
-        XmlTag rootTag = myPsiDocument.getRootTag();
-        if (rootTag == null) {
-          return null;
-        }
-        myRoot = new DomElement(this, this, rootTag);
-      }
-
-      return myRoot;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getElementsByTagName(String s) {
-      Element root = getDocumentElement();
-      if (root != null) {
-        return root.getElementsByTagName(s);
-      }
-      return EMPTY;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getElementsByTagNameNS(String s, String s2) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Element createElement(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public DocumentFragment createDocumentFragment() {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Text createTextNode(String s) {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Comment createComment(String s) {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public CDATASection createCDATASection(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public ProcessingInstruction createProcessingInstruction(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Attr createAttribute(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public EntityReference createEntityReference(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Node importNode(Node node, boolean b) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Element createElementNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Attr createAttributeNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Element getElementById(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public String getInputEncoding() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public String getXmlEncoding() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public boolean getXmlStandalone() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void setXmlStandalone(boolean b) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public String getXmlVersion() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void setXmlVersion(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public boolean getStrictErrorChecking() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void setStrictErrorChecking(boolean b) {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public String getDocumentURI() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void setDocumentURI(String s) {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Node adoptNode(Node node) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public DOMConfiguration getDomConfig() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void normalizeDocument() {
-    }
-
-    @NotNull
-    @Override
-    public Node renameNode(Node node, String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-  }
-
-  private static class DomElement extends DomNode implements Element {
-    private final XmlTag myTag;
-    @Nullable private NamedNodeMap myAttributes;
-
-    private DomElement(@NotNull Document owner, @NotNull DomNode parent, @NotNull XmlTag tag) {
-      super(owner, parent, tag);
-      myTag = tag;
-    }
-
-    // From org.w3c.dom.Node:
-
-    @NotNull
-    @Override
-    public String getNodeName() {
-      return getTagName();
-    }
-
-    @Nullable
-    @Override
-    public String getNodeValue() throws DOMException {
-      return null;
-    }
-
-    @Override
-    public short getNodeType() {
-      return Node.ELEMENT_NODE;
-    }
-
-    @NotNull
-    @Override
-    public NamedNodeMap getAttributes() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<NamedNodeMap>() {
-          @Override
-          public NamedNodeMap compute() {
-            return getAttributes();
-          }
-        });
-      }
-
-      if (myAttributes == null) {
-        XmlAttribute[] attributes = myTag.getAttributes();
-        if (attributes.length == 0) {
-         myAttributes = EMPTY_ATTRIBUTES;
-        } else {
-          myAttributes = new DomNamedNodeMap(this, attributes);
-        }
-      }
-
-      return myAttributes;
-    }
-
-    // From org.w3c.dom.Element:
-
-    @NotNull
-    @Override
-    public String getTagName() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getTagName();
-          }
-        });
-      }
-
-      return myTag.getName();
-    }
-
-    @NotNull
-    @Override
-    public String getAttribute(@NotNull String name) {
-      Node node = getAttributes().getNamedItem(name);
-      if (node != null) {
-        return node.getNodeValue();
-      }
-      return "";
-    }
-
-    @NotNull
-    @Override
-    public String getAttributeNS(@NotNull String namespace, @NotNull String name) throws DOMException {
-      Node node = getAttributes().getNamedItemNS(namespace, name);
-      if (node != null) {
-        return node.getNodeValue();
-      }
-      return "";
-    }
-
-    @Nullable
-    @Override
-    public Attr getAttributeNodeNS(@NotNull String namespace, @NotNull String name) throws DOMException {
-      Node node = getAttributes().getNamedItemNS(namespace, name);
-      if (node != null) {
-        return (Attr)node;
-      }
-      return  null;
-    }
-
-    @Nullable
-    @Override
-    public Attr getAttributeNode(@NotNull String name) {
-      Node node = getAttributes().getNamedItem(name);
-      if (node != null) {
-        return (Attr)node;
-      }
-      return  null;
-    }
-
-    @Override
-    public boolean hasAttribute(@NotNull String name) {
-      return getAttributes().getNamedItem(name) != null;
-    }
-
-    @Override
-    public boolean hasAttributeNS(@NotNull String namespace, @NotNull String name) throws DOMException {
-      return getAttributes().getNamedItemNS(namespace, name) != null;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getElementsByTagName(@NotNull String s) {
-      NodeList childNodes = getChildNodes();
-      if (childNodes == EMPTY) {
-        return EMPTY;
-      }
-      DomNodeList matches = new DomNodeList();
-      for (int i = 0, n = childNodes.getLength(); i < n; i++) {
-        Node node = childNodes.item(i);
-        if (s.equals(node.getNodeName())) {
-          matches.add((DomNode)node);
-        }
-      }
-
-      return matches;
-    }
-
-    @NotNull
-    @Override
-    public NodeList getElementsByTagNameNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Attr setAttributeNode(Attr attr) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Attr removeAttributeNode(Attr attr) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void setAttributeNS(String s, String s2, String s3) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void removeAttributeNS(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void setAttribute(String s, String s2) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void removeAttribute(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Attr setAttributeNodeNS(Attr attr) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public TypeInfo getSchemaTypeInfo() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public void setIdAttribute(String s, boolean b) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void setIdAttributeNS(String s, String s2, boolean b) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public void setIdAttributeNode(Attr attr, boolean b) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-  }
-
-  private static class DomText extends DomNode implements Text {
-    @NotNull private final XmlText myText;
-
-    private DomText(@NotNull Document owner, @NotNull DomNode parent, @NotNull XmlText text) {
-      super(owner, parent, text);
-      myText = text;
-    }
-
-    // From org.w3c.dom.Node:
-
-    @Nullable
-    @Override
-    public String getNodeName() {
-      return null;
-    }
-
-    @NotNull
-    @Override
-    public String getNodeValue() throws DOMException {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getNodeValue();
-          }
-        });
-      }
-
-      return myText.getText();
-    }
-
-    @Override
-    public short getNodeType() {
-      return Node.TEXT_NODE;
-    }
-
-    // From org.w3c.dom.Text:
-
-    @NotNull
-    @Override
-    public Text splitText(int i) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @Override
-    public boolean isElementContentWhitespace() {
-      String s = myText.getText();
-      for (int i = 0, n = s.length(); i < n; i++) {
-        if (!Character.isWhitespace(s.charAt(i))) {
-          return false;
-        }
-      }
-
-      return true;
-    }
-
-    @NotNull
-    @Override
-    public String getWholeText() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public Text replaceWholeText(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-  }
-
-  private static class DomComment extends DomNode implements Comment {
-    @NotNull private final XmlComment myComment;
-
-    private DomComment(@NotNull Document owner, @NotNull DomNode parent, @NotNull XmlComment comment) {
-      super(owner, parent, comment);
-      myComment = comment;
-    }
-
-    // From org.w3c.dom.Node:
-
-    @Nullable
-    @Override
-    public String getNodeName() {
-      return null;
-    }
-
-    @NotNull
-    @Override
-    public String getNodeValue() throws DOMException {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getNodeValue();
-          }
-        });
-      }
-
-      return myComment.getText();
-    }
-
-    @Override
-    public short getNodeType() {
-      return Node.COMMENT_NODE;
-    }
-
-    @NotNull
-    @Override
-    public String getTextContent() throws DOMException {
-      return getNodeValue();
-    }
-  }
-
-  private static class DomAttr extends DomNode implements Attr {
-    @NotNull private final DomElement myOwner;
-    @NotNull private final XmlAttribute myAttribute;
-
-    private DomAttr(@NotNull Document document, @NotNull DomElement owner, @NotNull XmlAttribute attribute) {
-      super(document, null, attribute);
-      myOwner = owner;
-      myAttribute = attribute;
-    }
-
-    // From org.w3c.dom.Node:
-
-    @NotNull
-    @Override
-    public String getNodeName() {
-      return getName();
-    }
-
-    @NotNull
-    @Override
-    public String getNodeValue() throws DOMException {
-      return getValue();
-    }
-
-    @Override
-    public short getNodeType() {
-      return Node.ATTRIBUTE_NODE;
-    }
-
-    // From org.w3c.dom.Attr:
-
-    @NotNull
-    @Override
-    public String getName() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getName();
-          }
-        });
-      }
-      return myAttribute.getName();
-    }
-
-    @Override
-    public boolean getSpecified() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @NotNull
-    @Override
-    public String getValue() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getValue();
-          }
-        });
-      }
-
-      String value = myAttribute.getValue();
-      if (value == null) {
-        value = "";
-      }
-      return value;
-    }
-
-    @NotNull
-    @Override
-    public String getLocalName() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getLocalName();
-          }
-        });
-      }
-
-      return myAttribute.getLocalName();
-    }
-
-    @NotNull
-    @Override
-    public String getPrefix() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getPrefix();
-          }
-        });
-      }
-
-      return myAttribute.getNamespacePrefix();
-    }
-
-    @NotNull
-    @Override
-    public String getNamespaceURI() {
-      Application application = ApplicationManager.getApplication();
-      if (!application.isReadAccessAllowed()) {
-        return application.runReadAction(new Computable<String>() {
-          @Override
-          public String compute() {
-            return getNamespaceURI();
-          }
-        });
-      }
-
-      return myAttribute.getNamespace();
-    }
-
-    @Override
-    public void setValue(String s) throws DOMException {
-      throw new UnsupportedOperationException(); // Read-only bridge
-    }
-
-    @NotNull
-    @Override
-    public Element getOwnerElement() {
-      return myOwner;
-    }
-
-    @NotNull
-    @Override
-    public TypeInfo getSchemaTypeInfo() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-
-    @Override
-    public boolean isId() {
-      throw new UnsupportedOperationException(); // Not supported
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiParser.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiParser.java
deleted file mode 100644
index 1c0ca05..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/DomPsiParser.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.client.api.XmlParser;
-import com.android.tools.klint.detector.api.DefaultPosition;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Position;
-import com.android.tools.klint.detector.api.XmlContext;
-import com.intellij.openapi.application.AccessToken;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.xml.XmlFile;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.File;
-
-/**
- * Lint parser which reads in a DOM from a given file, by mapping to the underlying XML PSI structure
- */
-class DomPsiParser extends XmlParser {
-  private final LintClient myClient;
-  private AccessToken myReadLock;
-
-  public DomPsiParser(LintClient client) {
-    myClient = client;
-  }
-
-  @Override
-  public void dispose(@NonNull XmlContext context, @NonNull Document document) {
-    if (context.document != null) {
-      myReadLock.finish();
-      myReadLock = null;
-      context.document = null;
-    }
-  }
-
-  @Override
-  public int getNodeStartOffset(@NonNull XmlContext context, @NonNull Node node) {
-    TextRange textRange = DomPsiConverter.getTextRange(node);
-    return textRange.getStartOffset();
-  }
-
-  @Override
-  public int getNodeEndOffset(@NonNull XmlContext context, @NonNull Node node) {
-    TextRange textRange = DomPsiConverter.getTextRange(node);
-    return textRange.getEndOffset();
-  }
-
-  @Nullable
-  @Override
-  public Document parseXml(@NonNull final XmlContext context) {
-    assert myReadLock == null;
-    myReadLock = ApplicationManager.getApplication().acquireReadActionLock();
-    Document document = parse(context);
-    if (document == null) {
-      myReadLock.finish();
-      myReadLock = null;
-    }
-    return document;
-  }
-
-  @Nullable
-  private Document parse(XmlContext context) {
-    // Should only be called from read thread
-    assert ApplicationManager.getApplication().isReadAccessAllowed();
-
-    final PsiFile psiFile = IntellijLintUtils.getPsiFile(context);
-    if (!(psiFile instanceof XmlFile)) {
-      return null;
-    }
-    XmlFile xmlFile = (XmlFile)psiFile;
-
-    try {
-      return DomPsiConverter.convert(xmlFile);
-    } catch (Throwable t) {
-      myClient.log(t, "Failed converting PSI parse tree to DOM for file %1$s",
-                   context.file.getPath());
-      return null;
-    }
-  }
-
-  @NonNull
-  @Override
-  public Location getLocation(@NonNull XmlContext context, @NonNull Node node) {
-    TextRange textRange = DomPsiConverter.getTextRange(node);
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-    Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-    return Location.create(context.file, start, end);
-  }
-
-  @NonNull
-  @Override
-  public Location getLocation(@NonNull XmlContext context, @NonNull Node node, int startDelta, int endDelta) {
-    TextRange textRange = DomPsiConverter.getTextRange(node);
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset() + startDelta);
-    Position end = new DefaultPosition(-1, -1, textRange.getStartOffset() + endDelta);
-    return Location.create(context.file, start, end);
-  }
-
-  @NonNull
-  @Override
-  public Location getNameLocation(@NonNull XmlContext context, @NonNull Node node) {
-    TextRange textRange = DomPsiConverter.getTextNameRange(node);
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-    Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-    return Location.create(context.file, start, end);
-  }
-
-  @NonNull
-  @Override
-  public Location getValueLocation(@NonNull XmlContext context, @NonNull Attr node) {
-    TextRange textRange = DomPsiConverter.getTextValueRange(node);
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-    Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-    return Location.create(context.file, start, end);
-  }
-
-  @NonNull
-  @Override
-  public Location.Handle createLocationHandle(@NonNull XmlContext context, @NonNull Node node) {
-    return new LocationHandle(context.file, node);
-  }
-
-  private static class LocationHandle implements Location.Handle {
-    private final File myFile;
-    private final Node myNode;
-    private Object myClientData;
-
-    public LocationHandle(File file, Node node) {
-      myFile = file;
-      myNode = node;
-    }
-
-    @NonNull
-    @Override
-    public Location resolve() {
-      if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
-        return ApplicationManager.getApplication().runReadAction(new Computable<Location>() {
-          @Override
-          public Location compute() {
-            return resolve();
-          }
-        });
-      }
-      TextRange textRange = DomPsiConverter.getTextRange(myNode);
-      Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-      Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-      return Location.create(myFile, start, end);
-    }
-
-    @Override
-    public void setClientData(@Nullable Object clientData) {
-      myClientData = clientData;
-    }
-
-    @Override
-    @Nullable
-    public Object getClientData() {
-      return myClientData;
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IdeaJavaParser.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IdeaJavaParser.java
deleted file mode 100644
index 5f468cc1..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IdeaJavaParser.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.JavaEvaluator;
-import com.android.tools.klint.client.api.JavaParser;
-import com.android.tools.klint.detector.api.JavaContext;
-import com.android.tools.klint.detector.api.Location;
-import com.android.tools.klint.detector.api.Severity;
-import com.google.common.collect.Sets;
-import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.InheritanceUtil;
-import lombok.ast.Node;
-import lombok.ast.Position;
-import org.jetbrains.uast.UastContext;
-
-import java.io.File;
-import java.util.List;
-
-public class IdeaJavaParser extends JavaParser {
-    private final IntellijLintClient myClient;
-    private final Project myProject;
-    private final UastContext myContext;
-    private final JavaEvaluator myEvaluator;
-
-    public IdeaJavaParser(IntellijLintClient client, Project myProject) {
-        this.myClient = client;
-        this.myProject = myProject;
-        this.myEvaluator = new MyJavaEvaluator(myProject);
-
-        myContext = ServiceManager.getService(myProject, UastContext.class);
-    }
-
-    @Override
-    public UastContext getUastContext() {
-        return myContext;
-    }
-
-    @Override
-    public void prepareJavaParse(@NonNull List<JavaContext> contexts) {
-        
-    }
-
-    @Override
-    public PsiJavaFile parseJavaToPsi(@NonNull JavaContext context) {
-        PsiFile psiFile = IntellijLintUtils.getPsiFile(context);
-        if (!(psiFile instanceof PsiJavaFile)) {
-            return null;
-        }
-        return (PsiJavaFile)psiFile;
-    }
-
-    @Override
-    public JavaEvaluator getEvaluator() {
-        return myEvaluator;
-    }
-
-    @Override
-    public Project getIdeaProject() {
-        return myProject;
-    }
-
-    @Override
-    public Location getRangeLocation(
-            @NonNull JavaContext context, @NonNull Node from, int fromDelta, @NonNull Node to, int toDelta
-    ) {
-        Position position1 = from.getPosition();
-        Position position2 = to.getPosition();
-        if (position1 == null) {
-            return getLocation(context, to);
-        }
-        else if (position2 == null) {
-            return getLocation(context, from);
-        }
-
-        int start = Math.max(0, from.getPosition().getStart() + fromDelta);
-        int end = to.getPosition().getEnd() + toDelta;
-        return Location.create(context.file, null, start, end);
-    }
-
-    @Override
-    public Location.Handle createLocationHandle(@NonNull JavaContext context, @NonNull Node node) {
-        return new LocationHandle(context.file, node);
-    }
-
-    @Override
-    public void runReadAction(@NonNull Runnable runnable) {
-        ApplicationManager.getApplication().runReadAction(runnable);
-    }
-
-    /* Handle for creating positions cheaply and returning full fledged locations later */
-    private class LocationHandle implements Location.Handle {
-        private final File myFile;
-        private final Node myNode;
-        private Object mClientData;
-
-        public LocationHandle(File file, Node node) {
-            myFile = file;
-            myNode = node;
-        }
-
-        @NonNull
-        @Override
-        public Location resolve() {
-            Position pos = myNode.getPosition();
-            if (pos == null) {
-                myClient.log(Severity.WARNING, null, "No position data found for node %1$s", myNode);
-                return Location.create(myFile);
-            }
-            return Location.create(myFile, null /*contents*/, pos.getStart(), pos.getEnd());
-        }
-
-        @Override
-        public void setClientData(@Nullable Object clientData) {
-            mClientData = clientData;
-        }
-
-        @Override
-        @Nullable
-        public Object getClientData() {
-            return mClientData;
-        }
-    }
-    
-    private static class MyJavaEvaluator extends JavaEvaluator {
-        private final Project myProject;
-
-        public MyJavaEvaluator(Project project) {
-            myProject = project;
-        }
-
-        @Nullable
-        @Override
-        public PsiClass findClass(@NonNull String qualifiedName) {
-            return JavaPsiFacade.getInstance(myProject).findClass(qualifiedName, GlobalSearchScope.allScope(myProject));
-        }
-
-        @Nullable
-        @Override
-        public PsiClassType getClassType(@Nullable PsiClass cls) {
-            return cls != null ? JavaPsiFacade.getElementFactory(myProject).createType(cls) : null;
-        }
-
-        @NonNull
-        @Override
-        public PsiAnnotation[] getAllAnnotations(@NonNull PsiModifierListOwner owner) {
-            return AnnotationUtil.getAllAnnotations(owner, true, null, true);
-        }
-
-        @Nullable
-        @Override
-        public PsiAnnotation findAnnotationInHierarchy(@NonNull PsiModifierListOwner listOwner, @NonNull String... annotationNames) {
-            return AnnotationUtil.findAnnotationInHierarchy(listOwner, Sets.newHashSet(annotationNames));
-        }
-
-        @Nullable
-        @Override
-        public PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, @NonNull String... annotationNames) {
-            return AnnotationUtil.findAnnotation(listOwner, false, annotationNames);
-        }
-
-        @Nullable
-        @Override
-        public File getFile(@NonNull PsiFile file) {
-            VirtualFile virtualFile = file.getVirtualFile();
-            return virtualFile != null ? VfsUtilCore.virtualToIoFile(virtualFile) : null;
-        }
-    }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java
deleted file mode 100644
index e01191c..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java
+++ /dev/null
@@ -1,867 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.builder.model.AndroidProject;
-import com.android.builder.model.LintOptions;
-import com.android.ide.common.repository.ResourceVisibilityLookup;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceFile;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.sdklib.repository.AndroidSdkHandler;
-import com.android.tools.idea.project.AndroidProjectInfo;
-import com.android.tools.idea.res.AppResourceRepository;
-import com.android.tools.idea.res.LocalResourceRepository;
-import com.android.tools.idea.res.ModuleResourceRepository;
-import com.android.tools.idea.res.ProjectResourceRepository;
-import com.android.tools.idea.sdk.IdeSdks;
-import com.android.tools.klint.checks.ApiLookup;
-import com.android.tools.klint.client.api.*;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-import com.intellij.analysis.AnalysisScope;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.DocumentListener;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
-import com.intellij.psi.xml.XmlElement;
-import com.intellij.psi.xml.XmlTag;
-import com.intellij.util.PathUtil;
-import com.intellij.util.containers.HashMap;
-import com.intellij.util.lang.UrlClassLoader;
-import com.intellij.util.net.HttpConfigurable;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.android.facet.AndroidRootUtil;
-import org.jetbrains.android.sdk.AndroidSdkData;
-import org.jetbrains.android.sdk.AndroidSdkType;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.tools.klint.detector.api.TextFormat.RAW;
-import static org.jetbrains.android.inspections.klint.IntellijLintIssueRegistry.CUSTOM_ERROR;
-import static org.jetbrains.android.inspections.klint.IntellijLintIssueRegistry.CUSTOM_WARNING;
-
-/**
- * Implementation of the {@linkplain LintClient} API for executing lint within the IDE:
- * reading files, reporting issues, logging errors, etc.
- */
-public class IntellijLintClient extends LintClient implements Disposable {
-  protected static final Logger LOG = Logger.getInstance("#org.jetbrains.android.inspections.IntellijLintClient");
-
-  @NonNull protected Project myProject;
-  @Nullable protected Map<com.android.tools.klint.detector.api.Project, Module> myModuleMap;
-
-  public IntellijLintClient(@NonNull Project project) {
-    super(CLIENT_STUDIO);
-    myProject = project;
-  }
-
-  /** Creates a lint client for batch inspections */
-  public static IntellijLintClient forBatch(@NotNull Project project,
-                                            @NotNull Map<Issue, Map<File, List<ProblemData>>> problemMap,
-                                            @NotNull AnalysisScope scope,
-                                            @NotNull List<Issue> issues) {
-    return new BatchLintClient(project, problemMap, scope, issues);
-  }
-
-  /**
-   * Returns an {@link ApiLookup} service.
-   *
-   * @param project the project to use for locating the Android SDK
-   * @return an API lookup if one can be found
-   */
-  @Nullable
-  public static ApiLookup getApiLookup(@NotNull Project project) {
-    return ApiLookup.get(new IntellijLintClient(project));
-  }
-
-  /**
-   * Creates a lint client used for in-editor single file lint analysis (e.g. background checking while user is editing.)
-   */
-  public static IntellijLintClient forEditor(@NotNull State state) {
-    return new EditorLintClient(state);
-  }
-
-  @Nullable
-  protected Module findModuleForLintProject(@NotNull Project project,
-                                            @NotNull com.android.tools.klint.detector.api.Project lintProject) {
-    if (myModuleMap != null) {
-      Module module = myModuleMap.get(lintProject);
-      if (module != null) {
-        return module;
-      }
-    }
-    final File dir = lintProject.getDir();
-    final VirtualFile vDir = LocalFileSystem.getInstance().findFileByIoFile(dir);
-    return vDir != null ? ModuleUtilCore.findModuleForFile(vDir, project) : null;
-  }
-
-  void setModuleMap(@Nullable Map<com.android.tools.klint.detector.api.Project, Module> moduleMap) {
-    myModuleMap = moduleMap;
-  }
-
-  @NonNull
-  @Override
-  public Configuration getConfiguration(@NonNull com.android.tools.klint.detector.api.Project project, @Nullable final LintDriver driver) {
-    if (project.isGradleProject() && project.isAndroidProject() && !project.isLibrary()) {
-      AndroidProject model = project.getGradleProjectModel();
-      if (model != null) {
-        try {
-          LintOptions lintOptions = model.getLintOptions();
-          final Map<String, Integer> overrides = lintOptions.getSeverityOverrides();
-          if (overrides != null && !overrides.isEmpty()) {
-            return new DefaultConfiguration(this, project, null) {
-              @NonNull
-              @Override
-              public Severity getSeverity(@NonNull Issue issue) {
-                Integer severity = overrides.get(issue.getId());
-                if (severity != null) {
-                  switch (severity.intValue()) {
-                    case LintOptions.SEVERITY_FATAL:
-                      return Severity.FATAL;
-                    case LintOptions.SEVERITY_ERROR:
-                      return Severity.ERROR;
-                    case LintOptions.SEVERITY_WARNING:
-                      return Severity.WARNING;
-                    case LintOptions.SEVERITY_INFORMATIONAL:
-                      return Severity.INFORMATIONAL;
-                    case LintOptions.SEVERITY_IGNORE:
-                    default:
-                      return Severity.IGNORE;
-                  }
-                }
-
-                // This is a LIST lookup. I should make this faster!
-                if (!getIssues().contains(issue) && (driver == null || !driver.isCustomIssue(issue))) {
-                  return Severity.IGNORE;
-                }
-
-                return super.getSeverity(issue);
-              }
-            };
-          }
-        } catch (Exception e) {
-          LOG.error(e);
-        }
-      }
-    }
-    return new DefaultConfiguration(this, project, null) {
-      @Override
-      public boolean isEnabled(@NonNull Issue issue) {
-        if (getIssues().contains(issue) && super.isEnabled(issue)) {
-          return true;
-        }
-
-        return driver != null && driver.isCustomIssue(issue);
-      }
-    };
-  }
-
-  @Override
-  public void report(@NonNull Context context,
-                     @NonNull Issue issue,
-                     @NonNull Severity severity,
-                     @NonNull Location location,
-                     @NonNull String message,
-                     @NonNull TextFormat format) {
-    assert false : message;
-  }
-
-  @NonNull protected List<Issue> getIssues() {
-    return Collections.emptyList();
-  }
-
-  @Nullable
-  protected Module getModule() {
-    return null;
-  }
-
-  /**
-   * Recursively calls {@link #report} on the secondary location of this error, if any, which in turn may call it on a third
-   * linked location, and so on.This is necessary since IntelliJ problems don't have secondary locations; instead, we create one
-   * problem for each location associated with the lint error.
-   */
-  protected void reportSecondary(@NonNull Context context, @NonNull Issue issue, @NonNull Severity severity, @NonNull Location location,
-                                 @NonNull String message, @NonNull TextFormat format) {
-    Location secondary = location.getSecondary();
-    if (secondary != null) {
-      if (secondary.getMessage() != null) {
-        message = message + " (" + secondary.getMessage() + ")";
-      }
-      report(context, issue, severity, secondary, message, format);
-    }
-  }
-
-  @Override
-  public void log(@NonNull Severity severity, @Nullable Throwable exception, @Nullable String format, @Nullable Object... args) {
-    if (severity == Severity.ERROR || severity == Severity.FATAL) {
-      if (format != null) {
-        LOG.error(String.format(format, args), exception);
-      } else if (exception != null) {
-        LOG.error(exception);
-      }
-    } else if (severity == Severity.WARNING) {
-      if (format != null) {
-        LOG.warn(String.format(format, args), exception);
-      } else if (exception != null) {
-        LOG.warn(exception);
-      }
-    } else {
-      if (format != null) {
-        LOG.info(String.format(format, args), exception);
-      } else if (exception != null) {
-        LOG.info(exception);
-      }
-    }
-  }
-
-  @Override
-  public XmlParser getXmlParser() {
-    return new DomPsiParser(this);
-  }
-
-  @Nullable
-  @Override
-  public JavaParser getJavaParser(@Nullable com.android.tools.klint.detector.api.Project project) {
-    return new IdeaJavaParser(this, myProject);
-  }
-
-  @NonNull
-  @Override
-  public List<File> getJavaClassFolders(@NonNull com.android.tools.klint.detector.api.Project project) {
-    // todo: implement when class files checking detectors will be available
-    return Collections.emptyList();
-  }
-
-  @NonNull
-  @Override
-  public List<File> getJavaLibraries(@NonNull com.android.tools.klint.detector.api.Project project, boolean includeProvided) {
-    // todo: implement
-    return Collections.emptyList();
-  }
-
-  @Override
-  @NonNull
-  public String readFile(@NonNull final File file) {
-    final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-    if (vFile == null) {
-      LOG.debug("Cannot find file " + file.getPath() + " in the VFS");
-      return "";
-    }
-
-    return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
-      @Nullable
-      @Override
-      public String compute() {
-        final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile);
-        if (psiFile == null) {
-          LOG.info("Cannot find file " + file.getPath() + " in the PSI");
-          return null;
-        }
-        else {
-          return psiFile.getText();
-        }
-      }
-    });
-  }
-
-  @Override
-  public void dispose() {
-  }
-
-  @Nullable
-  @Override
-  public File getSdkHome() {
-    Module module = getModule();
-    if (module != null) {
-      Sdk moduleSdk = ModuleRootManager.getInstance(module).getSdk();
-      if (moduleSdk != null && moduleSdk.getSdkType() instanceof AndroidSdkType) {
-        String path = moduleSdk.getHomePath();
-        if (path != null) {
-          File home = new File(path);
-          if (home.exists()) {
-            return home;
-          }
-        }
-      }
-    }
-
-    File sdkHome = super.getSdkHome();
-    if (sdkHome != null) {
-      return sdkHome;
-    }
-
-    for (Module m : ModuleManager.getInstance(myProject).getModules()) {
-      Sdk moduleSdk = ModuleRootManager.getInstance(m).getSdk();
-      if (moduleSdk != null) {
-        if (moduleSdk.getSdkType() instanceof AndroidSdkType) {
-          String path = moduleSdk.getHomePath();
-          if (path != null) {
-            File home = new File(path);
-            if (home.exists()) {
-              return home;
-            }
-          }
-        }
-      }
-    }
-
-    return IdeSdks.getInstance().getAndroidSdkPath();
-  }
-
-  @Nullable
-  @Override
-  public AndroidSdkHandler getSdk() {
-    if (mSdk == null) {
-      Module module = getModule();
-      AndroidSdkHandler sdk = getLocalSdk(module);
-      if (sdk != null) {
-        mSdk = sdk;
-      } else {
-        for (Module m : ModuleManager.getInstance(myProject).getModules()) {
-          sdk = getLocalSdk(m);
-          if (sdk != null) {
-            mSdk = sdk;
-            break;
-          }
-        }
-
-        if (mSdk == null) {
-          mSdk = super.getSdk();
-        }
-      }
-    }
-
-    return mSdk;
-  }
-
-  @Nullable
-  private static AndroidSdkHandler getLocalSdk(@Nullable Module module) {
-    if (module != null) {
-      AndroidFacet facet = AndroidFacet.getInstance(module);
-      if (facet != null) {
-        AndroidSdkData sdkData = AndroidSdkData.getSdkData(facet);   // AS24 AndroidSdkData.getSdkData()
-        if (sdkData != null) {
-          return sdkData.getSdkHandler();
-        }
-      }
-    }
-
-    return null;
-  }
-
-  @Override
-  public boolean isGradleProject(com.android.tools.klint.detector.api.Project project) {
-    Module module = getModule();
-    if (module != null) {
-      AndroidFacet facet = AndroidFacet.getInstance(module);
-      return facet != null && facet.requiresAndroidModel();
-    }
-    return AndroidProjectInfo.getInstance(this.myProject).requiresAndroidModel();
-  }
-
-  // Overridden such that lint doesn't complain about missing a bin dir property in the event
-  // that no SDK is configured
-  @Override
-  @Nullable
-  public File findResource(@NonNull String relativePath) {
-    File top = getSdkHome();
-    if (top != null) {
-      File file = new File(top, relativePath);
-      if (file.exists()) {
-        return file;
-      }
-    }
-
-    return null;
-  }
-
-  @Nullable private static volatile String ourSystemPath;
-
-  @Override
-  @Nullable
-  public File getCacheDir(boolean create) {
-    final String path = ourSystemPath != null ? ourSystemPath : (ourSystemPath = PathUtil.getCanonicalPath(PathManager.getSystemPath()));
-    File lint = new File(path, "lint");
-    if (create && !lint.exists()) {
-      lint.mkdirs();
-    }
-    return lint;
-  }
-
-  @Override
-  public boolean isProjectDirectory(@NonNull File dir) {
-    return new File(dir, Project.DIRECTORY_STORE_FOLDER).exists();
-  }
-
-  private static List<Issue> ourReportedCustomIssues;
-
-  private static void recordCustomIssue(@NonNull Issue issue) {
-    if (ourReportedCustomIssues == null) {
-      ourReportedCustomIssues = Lists.newArrayList();
-    } else if (ourReportedCustomIssues.contains(issue)) {
-      return;
-    }
-    ourReportedCustomIssues.add(issue);
-  }
-
-  @Nullable
-  public static Issue findCustomIssue(@NonNull String errorMessage) {
-    if (ourReportedCustomIssues != null) {
-      // We stash the original id into the error message such that we can
-      // find it later
-      int begin = errorMessage.lastIndexOf('[');
-      int end = errorMessage.lastIndexOf(']');
-      if (begin < end && begin != -1) {
-        String id = errorMessage.substring(begin + 1, end);
-        for (Issue issue : ourReportedCustomIssues) {
-          if (id.equals(issue.getId())) {
-            return issue;
-          }
-        }
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * A lint client used for in-editor single file lint analysis (e.g. background checking while user is editing.)
-   * <p>
-   * Since this applies only to a given file and module, it can take some shortcuts over what the general
-   * {@link BatchLintClient} has to do.
-   * */
-  private static class EditorLintClient extends IntellijLintClient {
-    private final State myState;
-
-    public EditorLintClient(@NotNull State state) {
-      super(state.getModule().getProject());
-      myState = state;
-    }
-
-    @Nullable
-    @Override
-    protected Module getModule() {
-      return myState.getModule();
-    }
-
-    @NonNull
-    @Override
-    protected List<Issue> getIssues() {
-      return myState.getIssues();
-    }
-
-    @Override
-    public void report(@NonNull Context context,
-                       @NonNull Issue issue,
-                       @NonNull Severity severity,
-                       @NonNull Location location,
-                       @NonNull String message,
-                       @NonNull TextFormat format) {
-      if (location != null) {
-        final File file = location.getFile();
-        final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-
-        if (context.getDriver().isCustomIssue(issue)) {
-          // Record original issue id in the message (such that we can find
-          // it later, in #findCustomIssue)
-          message += " [" + issue.getId() + "]";
-          recordCustomIssue(issue);
-          issue = Severity.WARNING.compareTo(severity) <= 0 ? CUSTOM_WARNING : CUSTOM_ERROR;
-        }
-
-        if (myState.getMainFile().equals(vFile)) {
-          final Position start = location.getStart();
-          final Position end = location.getEnd();
-
-          final TextRange textRange = start != null && end != null && start.getOffset() <= end.getOffset()
-                                      ? new TextRange(start.getOffset(), end.getOffset())
-                                      : TextRange.EMPTY_RANGE;
-
-          Severity configuredSeverity = severity != issue.getDefaultSeverity() ? severity : null;
-          message = format.convertTo(message, RAW);
-          myState.getProblems().add(new ProblemData(issue, message, textRange, configuredSeverity));
-        }
-
-        Location secondary = location.getSecondary();
-        if (secondary != null && myState.getMainFile().equals(LocalFileSystem.getInstance().findFileByIoFile(secondary.getFile()))) {
-          reportSecondary(context, issue, severity, location, message, format);
-        }
-      }
-    }
-
-    @Override
-    @NotNull
-    public String readFile(@NonNull File file) {
-      final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-
-      if (vFile == null) {
-        try {
-          return Files.toString(file, Charsets.UTF_8);
-        } catch (IOException ioe) {
-          LOG.debug("Cannot find file " + file.getPath() + " in the VFS");
-          return "";
-        }
-      }
-      final String content = getFileContent(vFile);
-
-      if (content == null) {
-        LOG.info("Cannot find file " + file.getPath() + " in the PSI");
-        return "";
-      }
-      return content;
-    }
-
-    @Nullable
-    private String getFileContent(final VirtualFile vFile) {
-      if (Comparing.equal(myState.getMainFile(), vFile)) {
-        return myState.getMainFileContent();
-      }
-
-      return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
-        @Nullable
-        @Override
-        public String compute() {
-          final Module module = myState.getModule();
-          final Project project = module.getProject();
-          if (project.isDisposed()) {
-            return null;
-          }
-
-          final PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
-
-          if (psiFile == null) {
-            return null;
-          }
-          final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
-
-          if (document != null) {
-            final DocumentListener listener = new DocumentListener() {
-              @Override
-              public void beforeDocumentChange(DocumentEvent event) {
-              }
-
-              @Override
-              public void documentChanged(DocumentEvent event) {
-                myState.markDirty();
-              }
-            };
-            document.addDocumentListener(listener, EditorLintClient.this);
-          }
-          return psiFile.getText();
-        }
-      });
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaSourceFolders(@NonNull com.android.tools.klint.detector.api.Project project) {
-      final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(myState.getModule()).getSourceRoots(false);
-      final List<File> result = new ArrayList<File>(sourceRoots.length);
-
-      for (VirtualFile root : sourceRoots) {
-        result.add(new File(root.getPath()));
-      }
-      return result;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getResourceFolders(@NonNull com.android.tools.klint.detector.api.Project project) {
-      AndroidFacet facet = AndroidFacet.getInstance(myState.getModule());
-      if (facet != null) {
-        return IntellijLintUtils.getResourceDirectories(facet);
-      }
-      return super.getResourceFolders(project);
-    }
-  }
-
-  /** Lint client used for batch operations */
-  private static class BatchLintClient extends IntellijLintClient {
-    private final Map<Issue, Map<File, List<ProblemData>>> myProblemMap;
-    private final AnalysisScope myScope;
-    private final List<Issue> myIssues;
-
-    public BatchLintClient(@NotNull Project project,
-                           @NotNull Map<Issue, Map<File, List<ProblemData>>> problemMap,
-                           @NotNull AnalysisScope scope,
-                           @NotNull List<Issue> issues) {
-      super(project);
-      myProblemMap = problemMap;
-      myScope = scope;
-      myIssues = issues;
-    }
-
-    @Nullable
-    @Override
-    protected Module getModule() {
-      // No default module
-      return null;
-    }
-
-    @NonNull
-    @Override
-    protected List<Issue> getIssues() {
-      return myIssues;
-    }
-
-    @Override
-    public void report(@NonNull Context context,
-                       @NonNull Issue issue,
-                       @NonNull Severity severity,
-                       @NonNull Location location,
-                       @NonNull String message,
-                       @NonNull TextFormat format) {
-      VirtualFile vFile = null;
-      File file = null;
-
-      if (location != null) {
-        file = location.getFile();
-        vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-      }
-      else if (context.getProject() != null) {
-        final Module module = findModuleForLintProject(myProject, context.getProject());
-
-        if (module != null) {
-          final AndroidFacet facet = AndroidFacet.getInstance(module);
-          vFile = facet != null ? AndroidRootUtil.getPrimaryManifestFile(facet) : null;
-
-          if (vFile != null) {
-            file = new File(vFile.getPath());
-          }
-        }
-      }
-
-      boolean inScope = vFile != null && myScope.contains(vFile);
-      // In analysis batch mode, the AnalysisScope contains a specific set of virtual
-      // files, not directories, so any errors reported against a directory will not
-      // be considered part of the scope and therefore won't be reported. Correct
-      // for this.
-      if (!inScope && vFile != null && vFile.isDirectory()) {
-        if (myScope.getScopeType() == AnalysisScope.PROJECT) {
-          inScope = true;
-        } else if (myScope.getScopeType() == AnalysisScope.MODULE ||
-          myScope.getScopeType() == AnalysisScope.MODULES) {
-          final Module module = findModuleForLintProject(myProject, context.getProject());
-          if (module != null && myScope.containsModule(module)) {
-            inScope = true;
-          }
-        }
-      }
-
-      if (inScope) {
-        if (context.getDriver().isCustomIssue(issue)) {
-          // Record original issue id in the message (such that we can find
-          // it later, in #findCustomIssue)
-          message += " [" + issue.getId() + "]";
-          recordCustomIssue(issue);
-          issue = Severity.WARNING.compareTo(severity) <= 0 ? CUSTOM_WARNING : CUSTOM_ERROR;
-        }
-
-        file = new File(PathUtil.getCanonicalPath(file.getPath()));
-
-        Map<File, List<ProblemData>> file2ProblemList = myProblemMap.get(issue);
-        if (file2ProblemList == null) {
-          file2ProblemList = new HashMap<File, List<ProblemData>>();
-          myProblemMap.put(issue, file2ProblemList);
-        }
-
-        List<ProblemData> problemList = file2ProblemList.get(file);
-        if (problemList == null) {
-          problemList = new ArrayList<ProblemData>();
-          file2ProblemList.put(file, problemList);
-        }
-
-        TextRange textRange = TextRange.EMPTY_RANGE;
-
-        if (location != null) {
-          final Position start = location.getStart();
-          final Position end = location.getEnd();
-
-          if (start != null && end != null && start.getOffset() <= end.getOffset()) {
-            textRange = new TextRange(start.getOffset(), end.getOffset());
-          }
-        }
-        Severity configuredSeverity = severity != issue.getDefaultSeverity() ? severity : null;
-        message = format.convertTo(message, RAW);
-        problemList.add(new ProblemData(issue, message, textRange, configuredSeverity));
-
-        if (location != null && location.getSecondary() != null) {
-          reportSecondary(context, issue, severity, location, message, format);
-        }
-      }
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaSourceFolders(@NonNull com.android.tools.klint.detector.api.Project project) {
-      final Module module = findModuleForLintProject(myProject, project);
-      if (module == null) {
-        return Collections.emptyList();
-      }
-      final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(false);
-      final List<File> result = new ArrayList<File>(sourceRoots.length);
-
-      for (VirtualFile root : sourceRoots) {
-        result.add(new File(root.getPath()));
-      }
-      return result;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getResourceFolders(@NonNull com.android.tools.klint.detector.api.Project project) {
-      final Module module = findModuleForLintProject(myProject, project);
-      if (module != null) {
-        AndroidFacet facet = AndroidFacet.getInstance(module);
-        if (facet != null) {
-          return IntellijLintUtils.getResourceDirectories(facet);
-        }
-      }
-      return super.getResourceFolders(project);
-    }
-  }
-
-  @Override
-  public boolean checkForSuppressComments() {
-    return false;
-  }
-
-  @Override
-  public boolean supportsProjectResources() {
-    return true;
-  }
-
-  @Nullable
-  @Override
-  public AbstractResourceRepository getProjectResources(com.android.tools.klint.detector.api.Project project, boolean includeDependencies) {
-    final Module module = findModuleForLintProject(myProject, project);
-    if (module != null) {
-      AndroidFacet facet = AndroidFacet.getInstance(module);
-      if (facet != null) {
-        return includeDependencies
-               ? ProjectResourceRepository.getOrCreateInstance(facet)  // AS24
-               : ModuleResourceRepository.getOrCreateInstance(facet);  // AS24
-      }
-    }
-
-    return null;
-  }
-
-  @Nullable
-  @Override
-  public URLConnection openConnection(@NonNull URL url) throws IOException {
-    return HttpConfigurable.getInstance().openConnection(url.toExternalForm());
-  }
-
-  @Override
-  public ClassLoader createUrlClassLoader(@NonNull URL[] urls, @NonNull ClassLoader parent) {
-    return UrlClassLoader.build().parent(parent).urls(urls).get();
-  }
-
-  @NonNull
-  @Override
-  public Location.Handle createResourceItemHandle(@NonNull ResourceItem item) {
-    XmlTag tag = LocalResourceRepository.getItemTag(myProject, item);
-    if (tag != null) {
-      ResourceFile source = item.getSource();
-      assert source != null : item;
-      return new LocationHandle(source.getFile(), tag);
-    }
-    return super.createResourceItemHandle(item);
-  }
-
-  @NonNull
-  @Override
-  public ResourceVisibilityLookup.Provider getResourceVisibilityProvider() {
-    Module module = getModule();
-    if (module != null) {
-      AppResourceRepository appResources = AppResourceRepository.getOrCreateInstance(module); // AS24
-      if (appResources != null) {
-        ResourceVisibilityLookup.Provider provider = appResources.getResourceVisibilityProvider();
-        if (provider != null) {
-          return provider;
-        }
-      }
-    }
-    return super.getResourceVisibilityProvider();
-  }
-
-  private static class LocationHandle implements Location.Handle, Computable<Location> {
-    private final File myFile;
-    private final XmlElement myNode;
-    private Object myClientData;
-
-    public LocationHandle(File file, XmlElement node) {
-      myFile = file;
-      myNode = node;
-    }
-
-    @NonNull
-    @Override
-    public Location resolve() {
-      if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
-        return ApplicationManager.getApplication().runReadAction(this);
-      }
-      TextRange textRange = myNode.getTextRange();
-
-      // For elements, don't highlight the entire element range; instead, just
-      // highlight the element name
-      if (myNode instanceof XmlTag) {
-        String tag = ((XmlTag)myNode).getName();
-        int index = myNode.getText().indexOf(tag);
-        if (index != -1) {
-          int start = textRange.getStartOffset() + index;
-          textRange = new TextRange(start, start + tag.length());
-        }
-      }
-
-      Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-      Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-      return Location.create(myFile, start, end);
-    }
-
-    @Override
-    public Location compute() {
-      return resolve();
-    }
-
-    @Override
-    public void setClientData(@Nullable Object clientData) {
-      myClientData = clientData;
-    }
-
-    @Override
-    @Nullable
-    public Object getClientData() {
-      return myClientData;
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintIssueRegistry.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintIssueRegistry.java
deleted file mode 100644
index 2a47da6..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintIssueRegistry.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.tools.klint.checks.*;
-import com.android.tools.klint.detector.api.*;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-
-import static org.jetbrains.android.inspections.klint.IntellijLintProject.*;
-
-/**
- * Custom version of the {@link BuiltinIssueRegistry}. This
- * variation will filter the default issues and remove
- * any issues that aren't usable inside IDEA (e.g. they
- * rely on class files), and it will also replace the implementation
- * of some issues with IDEA specific ones.
- */
-public class IntellijLintIssueRegistry extends BuiltinIssueRegistry {
-  private static final Implementation DUMMY_IMPLEMENTATION = new Implementation(Detector.class,
-                                                                                EnumSet.noneOf(Scope.class));
-
-  private static final String CUSTOM_EXPLANATION =
-    "When custom (third-party) lint rules are integrated in the IDE, they are not available as native IDE inspections, " +
-    "so the explanation text (which must be statically registered by a plugin) is not available. As a workaround, run the " +
-    "lint target in Gradle instead; the HTML report will include full explanations.";
-
-  /**
-   * Issue reported by a custom rule (3rd party detector). We need a placeholder issue to reference for inspections, which
-   * have to be registered statically (can't load these on the fly from custom jars the way lint does)
-   */
-  @NonNull
-  public static final Issue CUSTOM_WARNING = Issue.create(
-    "CustomWarning", "Warning from Custom Rule", CUSTOM_EXPLANATION, Category.CORRECTNESS, 5, Severity.WARNING, DUMMY_IMPLEMENTATION);
-
-  @NonNull
-  public static final Issue CUSTOM_ERROR = Issue.create(
-    "CustomError", "Error from Custom Rule", CUSTOM_EXPLANATION, Category.CORRECTNESS, 5, Severity.ERROR, DUMMY_IMPLEMENTATION);
-
-  private static List<Issue> ourFilteredIssues;
-
-  public IntellijLintIssueRegistry() {
-  }
-
-  @NonNull
-  @Override
-  public List<Issue> getIssues() {
-    if (ourFilteredIssues == null) {
-      List<Issue> sIssues = super.getIssues();
-      List<Issue> result = new ArrayList<Issue>(sIssues.size());
-      for (Issue issue : sIssues) {
-        Implementation implementation = issue.getImplementation();
-        EnumSet<Scope> scope = implementation.getScope();
-        Class<? extends Detector> detectorClass = implementation.getDetectorClass();
-        if (detectorClass == ApiDetector.class) {
-          //issue.setImplementation(IntellijApiDetector.IMPLEMENTATION);
-        } else if (detectorClass == ViewTypeDetector.class) {
-          issue.setImplementation(IntellijViewTypeDetector.IMPLEMENTATION);
-        }
-        if (detectorClass == SupportAnnotationDetector.class) {
-          // Handled by the ResourceTypeInspection
-          continue;
-        } else if (scope.contains(Scope.CLASS_FILE) ||
-            scope.contains(Scope.ALL_CLASS_FILES) ||
-            scope.contains(Scope.JAVA_LIBRARIES)) {
-          //noinspection ConstantConditions
-          assert !SUPPORT_CLASS_FILES; // When enabled, adjust this to include class detector based issues
-
-          boolean isOk = false;
-          for (EnumSet<Scope> analysisScope : implementation.getAnalysisScopes()) {
-            if (!analysisScope.contains(Scope.CLASS_FILE) &&
-                !analysisScope.contains(Scope.ALL_CLASS_FILES) &&
-                !analysisScope.contains(Scope.JAVA_LIBRARIES)) {
-              isOk = true;
-              break;
-            }
-          }
-          if (!isOk) {
-            // Skip issue: not included inside the IDE
-            continue;
-          }
-        }
-        result.add(issue);
-      }
-      //noinspection AssignmentToStaticFieldFromInstanceMethod
-      ourFilteredIssues = result;
-    }
-
-    return ourFilteredIssues;
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintProject.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintProject.java
deleted file mode 100644
index b811362..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintProject.java
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.builder.model.*;
-import com.android.sdklib.AndroidTargetHash;
-import com.android.sdklib.AndroidVersion;
-import com.android.tools.idea.gradle.project.model.AndroidModuleModel;
-import com.android.tools.idea.gradle.util.GradleUtil;
-import com.android.tools.idea.model.AndroidModel;
-import com.android.tools.idea.model.AndroidModuleInfo;
-import com.android.tools.klint.client.api.LintClient;
-import com.android.tools.klint.detector.api.Project;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.roots.LibraryOrderEntry;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.OrderEntry;
-import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.graph.Graph;
-import org.jetbrains.android.compiler.AndroidDexCompiler;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.android.facet.AndroidRootUtil;
-import org.jetbrains.android.facet.IdeaSourceProvider;
-import org.jetbrains.android.sdk.AndroidPlatform;
-import org.jetbrains.android.util.AndroidCommonUtils;
-import org.jetbrains.android.util.AndroidUtils;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.android.model.impl.JpsAndroidModuleProperties;
-
-import java.io.File;
-import java.util.*;
-
-import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT;
-import static com.android.SdkConstants.SUPPORT_LIB_ARTIFACT;
-
-/**
- * An {@linkplain IntellijLintProject} represents a lint project, which typically corresponds to a {@link Module},
- * but can also correspond to a library "project" such as an {@link AndroidLibrary}.
- */
-class IntellijLintProject extends Project {
-  /**
-   * Whether we support running .class file checks. No class file checks are currently registered as inspections.
-   * Since IntelliJ doesn't perform background compilation (e.g. only parsing, so there are no bytecode checks)
-   * this might need some work before we enable it.
-   */
-  public static final boolean SUPPORT_CLASS_FILES = false;
-
-  protected AndroidVersion mMinSdkVersion;
-  protected AndroidVersion mTargetSdkVersion;
-
-  IntellijLintProject(@NonNull LintClient client,
-                      @NonNull File dir,
-                      @NonNull File referenceDir) {
-    super(client, dir, referenceDir);
-  }
-
-  /** Creates a set of projects for the given IntelliJ modules */
-  @NonNull
-  public static List<Project> create(@NonNull IntellijLintClient client, @Nullable List<VirtualFile> files, @NonNull Module... modules) {
-    List<Project> projects = Lists.newArrayList();
-
-    Map<Project,Module> projectMap = Maps.newHashMap();
-    Map<Module,Project> moduleMap = Maps.newHashMap();
-    Map<AndroidLibrary,Project> libraryMap = Maps.newHashMap();
-    if (files != null && !files.isEmpty()) {
-      // Wrap list with a mutable list since we'll be removing the files as we see them
-      files = Lists.newArrayList(files);
-    }
-    for (Module module : modules) {
-      addProjects(client, module, files, moduleMap, libraryMap, projectMap, projects);
-    }
-
-    client.setModuleMap(projectMap);
-
-    if (projects.size() > 1) {
-      // Partition the projects up such that we only return projects that aren't
-      // included by other projects (e.g. because they are library projects)
-      Set<Project> roots = new HashSet<Project>(projects);
-      for (Project project : projects) {
-        roots.removeAll(project.getAllLibraries());
-      }
-      return Lists.newArrayList(roots);
-    } else {
-      return projects;
-    }
-  }
-
-  /**
-   * Creates a project for a single file. Also optionally creates a main project for the file, if applicable.
-   *
-   * @param client the lint client
-   * @param file the file to create a project for
-   * @param module the module to create a project for
-   * @return a project for the file, as well as a project (or null) for the main Android module
-   */
-  @NonNull
-  public static Pair<Project,Project> createForSingleFile(@NonNull IntellijLintClient client, @Nullable VirtualFile file, @NonNull Module module) {
-    // TODO: Can make this method even more lightweight: we don't need to initialize anything in the project (source paths etc)
-    // other than the metadata necessary for this file's type
-    LintModuleProject project = createModuleProject(client, module);
-    LintModuleProject main = null;
-    Map<Project,Module> projectMap = Maps.newHashMap();
-    if (project != null) {
-      project.setDirectLibraries(Collections.<Project>emptyList());
-      if (file != null) {
-        project.addFile(VfsUtilCore.virtualToIoFile(file));
-      }
-      projectMap.put(project, module);
-
-      // Supply a main project too, such that when you for example edit a file in a Java library,
-      // and lint asks for getMainProject().getMinSdk(), we return the min SDK of an application
-      // using the library, not "1" (the default for a module without a manifest)
-      if (!project.isAndroidProject()) {
-        Module androidModule = findAndroidModule(module);
-        if (androidModule != null) {
-          main = createModuleProject(client, androidModule);
-          if (main != null) {
-            projectMap.put(main, androidModule);
-            main.setDirectLibraries(Collections.<Project>singletonList(project));
-          }
-        }
-      }
-    }
-    client.setModuleMap(projectMap);
-
-    //noinspection ConstantConditions
-    return Pair.<Project,Project>create(project,main);
-  }
-
-  /** Find an Android module that depends on this module; prefer app modules over library modules */
-  @Nullable
-  private static Module findAndroidModule(@NonNull final Module module) {
-    // Search for dependencies of this module
-    Graph<Module> graph = ApplicationManager.getApplication().runReadAction(new Computable<Graph<Module>>() {
-      @Override
-      public Graph<Module> compute() {
-        com.intellij.openapi.project.Project project = module.getProject();
-        if (project.isDisposed()) {
-          return null;
-        }
-        return ModuleManager.getInstance(project).moduleGraph();
-      }
-    });
-
-    if (graph == null) {
-      return null;
-    }
-
-    Set<AndroidFacet> facets = Sets.newHashSet();
-    HashSet<Module> seen = Sets.newHashSet();
-    seen.add(module);
-    addAndroidModules(facets, seen, graph, module);
-
-    // Prefer Android app modules
-    for (AndroidFacet facet : facets) {
-      if (!facet.isLibraryProject()) {
-        return facet.getModule();
-      }
-    }
-
-    // Resort to library modules if no app module depends directly on it
-    if (!facets.isEmpty()) {
-      return facets.iterator().next().getModule();
-    }
-
-    return null;
-  }
-
-  private static void addAndroidModules(Set<AndroidFacet> androidFacets, Set<Module> seen, Graph<Module> graph, Module module) {
-    Iterator<Module> iterator = graph.getOut(module);
-    while (iterator.hasNext()) {
-      Module dep = iterator.next();
-      AndroidFacet facet = AndroidFacet.getInstance(dep);
-      if (facet != null) {
-        androidFacets.add(facet);
-      }
-
-      if (!seen.contains(dep)) {
-        seen.add(dep);
-        addAndroidModules(androidFacets, seen, graph, dep);
-      }
-    }
-  }
-
-  /**
-   * Recursively add lint projects for the given module, and any other module or library it depends on, and also
-   * populate the reverse maps so we can quickly map from a lint project to a corresponding module/library (used
-   * by the lint client
-   */
-  private static void addProjects(@NonNull LintClient client,
-                                  @NonNull Module module,
-                                  @Nullable List<VirtualFile> files,
-                                  @NonNull Map<Module,Project> moduleMap,
-                                  @NonNull Map<AndroidLibrary, Project> libraryMap,
-                                  @NonNull Map<Project,Module> projectMap,
-                                  @NonNull List<Project> projects) {
-    if (moduleMap.containsKey(module)) {
-      return;
-    }
-
-    LintModuleProject project = createModuleProject(client, module);
-
-    if (project == null) {
-      // It's possible for the module to *depend* on Android code, e.g. in a Gradle
-      // project there will be a top-level non-Android module
-      List<AndroidFacet> dependentFacets = AndroidUtils.getAllAndroidDependencies(module, false);
-      for (AndroidFacet dependentFacet : dependentFacets) {
-        addProjects(client, dependentFacet.getModule(), files, moduleMap, libraryMap, projectMap, projects);
-      }
-      return;
-    }
-
-    projects.add(project);
-    moduleMap.put(module, project);
-    projectMap.put(project, module);
-
-    if (processFileFilter(module, files, project)) {
-      // No need to process dependencies when doing single file analysis
-      return;
-    }
-
-    List<Project> dependencies = Lists.newArrayList();
-    // No, this shouldn't use getAllAndroidDependencies; we may have non-Android dependencies that this won't include
-    // (e.g. Java-only modules)
-    List<AndroidFacet> dependentFacets = AndroidUtils.getAllAndroidDependencies(module, true);
-    for (AndroidFacet dependentFacet : dependentFacets) {
-      Project p = moduleMap.get(dependentFacet.getModule());
-      if (p != null) {
-        dependencies.add(p);
-      } else {
-        addProjects(client, dependentFacet.getModule(), files, moduleMap, libraryMap, projectMap, dependencies);
-      }
-    }
-
-    AndroidFacet facet = AndroidFacet.getInstance(module);
-    if (facet != null) {
-      AndroidModuleModel androidModuleModel = AndroidModuleModel.get(facet);
-      if (androidModuleModel != null) {
-        addGradleLibraryProjects(client, files, libraryMap, projects, facet, androidModuleModel, project, projectMap, dependencies);
-      }
-    }
-
-    project.setDirectLibraries(dependencies);
-  }
-
-  /**
-   * Checks whether we have a file filter (e.g. a set of specific files to check in the module rather than all files,
-   * and if so, and if all the files have been found, returns true)
-   */
-  private static boolean processFileFilter(@NonNull Module module, @Nullable List<VirtualFile> files, @NonNull LintModuleProject project) {
-    if (files != null && !files.isEmpty()) {
-      ListIterator<VirtualFile> iterator = files.listIterator();
-      while (iterator.hasNext()) {
-        VirtualFile file = iterator.next();
-        if (module.getModuleContentScope().accept(file)) {
-          project.addFile(VfsUtilCore.virtualToIoFile(file));
-          iterator.remove();
-        }
-      }
-      if (files.isEmpty()) {
-        // We're only scanning a subset of files (typically the current file in the editor);
-        // in that case, don't initialize all the libraries etc
-        project.setDirectLibraries(Collections.<Project>emptyList());
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /** Creates a new module project */
-  @Nullable
-  private static LintModuleProject createModuleProject(@NonNull LintClient client, @NonNull Module module) {
-    AndroidFacet facet = AndroidFacet.getInstance(module);
-    File dir;
-
-    if (facet != null) {
-      final VirtualFile mainContentRoot = AndroidRootUtil.getMainContentRoot(facet);
-
-      if (mainContentRoot == null) {
-        return null;
-      }
-      dir = new File(FileUtil.toSystemDependentName(mainContentRoot.getPath()));
-    } else {
-      String moduleDirPath = AndroidRootUtil.getModuleDirPath(module);
-      if (moduleDirPath == null) {
-        return null;
-      }
-      dir = new File(FileUtil.toSystemDependentName(moduleDirPath));
-    }
-    LintModuleProject project = null;
-    if (facet == null) {
-      project = new LintModuleProject(client, dir, dir, module);
-      AndroidFacet f = findAndroidFacetInProject(module.getProject());
-      if (f != null) {
-        project.mGradleProject = f.requiresAndroidModel();
-      }
-    }
-    else if (facet.requiresAndroidModel()) {
-      AndroidModel androidModel = facet.getAndroidModel();
-      if (androidModel instanceof AndroidModuleModel) {
-        project = new LintGradleProject(client, dir, dir, facet, (AndroidModuleModel)androidModel);
-      } else {
-        project = new LintAndroidModelProject(client, dir, dir, facet, androidModel);
-      }
-    }
-    else {
-      project = new LintAndroidProject(client, dir, dir, facet);
-    }
-    if (project != null) {
-      client.registerProject(dir, project);
-    }
-    return project;
-  }
-
-  public static boolean hasAndroidModule(@NonNull com.intellij.openapi.project.Project project) {
-    return findAndroidFacetInProject(project) != null;
-  }
-
-  @Nullable
-  private static AndroidFacet findAndroidFacetInProject(@NonNull com.intellij.openapi.project.Project project) {
-    ModuleManager moduleManager = ModuleManager.getInstance(project);
-    for (Module module : moduleManager.getModules()) {
-      AndroidFacet facet = AndroidFacet.getInstance(module);
-      if (facet != null) {
-        return facet;
-      }
-    }
-
-    return null;
-  }
-
-  /** Adds any gradle library projects to the dependency list */
-  private static void addGradleLibraryProjects(@NonNull LintClient client,
-                                               @Nullable List<VirtualFile> files,
-                                               @NonNull Map<AndroidLibrary, Project> libraryMap,
-                                               @NonNull List<Project> projects,
-                                               @NonNull AndroidFacet facet,
-                                               @NonNull AndroidModuleModel AndroidModuleModel,
-                                               @NonNull LintModuleProject project,
-                                               @NonNull Map<Project,Module> projectMap,
-                                               @NonNull List<Project> dependencies) {
-    Collection<AndroidLibrary> libraries = AndroidModuleModel.getMainArtifact().getDependencies().getLibraries();
-    for (AndroidLibrary library : libraries) {
-      Project p = libraryMap.get(library);
-      if (p == null) {
-        File dir = library.getFolder();
-        p = new LintGradleLibraryProject(client, dir, dir, library);
-        libraryMap.put(library, p);
-        projectMap.put(p, facet.getModule());
-        projects.add(p);
-
-        if (files != null) {
-          VirtualFile libraryDir = LocalFileSystem.getInstance().findFileByIoFile(dir);
-          if (libraryDir != null) {
-            ListIterator<VirtualFile> iterator = files.listIterator();
-            while (iterator.hasNext()) {
-              VirtualFile file = iterator.next();
-              if (VfsUtilCore.isAncestor(libraryDir, file, false)) {
-                project.addFile(VfsUtilCore.virtualToIoFile(file));
-                iterator.remove();
-              }
-            }
-          }
-          if (files.isEmpty()) {
-            files = null; // No more work in other modules
-          }
-        }
-      }
-      dependencies.add(p);
-    }
-  }
-
-  @Override
-  protected void initialize() {
-    // NOT calling super: super performs ADT/ant initialization. Here we want to use
-    // the gradle data instead
-  }
-
-  protected static boolean depsDependsOn(@NonNull Project project, @NonNull String artifact) {
-    // Checks project dependencies only; used when there is no model
-    for (Project dependency : project.getDirectLibraries()) {
-      Boolean b = dependency.dependsOn(artifact);
-      if (b != null && b) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  private static class LintModuleProject extends IntellijLintProject {
-    private Module myModule;
-
-    public void setDirectLibraries(List<Project> libraries) {
-      mDirectLibraries = libraries;
-    }
-
-    private LintModuleProject(@NonNull LintClient client, @NonNull File dir, @NonNull File referenceDir, Module module) {
-      super(client, dir, referenceDir);
-      myModule = module;
-    }
-
-    @Override
-    public boolean isAndroidProject() {
-      return false;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaSourceFolders() {
-      if (mJavaSourceFolders == null) {
-        VirtualFile[] sourceRoots = ModuleRootManager.getInstance(myModule).getSourceRoots(false);
-        List<File> dirs = new ArrayList<File>(sourceRoots.length);
-        for (VirtualFile root : sourceRoots) {
-          dirs.add(new File(root.getPath()));
-        }
-        mJavaSourceFolders = dirs;
-      }
-
-      return mJavaSourceFolders;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getTestSourceFolders() {
-      if (mTestSourceFolders == null) {
-        ModuleRootManager manager = ModuleRootManager.getInstance(myModule);
-        VirtualFile[] sourceRoots = manager.getSourceRoots(false);
-        VirtualFile[] sourceAndTestRoots = manager.getSourceRoots(true);
-        List<File> dirs = new ArrayList<File>(sourceAndTestRoots.length);
-        for (VirtualFile root : sourceAndTestRoots) {
-          if (!ArrayUtil.contains(root, sourceRoots)) {
-            dirs.add(new File(root.getPath()));
-          }
-        }
-        mTestSourceFolders = dirs;
-      }
-      return mTestSourceFolders;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaClassFolders() {
-      if (SUPPORT_CLASS_FILES) {
-        if (mJavaClassFolders == null) {
-          VirtualFile folder = AndroidDexCompiler.getOutputDirectoryForDex(myModule);
-          if (folder != null) {
-            mJavaClassFolders = Collections.singletonList(VfsUtilCore.virtualToIoFile(folder));
-          } else {
-            mJavaClassFolders = Collections.emptyList();
-          }
-        }
-
-        return mJavaClassFolders;
-      }
-
-      return Collections.emptyList();
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaLibraries(boolean includeProvided) {
-      if (SUPPORT_CLASS_FILES) {
-        if (mJavaLibraries == null) {
-          mJavaLibraries = Lists.newArrayList();
-
-          final OrderEntry[] entries = ModuleRootManager.getInstance(myModule).getOrderEntries();
-          // loop in the inverse order to resolve dependencies on the libraries, so that if a library
-          // is required by two higher level libraries it can be inserted in the correct place
-
-          for (int i = entries.length - 1; i >= 0; i--) {
-            final OrderEntry orderEntry = entries[i];
-            if (orderEntry instanceof LibraryOrderEntry) {
-              LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
-              VirtualFile[] classes = libraryOrderEntry.getRootFiles(OrderRootType.CLASSES);
-              if (classes != null) {
-                for (VirtualFile file : classes) {
-                  mJavaLibraries.add(VfsUtilCore.virtualToIoFile(file));
-                }
-              }
-            }
-          }
-        }
-
-        return mJavaLibraries;
-      }
-
-      return Collections.emptyList();
-    }
-  }
-
-  /** Wraps an Android module */
-  private static class LintAndroidProject extends LintModuleProject {
-    protected final AndroidFacet myFacet;
-
-    private LintAndroidProject(@NonNull LintClient client, @NonNull File dir, @NonNull File referenceDir, @NonNull AndroidFacet facet) {
-      super(client, dir, referenceDir, facet.getModule());
-      myFacet = facet;
-
-      mGradleProject = false;
-      mLibrary = myFacet.isLibraryProject();
-
-      AndroidPlatform platform = AndroidPlatform.getInstance(myFacet.getModule());
-      if (platform != null) {
-        mBuildSdk = platform.getApiLevel();
-      }
-    }
-
-    @Override
-    public boolean isAndroidProject() {
-      return true;
-    }
-
-    @NonNull
-    @Override
-    public String getName() {
-      return myFacet.getModule().getName();
-    }
-
-    @Override
-    @NonNull
-    public List<File> getManifestFiles() {
-      if (mManifestFiles == null) {
-        VirtualFile manifestFile = AndroidRootUtil.getPrimaryManifestFile(myFacet);
-        if (manifestFile != null) {
-          mManifestFiles = Collections.singletonList(VfsUtilCore.virtualToIoFile(manifestFile));
-        } else {
-          mManifestFiles = Collections.emptyList();
-        }
-      }
-
-      return mManifestFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getProguardFiles() {
-      if (mProguardFiles == null) {
-        final JpsAndroidModuleProperties properties = myFacet.getProperties();
-
-        if (properties.RUN_PROGUARD) {
-          final List<String> urls = properties.myProGuardCfgFiles;
-
-          if (!urls.isEmpty()) {
-            mProguardFiles = new ArrayList<File>();
-
-            for (String osPath : AndroidUtils.urlsToOsPaths(urls, null)) {
-              if (!osPath.contains(AndroidCommonUtils.SDK_HOME_MACRO)) {
-                mProguardFiles.add(new File(osPath));
-              }
-            }
-          }
-        }
-
-        if (mProguardFiles == null) {
-          mProguardFiles = Collections.emptyList();
-        }
-      }
-
-      return mProguardFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getResourceFolders() {
-      if (mResourceFolders == null) {
-        List<VirtualFile> folders = myFacet.getResourceFolderManager().getFolders();
-        List<File> dirs = Lists.newArrayListWithExpectedSize(folders.size());
-        for (VirtualFile folder : folders) {
-          dirs.add(VfsUtilCore.virtualToIoFile(folder));
-        }
-        mResourceFolders = dirs;
-      }
-
-      return mResourceFolders;
-    }
-
-    @Nullable
-    @Override
-    public Boolean dependsOn(@NonNull String artifact) {
-      if (SUPPORT_LIB_ARTIFACT.equals(artifact)) {
-        if (mSupportLib == null) {
-          final OrderEntry[] entries = ModuleRootManager.getInstance(myFacet.getModule()).getOrderEntries();
-          libraries:
-          for (int i = entries.length - 1; i >= 0; i--) {
-            final OrderEntry orderEntry = entries[i];
-            if (orderEntry instanceof LibraryOrderEntry) {
-              LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
-              VirtualFile[] classes = libraryOrderEntry.getRootFiles(OrderRootType.CLASSES);
-              if (classes != null) {
-                for (VirtualFile file : classes) {
-                  if (file.getName().equals("android-support-v4.jar")) {
-                    mSupportLib = true;
-                    break libraries;
-
-                  }
-                }
-              }
-            }
-          }
-          if (mSupportLib == null) {
-            mSupportLib = depsDependsOn(this, artifact);
-          }
-        }
-        return mSupportLib;
-      } else if (APPCOMPAT_LIB_ARTIFACT.equals(artifact)) {
-        if (mSupportLib == null) {
-          final OrderEntry[] entries = ModuleRootManager.getInstance(myFacet.getModule()).getOrderEntries();
-          libraries:
-          for (int i = entries.length - 1; i >= 0; i--) {
-            final OrderEntry orderEntry = entries[i];
-            if (orderEntry instanceof LibraryOrderEntry) {
-              LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
-              VirtualFile[] classes = libraryOrderEntry.getRootFiles(OrderRootType.CLASSES);
-              if (classes != null) {
-                for (VirtualFile file : classes) {
-                  if (file.getName().equals("appcompat-v7.jar")) {
-                    mSupportLib = true;
-                    break libraries;
-
-                  }
-                }
-              }
-            }
-          }
-          if (mSupportLib == null) {
-            mSupportLib = depsDependsOn(this, artifact);
-          }
-        }
-        return mSupportLib;
-      } else {
-        return super.dependsOn(artifact);
-      }
-    }
-  }
-
-  private static class LintAndroidModelProject extends LintAndroidProject {
-    private final AndroidModel myAndroidModel;
-
-    private LintAndroidModelProject(
-      @NonNull LintClient client,
-      @NonNull File dir,
-      @NonNull File referenceDir,
-      @NonNull AndroidFacet facet,
-      @NonNull AndroidModel androidModel) {
-      super(client, dir, referenceDir, facet);
-      myAndroidModel = androidModel;
-    }
-
-    @Nullable
-    @Override
-    public String getPackage() {
-      String manifestPackage = super.getPackage();
-      // For now, lint only needs the manifest package; not the potentially variant specific
-      // package. As part of the Gradle work on the Lint API we should make two separate
-      // package lookup methods -- one for the manifest package, one for the build package
-      if (manifestPackage != null) {
-        return manifestPackage;
-      }
-
-      return myAndroidModel.getApplicationId();
-    }
-
-    @NonNull
-    @Override
-    public AndroidVersion getMinSdkVersion() {
-      if (mMinSdkVersion == null) {
-        mMinSdkVersion = AndroidModuleInfo.getInstance(myFacet).getMinSdkVersion();   // AS24 getInstance()
-      }
-      return mMinSdkVersion;
-    }
-
-    @NonNull
-    @Override
-    public AndroidVersion getTargetSdkVersion() {
-      if (mTargetSdkVersion == null) {
-        mTargetSdkVersion = AndroidModuleInfo.getInstance(myFacet).getTargetSdkVersion();  // AS24 getInstance()
-      }
-
-      return mTargetSdkVersion;
-    }
-  }
-
-  private static class LintGradleProject extends LintAndroidModelProject {
-    private final AndroidModuleModel myAndroidModuleModel;
-
-    /**
-     * Creates a new Project. Use one of the factory methods to create.
-     */
-    private LintGradleProject(
-      @NonNull LintClient client,
-      @NonNull File dir,
-      @NonNull File referenceDir,
-      @NonNull AndroidFacet facet,
-      @NonNull AndroidModuleModel AndroidModuleModel) {
-      super(client, dir, referenceDir, facet, AndroidModuleModel);
-      mGradleProject = true;
-      mMergeManifests = true;
-      myAndroidModuleModel = AndroidModuleModel;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getManifestFiles() {
-      if (mManifestFiles == null) {
-        mManifestFiles = Lists.newArrayList();
-        File mainManifest = myFacet.getMainSourceProvider().getManifestFile();
-        if (mainManifest.exists()) {
-          mManifestFiles.add(mainManifest);
-        }
-
-        List<SourceProvider> flavorSourceProviders = myAndroidModuleModel.getFlavorSourceProviders();
-        if (flavorSourceProviders != null) {
-          for (SourceProvider provider : flavorSourceProviders) {
-            File manifestFile = provider.getManifestFile();
-            if (manifestFile.exists()) {
-              mManifestFiles.add(manifestFile);
-            }
-          }
-        }
-
-        SourceProvider multiProvider = myAndroidModuleModel.getMultiFlavorSourceProvider();
-        if (multiProvider != null) {
-          File manifestFile = multiProvider.getManifestFile();
-          if (manifestFile.exists()) {
-            mManifestFiles.add(manifestFile);
-          }
-        }
-
-        SourceProvider buildTypeSourceProvider = myAndroidModuleModel.getBuildTypeSourceProvider();
-        if (buildTypeSourceProvider != null) {
-          File manifestFile = buildTypeSourceProvider.getManifestFile();
-          if (manifestFile.exists()) {
-            mManifestFiles.add(manifestFile);
-          }
-        }
-
-        SourceProvider variantProvider = myAndroidModuleModel.getVariantSourceProvider();
-        if (variantProvider != null) {
-          File manifestFile = variantProvider.getManifestFile();
-          if (manifestFile.exists()) {
-            mManifestFiles.add(manifestFile);
-          }
-        }
-      }
-
-      return mManifestFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getAssetFolders() {
-      if (mAssetFolders == null) {
-        mAssetFolders = Lists.newArrayList();
-        for (SourceProvider provider : IdeaSourceProvider.getAllSourceProviders(myFacet)) {
-          Collection<File> dirs = provider.getAssetsDirectories();
-          for (File dir : dirs) {
-            if (dir.exists()) { // model returns path whether or not it exists
-              mAssetFolders.add(dir);
-            }
-          }
-        }
-      }
-
-      return mAssetFolders;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getProguardFiles() {
-      if (mProguardFiles == null) {
-        if (myFacet.requiresAndroidModel()) {
-          // TODO: b/22928250
-          AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
-          if (androidModel != null) {
-            ProductFlavor flavor = androidModel.getAndroidProject().getDefaultConfig().getProductFlavor();
-            mProguardFiles = Lists.newArrayList();
-            for (File file : flavor.getProguardFiles()) {
-              if (file.exists()) {
-                mProguardFiles.add(file);
-              }
-            }
-            try {
-              for (File file : flavor.getConsumerProguardFiles()) {
-                if (file.exists()) {
-                  mProguardFiles.add(file);
-                }
-              }
-            } catch (Throwable t) {
-              // On some models, this threw
-              //   org.gradle.tooling.model.UnsupportedMethodException: Unsupported method: BaseConfig.getConsumerProguardFiles().
-              // Playing it safe for a while.
-            }
-          }
-        }
-
-        if (mProguardFiles == null) {
-          mProguardFiles = Collections.emptyList();
-        }
-      }
-
-      return mProguardFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaClassFolders() {
-      if (SUPPORT_CLASS_FILES) {
-        if (mJavaClassFolders == null) {
-          // Overridden because we don't synchronize the gradle output directory to
-          // the AndroidDexCompiler settings the way java source roots are mapped into
-          // the module content root settings
-          File dir = myAndroidModuleModel.getMainArtifact().getClassesFolder();
-          if (dir != null) {
-            mJavaClassFolders = Collections.singletonList(dir);
-          } else {
-            mJavaClassFolders = Collections.emptyList();
-          }
-        }
-
-        return mJavaClassFolders;
-      }
-
-      return Collections.emptyList();
-    }
-
-    private static boolean sProvidedAvailable = true;
-
-    @NonNull
-    @Override
-    public List<File> getJavaLibraries(boolean includeProvided) {
-      if (SUPPORT_CLASS_FILES) {
-        if (mJavaLibraries == null) {
-          if (myFacet.requiresAndroidModel() && myFacet.getAndroidModel() != null) {
-            Collection<JavaLibrary> libs = myAndroidModuleModel.getMainArtifact().getDependencies().getJavaLibraries();
-            mJavaLibraries = Lists.newArrayListWithExpectedSize(libs.size());
-            for (JavaLibrary lib : libs) {
-              if (!includeProvided) {
-                if (sProvidedAvailable) {
-                  // Method added in 1.4-rc1; gracefully handle running with
-                  // older plugins
-                  try {
-                    if (lib.isProvided()) {
-                      continue;
-                    }
-                  }
-                  catch (Throwable t) {
-                    //noinspection AssignmentToStaticFieldFromInstanceMethod
-                    sProvidedAvailable = false; // don't try again
-                  }
-                }
-              }
-
-              File jar = lib.getJarFile();
-              if (jar.exists()) {
-                mJavaLibraries.add(jar);
-              }
-            }
-          } else {
-            mJavaLibraries = super.getJavaLibraries(includeProvided);
-          }
-        }
-        return mJavaLibraries;
-      }
-
-      return Collections.emptyList();
-    }
-
-    @Override
-    public int getBuildSdk() {
-      // TODO: b/22928250
-      AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
-      if (androidModel != null) {
-        String compileTarget = androidModel.getAndroidProject().getCompileTarget();
-        AndroidVersion version = AndroidTargetHash.getPlatformVersion(compileTarget);
-        if (version != null) {
-          return version.getFeatureLevel();
-        }
-      }
-
-      AndroidPlatform platform = AndroidPlatform.getInstance(myFacet.getModule());
-      if (platform != null) {
-        return platform.getApiVersion().getFeatureLevel();
-      }
-
-      return super.getBuildSdk();
-    }
-
-    @Nullable
-    @Override
-    public AndroidProject getGradleProjectModel() {
-      // TODO: b/22928250
-      AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
-      if (androidModel != null) {
-        return androidModel.getAndroidProject();
-      }
-
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public Variant getCurrentVariant() {
-      // TODO: b/22928250
-      AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
-      if (androidModel != null) {
-        return androidModel.getSelectedVariant();
-      }
-
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public AndroidLibrary getGradleLibraryModel() {
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public Boolean dependsOn(@NonNull String artifact) {
-      // TODO: b/22928250
-      AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
-
-      if (SUPPORT_LIB_ARTIFACT.equals(artifact)) {
-        if (mSupportLib == null) {
-          if (myFacet.requiresAndroidModel() && myFacet.getAndroidModel() != null) {
-            mSupportLib = GradleUtil.dependsOn(androidModel, artifact);
-          } else {
-            mSupportLib = depsDependsOn(this, artifact);
-          }
-        }
-        return mSupportLib;
-      } else if (APPCOMPAT_LIB_ARTIFACT.equals(artifact)) {
-        if (mAppCompat == null) {
-          if (myFacet.requiresAndroidModel() && myFacet.getAndroidModel() != null) {
-            mAppCompat = GradleUtil.dependsOn(androidModel, artifact);
-          } else {
-            mAppCompat = depsDependsOn(this, artifact);
-          }
-        }
-        return mAppCompat;
-      } else {
-        // Some other (not yet directly cached result)
-        if (myFacet.requiresAndroidModel() && myFacet.getAndroidModel() != null
-           && GradleUtil.dependsOn(androidModel, artifact)) {
-          return true;
-        }
-
-        return super.dependsOn(artifact);
-      }
-    }
-  }
-
-  private static class LintGradleLibraryProject extends IntellijLintProject {
-    private final AndroidLibrary myLibrary;
-
-    private LintGradleLibraryProject(@NonNull LintClient client,
-                                     @NonNull File dir,
-                                     @NonNull File referenceDir,
-                                     @NonNull AndroidLibrary library) {
-      super(client, dir, referenceDir);
-      myLibrary = library;
-
-      mLibrary = true;
-      mMergeManifests = true;
-      mReportIssues = false;
-      mGradleProject = true;
-      mDirectLibraries = Collections.emptyList();
-    }
-
-    @NonNull
-    @Override
-    public List<File> getManifestFiles() {
-      if (mManifestFiles == null) {
-        File manifest = myLibrary.getManifest();
-        if (manifest.exists()) {
-          mManifestFiles = Collections.singletonList(manifest);
-        } else {
-          mManifestFiles = Collections.emptyList();
-        }
-      }
-
-      return mManifestFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getProguardFiles() {
-      if (mProguardFiles == null) {
-        File proguardRules = myLibrary.getProguardRules();
-        if (proguardRules.exists()) {
-          mProguardFiles = Collections.singletonList(proguardRules);
-        } else {
-          mProguardFiles = Collections.emptyList();
-        }
-      }
-
-      return mProguardFiles;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getResourceFolders() {
-      if (mResourceFolders == null) {
-        File folder = myLibrary.getResFolder();
-        if (folder.exists()) {
-          mResourceFolders = Collections.singletonList(folder);
-        } else {
-          mResourceFolders = Collections.emptyList();
-        }
-      }
-
-      return mResourceFolders;
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaSourceFolders() {
-      return Collections.emptyList();
-    }
-
-    @NonNull
-    @Override
-    public List<File> getJavaClassFolders() {
-      return Collections.emptyList();
-    }
-
-    private static boolean sOptionalAvailable = true;
-
-    @NonNull
-    @Override
-    public List<File> getJavaLibraries(boolean includeProvided) {
-      if (SUPPORT_CLASS_FILES) {
-        if (!includeProvided) {
-          if (sOptionalAvailable) {
-            // Method added in 1.4-rc1; gracefully handle running with
-            // older plugins
-            try {
-              if (myLibrary.isOptional()) {
-                return Collections.emptyList();
-              }
-            }
-            catch (Throwable t) {
-              //noinspection AssignmentToStaticFieldFromInstanceMethod
-              sOptionalAvailable = false; // don't try again
-            }
-          }
-        }
-
-        if (mJavaLibraries == null) {
-          mJavaLibraries = Lists.newArrayList();
-          File jarFile = myLibrary.getJarFile();
-          if (jarFile.exists()) {
-            mJavaLibraries.add(jarFile);
-          }
-
-          for (File local : myLibrary.getLocalJars()) {
-            if (local.exists()) {
-              mJavaLibraries.add(local);
-            }
-          }
-        }
-
-        return mJavaLibraries;
-      }
-
-      return Collections.emptyList();
-    }
-
-    @Nullable
-    @Override
-    public AndroidProject getGradleProjectModel() {
-      return null;
-    }
-
-    @Nullable
-    @Override
-    public AndroidLibrary getGradleLibraryModel() {
-      return myLibrary;
-    }
-
-    @Nullable
-    @Override
-    public Boolean dependsOn(@NonNull String artifact) {
-      if (SUPPORT_LIB_ARTIFACT.equals(artifact)) {
-        if (mSupportLib == null) {
-          mSupportLib = GradleUtil.dependsOn(myLibrary, artifact, true);
-        }
-        return mSupportLib;
-      } else if (APPCOMPAT_LIB_ARTIFACT.equals(artifact)) {
-        if (mAppCompat == null) {
-          mAppCompat = GradleUtil.dependsOn(myLibrary, artifact, true);
-        }
-        return mAppCompat;
-      } else {
-        // Some other (not yet directly cached result)
-        if (GradleUtil.dependsOn(myLibrary, artifact, true)) {
-          return true;
-        }
-
-        return super.dependsOn(artifact);
-      }
-    }
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintRequest.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintRequest.java
deleted file mode 100644
index 13b340d..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintRequest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.klint.client.api.LintRequest;
-import com.android.tools.klint.detector.api.Scope;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.vfs.VirtualFile;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-
-public class IntellijLintRequest extends LintRequest {
-  @NonNull private final Project myProject;
-  @NonNull private final List<Module> myModules;
-  @NonNull private final IntellijLintClient mLintClient;
-  @Nullable private final List<VirtualFile> myFileList;
-  @Nullable private com.android.tools.klint.detector.api.Project myMainProject;
-  private final boolean myIncremental;
-
-  /**
-   * Creates a new {@linkplain IntellijLintRequest}.
-   * @param client the client
-   * @param project the project where lint is run
-   * @param fileList an optional list of specific files to check, normally null
-   * @param modules the set of modules to be checked (or containing the files)
-   * @param incremental true if this is an incremental (current editor) analysis
-   */
-  public IntellijLintRequest(@NonNull IntellijLintClient client,
-                             @NonNull Project project,
-                             @Nullable List<VirtualFile> fileList,
-                             @NonNull List<Module> modules,
-                             boolean incremental) {
-    super(client, Collections.<File>emptyList());
-    mLintClient = client;
-    myProject = project;
-    myModules = modules;
-    myFileList = fileList;
-    myIncremental = incremental;
-  }
-
-  @NonNull
-  Project getProject() {
-    return myProject;
-  }
-
-  @Nullable
-  @Override
-  public EnumSet<Scope> getScope() {
-    if (mScope == null) {
-      Collection<com.android.tools.klint.detector.api.Project> projects = getProjects();
-      if (projects != null) {
-        mScope = Scope.infer(projects);
-
-        //noinspection ConstantConditions
-        if (!IntellijLintProject.SUPPORT_CLASS_FILES && (mScope.contains(Scope.CLASS_FILE) || mScope.contains(Scope.ALL_CLASS_FILES)
-                                                         || mScope.contains(Scope.JAVA_LIBRARIES))) {
-          mScope = EnumSet.copyOf(mScope); // make mutable
-          // Can't run class file based checks
-          mScope.remove(Scope.CLASS_FILE);
-          mScope.remove(Scope.ALL_CLASS_FILES);
-          mScope.remove(Scope.JAVA_LIBRARIES);
-        }
-      }
-    }
-
-    return mScope;
-  }
-
-  @Nullable
-  @Override
-  public Collection<com.android.tools.klint.detector.api.Project> getProjects() {
-    if (mProjects == null) {
-      if (myIncremental && myFileList != null && myFileList.size() == 1 && myModules.size() == 1) {
-        Pair<com.android.tools.klint.detector.api.Project,com.android.tools.klint.detector.api.Project> pair =
-          IntellijLintProject.createForSingleFile(mLintClient, myFileList.get(0), myModules.get(0));
-        mProjects = pair.first != null ? Collections.singletonList(pair.first)
-                                       : Collections.<com.android.tools.klint.detector.api.Project>emptyList();
-        myMainProject = pair.second;
-      } else if (!myModules.isEmpty()) {
-        // Make one project for each module, mark each one as a library,
-        // and add projects for the gradle libraries and set error reporting to
-        // false on those
-        //mProjects = computeProjects()
-        mProjects = IntellijLintProject.create(mLintClient, myFileList, myModules.toArray(new Module[myModules.size()]));
-      } else {
-        mProjects = super.getProjects();
-      }
-    }
-
-    return mProjects;
-  }
-
-  @NonNull
-  @Override
-  public com.android.tools.klint.detector.api.Project getMainProject(@NonNull com.android.tools.klint.detector.api.Project project) {
-    if (myMainProject != null) {
-      return myMainProject;
-    }
-    return super.getMainProject(project);
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintUtils.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintUtils.java
deleted file mode 100644
index 891a047..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintUtils.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2013 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 org.jetbrains.android.inspections.klint;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.builder.model.SourceProvider;
-import com.android.tools.idea.AndroidPsiUtils;
-import com.android.tools.idea.model.AndroidModel;
-import com.android.tools.klint.client.api.LintRequest;
-import com.android.tools.klint.detector.api.*;
-import com.google.common.base.Splitter;
-import com.intellij.debugger.engine.JVMNameUtil;
-import com.intellij.ide.util.JavaAnonymousClassesHelper;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.ClassUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.TypeConversionUtil;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.uast.*;
-import org.jetbrains.uast.psi.UElementWithLocation;
-import org.jetbrains.uast.util.UastExpressionUtils;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.android.SdkConstants.CONSTRUCTOR_NAME;
-import static com.android.SdkConstants.SUPPRESS_ALL;
-
-/**
- * Common utilities for handling lint within IntelliJ
- * TODO: Merge with {@link AndroidLintUtil}
- */
-public class IntellijLintUtils {
-  private IntellijLintUtils() {
-  }
-
-  @NonNls
-  public static final String SUPPRESS_LINT_FQCN = "android.annotation.SuppressLint";
-  @NonNls
-  public static final String SUPPRESS_WARNINGS_FQCN = "java.lang.SuppressWarnings";
-
-  /**
-   * Gets the location of the given element
-   *
-   * @param file the file containing the location
-   * @param element the element to look up the location for
-   * @return the location of the given element
-   */
-  @NonNull
-  public static Location getLocation(@NonNull File file, @NonNull PsiElement element) {
-    //noinspection ConstantConditions
-    assert element.getContainingFile().getVirtualFile() == null
-           || FileUtil.filesEqual(VfsUtilCore.virtualToIoFile(element.getContainingFile().getVirtualFile()), file);
-
-    if (element instanceof PsiClass) {
-      // Point to the name rather than the beginning of the javadoc
-      PsiClass clz = (PsiClass)element;
-      PsiIdentifier nameIdentifier = clz.getNameIdentifier();
-      if (nameIdentifier != null) {
-        element = nameIdentifier;
-      }
-    }
-
-    TextRange textRange = element.getTextRange();
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-    Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-    return Location.create(file, start, end);
-  }
-
-  /**
-   * Gets the location of the given element
-   *
-   * @param file the file containing the location
-   * @param element the element to look up the location for
-   * @return the location of the given element
-   */
-  @NonNull
-  public static Location getUastLocation(@NonNull File file, @NonNull UElement element) {
-    //noinspection ConstantConditions
-    PsiFile containingPsiFile = UastUtils.getContainingFile(element).getPsi();
-    assert containingPsiFile.getVirtualFile() == null
-           || FileUtil.filesEqual(VfsUtilCore.virtualToIoFile(containingPsiFile.getVirtualFile()), file);
-
-    if (element instanceof UClass) {
-      // Point to the name rather than the beginning of the javadoc
-      UClass clz = (UClass)element;
-      UElement nameIdentifier = clz.getUastAnchor();
-      if (nameIdentifier != null) {
-        element = nameIdentifier;
-      }
-    }
-
-    TextRange textRange = null;
-    PsiElement psi = element.getPsi();
-    if (psi != null) {
-      textRange = psi.getTextRange();
-    } else if (element instanceof UElementWithLocation) {
-      UElementWithLocation elementWithLocation = (UElementWithLocation) element;
-      textRange = new TextRange(
-              elementWithLocation.getStartOffset(),
-              elementWithLocation.getEndOffset());
-    }
-
-    if (textRange == null) {
-      return Location.NONE;
-    }
-
-    Position start = new DefaultPosition(-1, -1, textRange.getStartOffset());
-    Position end = new DefaultPosition(-1, -1, textRange.getEndOffset());
-    return Location.create(file, start, end);
-  }
-
-  /**
-   * Returns the {@link PsiFile} associated with a given lint {@link Context}
-   *
-   * @param context the context to look up the file for
-   * @return the corresponding {@link PsiFile}, or null
-   */
-  @Nullable
-  public static PsiFile getPsiFile(@NonNull Context context) {
-    VirtualFile file = VfsUtil.findFileByIoFile(context.file, false);
-    if (file == null) {
-      return null;
-    }
-    LintRequest request = context.getDriver().getRequest();
-    Project project = ((IntellijLintRequest)request).getProject();
-    if (project.isDisposed()) {
-      return null;
-    }
-    return AndroidPsiUtils.getPsiFileSafely(project, file);
-  }
-
-  /**
-   * Returns true if the given issue is suppressed at the given element within the given file
-   *
-   * @param element the element to check
-   * @param file the file containing the element
-   * @param issue the issue to check
-   * @return true if the given issue is suppressed
-   */
-  public static boolean isSuppressed(@NonNull PsiElement element, @NonNull PsiFile file, @NonNull Issue issue) {
-    // Search upwards for suppress lint and suppress warnings annotations
-    //noinspection ConstantConditions
-    while (element != null && element != file) { // otherwise it will keep going into directories!
-      if (element instanceof PsiModifierListOwner) {
-        PsiModifierListOwner owner = (PsiModifierListOwner)element;
-        PsiModifierList modifierList = owner.getModifierList();
-        if (modifierList != null) {
-          for (PsiAnnotation annotation : modifierList.getAnnotations()) {
-            String fqcn = annotation.getQualifiedName();
-            if (fqcn != null && (fqcn.equals(SUPPRESS_LINT_FQCN) || fqcn.equals(SUPPRESS_WARNINGS_FQCN))) {
-              PsiAnnotationParameterList parameterList = annotation.getParameterList();
-              for (PsiNameValuePair pair : parameterList.getAttributes()) {
-                PsiAnnotationMemberValue v = pair.getValue();
-                if (v instanceof PsiLiteral) {
-                  PsiLiteral literal = (PsiLiteral)v;
-                  Object value = literal.getValue();
-                  if (value instanceof String) {
-                    if (isSuppressed(issue, (String) value)) {
-                      return true;
-                    }
-                  }
-                } else if (v instanceof PsiArrayInitializerMemberValue) {
-                  PsiArrayInitializerMemberValue mv = (PsiArrayInitializerMemberValue)v;
-                  for (PsiAnnotationMemberValue mmv : mv.getInitializers()) {
-                    if (mmv instanceof PsiLiteral) {
-                      PsiLiteral literal = (PsiLiteral) mmv;
-                      Object value = literal.getValue();
-                      if (value instanceof String) {
-                        if (isSuppressed(issue, (String) value)) {
-                          return true;
-                        }
-                      }
-                    }
-                  }
-                } else if (v != null) {
-                  // This shouldn't be necessary
-                  String text = v.getText().trim(); // UGH! Find better way to access value!
-                  if (!text.isEmpty() && isSuppressed(issue, text)) {
-                    return true;
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-      element = element.getParent();
-    }
-
-    return false;
-  }
-
-  /**
-   * Returns true if the given issue is suppressed at the given element within the given file
-   *
-   * @param element the element to check
-   * @param file the file containing the element
-   * @param issue the issue to check
-   * @return true if the given issue is suppressed
-   */
-  public static boolean isSuppressed(@NonNull UElement element, @NonNull UFile file, @NonNull Issue issue) {
-    // Search upwards for suppress lint and suppress warnings annotations
-    //noinspection ConstantConditions
-    while (element != null && element != file) { // otherwise it will keep going into directories!
-      if (element instanceof UAnnotated) {
-        UAnnotated annotated = (UAnnotated)element;
-        for (UAnnotation annotation : annotated.getAnnotations()) {
-          String fqcn = annotation.getQualifiedName();
-          if (fqcn != null && (fqcn.equals(SUPPRESS_LINT_FQCN) || fqcn.equals(SUPPRESS_WARNINGS_FQCN))) {
-            List<UNamedExpression> parameterList = annotation.getAttributeValues();
-            for (UNamedExpression pair : parameterList) {
-              UExpression v = pair.getExpression();
-              if (v instanceof ULiteralExpression) {
-                ULiteralExpression literal = (ULiteralExpression)v;
-                Object value = literal.getValue();
-                if (value instanceof String) {
-                  if (isSuppressed(issue, (String) value)) {
-                    return true;
-                  }
-                }
-              } else if (UastExpressionUtils.isArrayInitializer(v)) {
-                UCallExpression mv = (UCallExpression)v;
-                for (UExpression mmv : mv.getValueArguments()) {
-                  if (mmv instanceof ULiteralExpression) {
-                    ULiteralExpression literal = (ULiteralExpression) mmv;
-                    Object value = literal.getValue();
-                    if (value instanceof String) {
-                      if (isSuppressed(issue, (String) value)) {
-                        return true;
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-      element = element.getUastParent();
-    }
-
-    return false;
-  }
-
-  /**
-   * Returns true if the given issue is suppressed by the given suppress string; this
-   * is typically the same as the issue id, but is allowed to not match case sensitively,
-   * and is allowed to be a comma separated list, and can be the string "all"
-   *
-   * @param issue  the issue id to match
-   * @param string the suppress string -- typically the id, or "all", or a comma separated list of ids
-   * @return true if the issue is suppressed by the given string
-   */
-  private static boolean isSuppressed(@NonNull Issue issue, @NonNull String string) {
-    for (String id : Splitter.on(',').trimResults().split(string)) {
-      if (id.equals(issue.getId()) || id.equals(SUPPRESS_ALL)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /** Returns the internal method name */
-  @NonNull
-  public static String getInternalMethodName(@NonNull PsiMethod method) {
-    if (method.isConstructor()) {
-      return SdkConstants.CONSTRUCTOR_NAME;
-    }
-    else {
-      return method.getName();
-    }
-  }
-
-  @Nullable
-  public static PsiElement getCallName(@NonNull PsiCallExpression expression) {
-    PsiElement firstChild = expression.getFirstChild();
-    if (firstChild != null) {
-      PsiElement lastChild = firstChild.getLastChild();
-      if (lastChild instanceof PsiIdentifier) {
-        return lastChild;
-      }
-    }
-    return null;
-  }
-
-
-  /**
-   * Computes the internal class name of the given class.
-   * For example, for PsiClass foo.bar.Foo.Bar it returns foo/bar/Foo$Bar.
-   *
-   * @param psiClass the class to look up the internal name for
-   * @return the internal class name
-   * @see ClassContext#getInternalName(String)
-   */
-  @Nullable
-  public static String getInternalName(@NonNull PsiClass psiClass) {
-    if (psiClass instanceof PsiAnonymousClass) {
-      PsiClass parent = PsiTreeUtil.getParentOfType(psiClass, PsiClass.class);
-      if (parent != null) {
-        String internalName = getInternalName(parent);
-        if (internalName == null) {
-          return null;
-        }
-        return internalName + JavaAnonymousClassesHelper.getName((PsiAnonymousClass)psiClass);
-      }
-    }
-    String sig = ClassUtil.getJVMClassName(psiClass);
-    if (sig == null) {
-      String qualifiedName = psiClass.getQualifiedName();
-      if (qualifiedName != null) {
-        return ClassContext.getInternalName(qualifiedName);
-      }
-      return null;
-    } else if (sig.indexOf('.') != -1) {
-      // Workaround -- ClassUtil doesn't treat this correctly!
-      // .replace('.', '/');
-      sig = ClassContext.getInternalName(sig);
-    }
-    return sig;
-  }
-
-  /**
-   * Computes the internal class name of the given class type.
-   * For example, for PsiClassType foo.bar.Foo.Bar it returns foo/bar/Foo$Bar.
-   *
-   * @param psiClassType the class type to look up the internal name for
-   * @return the internal class name
-   * @see ClassContext#getInternalName(String)
-   */
-  @Nullable
-  public static String getInternalName(@NonNull PsiClassType psiClassType) {
-    PsiClass resolved = psiClassType.resolve();
-    if (resolved != null) {
-      return getInternalName(resolved);
-    }
-
-    String className = psiClassType.getClassName();
-    if (className != null) {
-      return ClassContext.getInternalName(className);
-    }
-
-    return null;
-  }
-
-  /**
-   * Computes the internal JVM description of the given method. This is in the same
-   * format as the ASM desc fields for methods; meaning that a method named foo which for example takes an
-   * int and a String and returns a void will have description {@code foo(ILjava/lang/String;):V}.
-   *
-   * @param method the method to look up the description for
-   * @param includeName whether the name should be included
-   * @param includeReturn whether the return type should be included
-   * @return the internal JVM description for this method
-   */
-  @Nullable
-  public static String getInternalDescription(@NonNull PsiMethod method, boolean includeName, boolean includeReturn) {
-    assert !includeName; // not yet tested
-    assert !includeReturn; // not yet tested
-
-    StringBuilder signature = new StringBuilder();
-
-    if (includeName) {
-      if (method.isConstructor()) {
-        final PsiClass declaringClass = method.getContainingClass();
-        if (declaringClass != null) {
-          final PsiClass outerClass = declaringClass.getContainingClass();
-          if (outerClass != null) {
-            // declaring class is an inner class
-            if (!declaringClass.hasModifierProperty(PsiModifier.STATIC)) {
-              if (!appendJvmTypeName(signature, outerClass)) {
-                return null;
-              }
-            }
-          }
-        }
-        signature.append(CONSTRUCTOR_NAME);
-      } else {
-        signature.append(method.getName());
-      }
-    }
-
-    signature.append('(');
-
-    for (PsiParameter psiParameter : method.getParameterList().getParameters()) {
-      if (!appendJvmSignature(signature, psiParameter.getType())) {
-        return null;
-      }
-    }
-    signature.append(')');
-    if (includeReturn) {
-      if (!method.isConstructor()) {
-        if (!appendJvmSignature(signature, method.getReturnType())) {
-          return null;
-        }
-      }
-      else {
-        signature.append('V');
-      }
-    }
-    return signature.toString();
-  }
-
-  private static boolean appendJvmTypeName(@NonNull StringBuilder signature, @NonNull PsiClass outerClass) {
-    String className = getInternalName(outerClass);
-    if (className == null) {
-      return false;
-    }
-    signature.append('L').append(className.replace('.', '/')).append(';');
-    return true;
-  }
-
-  private static boolean appendJvmSignature(@NonNull StringBuilder buffer, @Nullable PsiType type) {
-    if (type == null) {
-      return false;
-    }
-    final PsiType psiType = TypeConversionUtil.erasure(type);
-    if (psiType instanceof PsiArrayType) {
-      buffer.append('[');
-      appendJvmSignature(buffer, ((PsiArrayType)psiType).getComponentType());
-    }
-    else if (psiType instanceof PsiClassType) {
-      PsiClass resolved = ((PsiClassType)psiType).resolve();
-      if (resolved == null) {
-        return false;
-      }
-      if (!appendJvmTypeName(buffer, resolved)) {
-        return false;
-      }
-    }
-    else if (psiType instanceof PsiPrimitiveType) {
-      buffer.append(JVMNameUtil.getPrimitiveSignature(psiType.getCanonicalText()));
-    }
-    else {
-      return false;
-    }
-    return true;
-  }
-
-  /** Returns the resource directories to use for the given module */
-  @NotNull
-  public static List<File> getResourceDirectories(@NotNull AndroidFacet facet) {
-    if (facet.requiresAndroidModel()) {
-      AndroidModel androidModel = facet.getAndroidModel();
-      if (androidModel != null) {
-        List<File> resDirectories = new ArrayList<File>();
-        List<SourceProvider> sourceProviders = androidModel.getActiveSourceProviders();
-        for (SourceProvider provider : sourceProviders) {
-          for (File file : provider.getResDirectories()) {
-            if (file.isDirectory()) {
-              resDirectories.add(file);
-            }
-          }
-        }
-        return resDirectories;
-      }
-    }
-    return new ArrayList<File>(facet.getMainSourceProvider().getResDirectories());
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijViewTypeDetector.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijViewTypeDetector.java
deleted file mode 100644
index 287fe0e..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijViewTypeDetector.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 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 org.jetbrains.android.inspections.klint;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.res2.AbstractResourceRepository;
-import com.android.ide.common.res2.ResourceItem;
-import com.android.tools.idea.res.LocalResourceRepository;
-import com.android.tools.klint.checks.ViewTypeDetector;
-import com.android.tools.klint.detector.api.Context;
-import com.android.tools.klint.detector.api.Implementation;
-import com.android.tools.klint.detector.api.Scope;
-
-import java.util.Collection;
-import java.util.Collections;
-
-public class IntellijViewTypeDetector extends ViewTypeDetector {
-  static final Implementation IMPLEMENTATION = new Implementation(
-    IntellijViewTypeDetector.class,
-    Scope.JAVA_FILE_SCOPE);
-
-  @Nullable
-  @Override
-  protected Collection<String> getViewTags(@NonNull Context context, @NonNull ResourceItem item) {
-    AbstractResourceRepository projectResources = context.getClient().getProjectResources(context.getMainProject(), true);
-    assert projectResources instanceof LocalResourceRepository : projectResources;
-    LocalResourceRepository repository = (LocalResourceRepository)projectResources;
-    String viewTag = repository.getViewTag(item);
-    if (viewTag != null) {
-      return Collections.singleton(viewTag);
-    }
-
-    return super.getViewTags(context, item);
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/LintInspectionDescriptionLinkHandler.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/LintInspectionDescriptionLinkHandler.java
deleted file mode 100644
index dd910a3..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/LintInspectionDescriptionLinkHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 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 org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.checks.BuiltinIssueRegistry;
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.TextFormat;
-import com.intellij.codeInsight.highlighting.TooltipLinkHandler;
-import com.intellij.codeInspection.InspectionProfile;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ex.InspectionToolWrapper;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-import com.intellij.profile.codeInspection.InspectionProfileManager;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import org.jetbrains.annotations.NotNull;
-
-public class LintInspectionDescriptionLinkHandler extends TooltipLinkHandler {
-  private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.inspections.lint.LintInspectionDescriptionLinkHandler");
-
-  @Override
-  public String getDescription(@NotNull final String refSuffix, @NotNull final Editor editor) {
-    final Project project = editor.getProject();
-    if (project == null) {
-      LOG.error(editor);
-      return null;
-    }
-
-    final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
-    if (file == null) {
-      return null;
-    }
-
-    Issue issue = new BuiltinIssueRegistry().getIssue(refSuffix);
-    if (issue != null) {
-      String html = issue.getExplanation(TextFormat.HTML);
-      // IntelliJ seems to treat newlines in the HTML as needing to also be converted to <br> (whereas
-      // Lint includes these for HTML readability but they shouldn't add additional lines since it has
-      // already added <br> as well) so strip these out
-      html = html.replace("\n", "");
-      return html;
-    }
-
-    // TODO: What about custom registries for custom rules, AARs etc?
-
-    LOG.warn("No description for inspection '" + refSuffix + "'");
-    return InspectionsBundle.message("inspection.tool.description.under.construction.text");
-  }
-}
\ No newline at end of file
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ProblemData.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ProblemData.java
deleted file mode 100644
index 33abc54..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/ProblemData.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.detector.api.Issue;
-import com.android.tools.klint.detector.api.Severity;
-import com.intellij.openapi.util.TextRange;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class ProblemData {
-  private final Issue myIssue;
-  private final String myMessage;
-  private final TextRange myTextRange;
-  private final Severity myConfiguredSeverity;
-
-  ProblemData(@NotNull Issue issue, @NotNull String message, @NotNull TextRange textRange, @Nullable Severity configuredSeverity) {
-    myIssue = issue;
-    myTextRange = textRange;
-    myMessage = message;
-    myConfiguredSeverity = configuredSeverity;
-  }
-
-  @NotNull
-  public Issue getIssue() {
-    return myIssue;
-  }
-
-  @NotNull
-  public TextRange getTextRange() {
-    return myTextRange;
-  }
-
-  @NotNull
-  public String getMessage() {
-    return myMessage;
-  }
-
-  @Nullable
-  public Severity getConfiguredSeverity() {
-    return myConfiguredSeverity;
-  }
-}
diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/State.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/State.java
deleted file mode 100644
index b122b49..0000000
--- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/State.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.jetbrains.android.inspections.klint;
-
-import com.android.tools.klint.detector.api.Issue;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class State {
-  private final Module myModule;
-  private final VirtualFile myMainFile;
-
-  private final String myMainFileContent;
-  private final List<ProblemData> myProblems = new ArrayList<ProblemData>();
-  private final List<Issue> myIssues;
-
-  private volatile boolean myDirty;
-
-  State(@NotNull Module module,
-        @NotNull VirtualFile mainFile,
-        @NotNull String mainFileContent,
-        @NotNull List<Issue> issues) {
-    myModule = module;
-    myMainFile = mainFile;
-    myMainFileContent = mainFileContent;
-    myIssues = issues;
-  }
-
-  @NotNull
-  public VirtualFile getMainFile() {
-    return myMainFile;
-  }
-
-  @NotNull
-  public String getMainFileContent() {
-    return myMainFileContent;
-  }
-
-  public void markDirty() {
-    myDirty = true;
-  }
-
-  public boolean isDirty() {
-    return myDirty;
-  }
-
-  @NotNull
-  public Module getModule() {
-    return myModule;
-  }
-
-  @NotNull
-  public List<ProblemData> getProblems() {
-    return myProblems;
-  }
-
-  @NotNull
-  public List<Issue> getIssues() {
-    return myIssues;
-  }
-}