diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
index a542192..834b1ef 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.asJava.AbstractCompilerLightClassTest
@@ -1268,10 +1267,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 b91e9bb..0097a8e 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 93%
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 5cf05ff6..a05fc15 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.android.hasBackingField
 import org.jetbrains.kotlin.idea.util.addAnnotation
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 95%
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 347a402..d506bed 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.caches.resolve.analyze
 import org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinIfSurrounder
 import org.jetbrains.kotlin.idea.core.ShortenReferences
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 62%
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 0d8d750..724f718 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,52 +14,26 @@
  * 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.android.hasBackingField
 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
         }
@@ -67,14 +41,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
@@ -107,4 +91,9 @@
                this !is KtFunctionLiteral &&
                this !is KtDestructuringDeclaration
     }
+    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 f9f8903..0000000
--- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt
+++ /dev/null
@@ -1,71 +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
-    }
-
-    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 fd33e33..8bb72c1 100644
--- a/idea/src/META-INF/android.xml
+++ b/idea/src/META-INF/android.xml
@@ -89,6 +89,10 @@
         <androidDexer implementation="org.jetbrains.kotlin.android.debugger.AndroidDexerImpl"/>
     </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 d6a4844..0000000
--- a/idea/testData/android/lint/apiCheck.kt
+++ /dev/null
@@ -1,486 +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 }
-}
-
-interface WithDefault {
-    // Should be ok
-    fun methodWithBody() {
-        return
-    }
-}
\ 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 ffc534f..0000000
--- a/idea/testData/android/lint/sdCardTest.kt
+++ /dev/null
@@ -1,45 +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>"
-
-    val sdCardPath by lazy { "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard</warning>" }
-    fun localPropertyTest() {
-        val sdCardPathLocal by lazy { "<warning descr="Do not hardcode \"/sdcard/\"; use `Environment.getExternalStorageDirectory().getPath()` instead">/sdcard</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 f0f57c9..0000000
--- a/plugins/lint/lint-api/lint-api.iml
+++ /dev/null
@@ -1,19 +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" />
-    <orderEntry type="library" exported="" name="uast-java" level="project" />
-    <orderEntry type="module" module-name="util.runtime" scope="PROVIDED" />
-  </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 b66a8418..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 e683aea..0000000
--- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaVisitor.java
+++ /dev/null
@@ -1,1400 +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.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 lombok.ast.*;
-import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
-
-import java.util.*;
-
-import static com.android.SdkConstants.ANDROID_PKG;
-import static com.android.SdkConstants.R_CLASS;
-
-/**
- * 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 (ExceptionUtilsKt.isProcessCanceledException(e)) {
-                // 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 29a03d0..0000000
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.java
+++ /dev/null
@@ -1,1974 +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 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;
-  }
-}
