diff --git a/ultimate/resources/META-INF/kotlin-spring.xml.172 b/ultimate/resources/META-INF/kotlin-spring.xml.172
new file mode 100644
index 00000000000..8d87a408fe4
--- /dev/null
+++ b/ultimate/resources/META-INF/kotlin-spring.xml.172
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/jam/KotlinJamReferenceContributor.kt.172 b/ultimate/src/org/jetbrains/kotlin/idea/jam/KotlinJamReferenceContributor.kt.172
new file mode 100644
index 00000000000..2860e10b445
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/jam/KotlinJamReferenceContributor.kt.172
@@ -0,0 +1,57 @@
+package org.jetbrains.kotlin.idea.jam
+
+import com.intellij.codeInsight.completion.CompletionUtil
+import com.intellij.jam.JamService
+import com.intellij.jam.JamStringAttributeElement
+import com.intellij.jam.reflect.JamStringAttributeMeta
+import com.intellij.psi.PsiElementRef
+import com.intellij.psi.PsiReference
+import com.intellij.psi.PsiReferenceRegistrar
+import com.intellij.util.SmartList
+import org.jetbrains.kotlin.asJava.toLightAnnotation
+import org.jetbrains.kotlin.asJava.unwrapped
+import org.jetbrains.kotlin.idea.references.AbstractKotlinReferenceContributor
+import org.jetbrains.kotlin.psi.KtAnnotationEntry
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+import org.jetbrains.kotlin.psi.KtValueArgument
+import org.jetbrains.kotlin.psi.psiUtil.isPlain
+import org.jetbrains.kotlin.psi.psiUtil.parents
+
+// Based on the JamReferenceContributor
+class KotlinJamReferenceContributor : AbstractKotlinReferenceContributor() {
+ @Suppress("UNCHECKED_CAST")
+ override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
+ registrar.registerMultiProvider { expression ->
+ if (!expression.isPlain()) return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val argument = expression
+ .parents
+ .filterIsInstance()
+ .firstOrNull() { it.parent?.parent is KtAnnotationEntry } ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val annotationEntry = argument.parent.parent as KtAnnotationEntry
+ val lightAnnotation = (CompletionUtil.getOriginalOrSelf(annotationEntry)).toLightAnnotation()
+ ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+
+ val service = JamService.getJamService(expression.project)
+ val annotationMeta = service.getMeta(lightAnnotation)
+ ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val attributeName = argument.getArgumentName()?.asName?.asString()
+ val attribute = annotationMeta.findAttribute(attributeName) as? JamStringAttributeMeta
+ ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val jam = attribute.getJam(PsiElementRef.real(lightAnnotation))
+ val converter = attribute.converter
+ when (jam) {
+ is JamStringAttributeElement<*> -> converter.createReferences(jam as JamStringAttributeElement)
+ is List<*> -> {
+ val list = SmartList()
+ for (item in jam) {
+ val jamElement = item as? JamStringAttributeElement ?: continue
+ if (jamElement.psiElement?.unwrapped != expression) continue
+ list += converter.createReferences(jamElement)
+ }
+ list.toTypedArray()
+ }
+ else -> PsiReference.EMPTY_ARRAY
+ }
+ }
+ }
+}
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KotlinSpringReferenceContributor.kt.172 b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KotlinSpringReferenceContributor.kt.172
new file mode 100644
index 00000000000..1a5c72bdc9b
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KotlinSpringReferenceContributor.kt.172
@@ -0,0 +1,157 @@
+/*
+ * 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.idea.spring.references
+
+import com.intellij.openapi.util.TextRange
+import com.intellij.psi.PsiReference
+import com.intellij.psi.PsiReferenceBase
+import com.intellij.psi.PsiReferenceRegistrar
+import com.intellij.spring.constants.SpringAnnotationsConstants
+import com.intellij.spring.constants.SpringConstants
+import com.intellij.spring.model.utils.resources.SpringResourcesBuilder
+import com.intellij.spring.model.utils.resources.SpringResourcesUtil
+import com.intellij.spring.references.SpringBeanNamesReferenceProvider
+import com.intellij.spring.references.SpringBeanReference
+import org.jetbrains.kotlin.asJava.toLightClass
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
+import org.jetbrains.kotlin.idea.imports.importableFqName
+import org.jetbrains.kotlin.idea.references.AbstractKotlinReferenceContributor
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.getContentRange
+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
+import org.jetbrains.kotlin.psi.psiUtil.isPlain
+import org.jetbrains.kotlin.psi.psiUtil.plainContent
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
+import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import org.jetbrains.kotlin.resolve.source.getPsi
+
+// TODO: Use Kotlin patterns
+class KotlinSpringReferenceContributor : AbstractKotlinReferenceContributor() {
+ override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
+ registrar.registerProvider {
+ if (!it.isPlain()) return@registerProvider null
+
+ val callExpression = (it.parent as? KtValueArgument)?.getStrictParentOfType() ?: return@registerProvider null
+ val context = callExpression.analyze(BodyResolveMode.PARTIAL)
+ val resolvedCall = callExpression.getResolvedCall(context) ?: return@registerProvider null
+ val callable = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return@registerProvider null
+ if (!callable.overriddenTreeAsSequence(true).any {
+ it.containingDeclaration.importableFqName?.asString() == SpringConstants.BEAN_FACTORY_CLASS
+ }) return@registerProvider null
+ if (callable.name.asString() !in SpringBeanNamesReferenceProvider.METHODS) return@registerProvider null
+
+ SpringBeanReference(it, it.getContentRange())
+ }
+
+ registrar.registerProvider(PsiReferenceRegistrar.HIGHER_PRIORITY) {
+ if (!it.isPlain()) return@registerProvider null
+
+ val argument = it.parent as? KtValueArgument ?: return@registerProvider null
+ val argumentName = argument.getArgumentName() ?: return@registerProvider null
+ if (argumentName.asName.asString() != "name") return@registerProvider null
+
+ val entry = argument.getStrictParentOfType() ?: return@registerProvider null
+ val context = entry.analyze(BodyResolveMode.PARTIAL)
+ val resolvedCall = entry.getResolvedCall(context) ?: return@registerProvider null
+ val annotation = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration ?: return@registerProvider null
+ if (annotation.importableFqName?.asString() != SpringAnnotationsConstants.JAVAX_RESOURCE) return@registerProvider null
+
+ val contentRange = it.getContentRange()
+ var startOffset = contentRange.startOffset
+ val isFactoryBeanRef: Boolean
+ if (it.plainContent.startsWith("&")) {
+ startOffset++
+ isFactoryBeanRef = true
+ }
+ else {
+ isFactoryBeanRef = false
+ }
+
+ val callable = (it.getStrictParentOfType()?.parent as? KtModifierList)?.parent as? KtCallableDeclaration
+ val callableType = (callable?.resolveToDescriptor() as? CallableDescriptor)?.returnType
+ val requiredSuperClass = callableType?.constructor?.declarationDescriptor?.source?.getPsi() as? KtClass
+
+ SpringBeanReference(it, TextRange(startOffset, contentRange.endOffset), requiredSuperClass?.toLightClass(), isFactoryBeanRef)
+ }
+
+ registrar.registerProvider(PsiReferenceRegistrar.HIGHER_PRIORITY) {
+ if (!it.isPlain()) return@registerProvider null
+
+ val argument = it.parent as? KtValueArgument ?: return@registerProvider null
+ val argumentName = argument.getArgumentName()
+ if (argumentName != null && argumentName.asName.asString() != "value") return@registerProvider null
+
+ val entry = argument.getStrictParentOfType() ?: return@registerProvider null
+ val context = entry.analyze(BodyResolveMode.PARTIAL)
+ val resolvedCall = entry.getResolvedCall(context) ?: return@registerProvider null
+ val annotation = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration ?: return@registerProvider null
+ if (annotation.importableFqName?.asString() != SpringAnnotationsConstants.SCOPE) return@registerProvider null
+
+ KtSpringBeanScopeReference(it)
+ }
+
+ registrar.registerMultiProvider {
+ if (!it.isPlain()) return@registerMultiProvider PsiReference.EMPTY_ARRAY
+
+ val callExpression = (it.parent as? KtValueArgument)?.getStrictParentOfType()
+ ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val context = callExpression.analyze(BodyResolveMode.PARTIAL)
+ val resolvedCall = callExpression.getResolvedCall(context) ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val classDescriptor = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration
+ ?: return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ val qName = classDescriptor.importableFqName?.asString()
+ if (qName != SpringConstants.CLASS_PATH_XML_APP_CONTEXT && qName != SpringConstants.CLASS_PATH_RESOURCE) {
+ return@registerMultiProvider PsiReference.EMPTY_ARRAY
+ }
+
+ val content = it.plainContent
+ val resourcesBuilder = SpringResourcesBuilder.create(it, content).fromRoot(content.startsWith("/")).soft(false)
+ SpringResourcesUtil.getInstance().getClassPathReferences(resourcesBuilder)
+ }
+
+ registrar.registerProvider(PsiReferenceRegistrar.HIGHER_PRIORITY) {
+ if (!it.isPlain()) return@registerProvider null
+
+ val argument = it.parent as? KtValueArgument ?: return@registerProvider null
+ val argumentName = argument.getArgumentName()
+ if (argumentName != null && argumentName.asName.asString() != "value") return@registerProvider null
+
+ val entry = argument.getStrictParentOfType() ?: return@registerProvider null
+ val bindingContext = entry.analyze(BodyResolveMode.PARTIAL)
+ val resolvedCall = entry.getResolvedCall(bindingContext) ?: return@registerProvider null
+ val annotation = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration
+ ?: return@registerProvider null
+ if (annotation.importableFqName?.asString() != SpringAnnotationsConstants.QUALIFIER) return@registerProvider null
+
+ val annotated = entry.getStrictParentOfType() ?: return@registerProvider null
+ if (annotated is KtClassOrObject) {
+ object : PsiReferenceBase(it) {
+ override fun resolve() = entry
+ override fun getVariants(): Array = arrayOf()
+ }
+ }
+ else {
+ KtSpringQualifierReference(it)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringBeanScopeReference.kt.172 b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringBeanScopeReference.kt.172
new file mode 100644
index 00000000000..1254d1be575
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringBeanScopeReference.kt.172
@@ -0,0 +1,44 @@
+/*
+ * 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.idea.spring.references
+
+import com.intellij.codeInsight.lookup.LookupElementBuilder
+import com.intellij.ide.TypePresentationService
+import com.intellij.psi.ElementManipulators
+import com.intellij.psi.PsiReferenceBase
+import com.intellij.spring.model.scope.SpringBeanScope
+import com.intellij.spring.model.scope.SpringBeanScopeManager
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+import org.jetbrains.kotlin.psi.psiUtil.plainContent
+
+class KtSpringBeanScopeReference(
+ element: KtStringTemplateExpression
+) : PsiReferenceBase(element, ElementManipulators.getManipulator(element).getRangeInElement(element)) {
+ private fun getScopes(): Sequence {
+ return SpringBeanScope.getDefaultScopes().asSequence() + SpringBeanScopeManager.getInstance().getCustomBeanScopes(element)
+ }
+
+ private fun getLookupElement(scope: String): LookupElementBuilder {
+ return LookupElementBuilder
+ .create(scope)
+ .withIcon(TypePresentationService.getService().getTypeIcon(SpringBeanScope::class.java))
+ }
+
+ override fun resolve() = if (element.plainContent in getScopes().map { it.value }) element else null
+
+ override fun getVariants() = getScopes().map { getLookupElement(it.value) }.toList().toTypedArray()
+}
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringQualifierReference.kt.172 b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringQualifierReference.kt.172
new file mode 100644
index 00000000000..eb9e900a2cf
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/references/KtSpringQualifierReference.kt.172
@@ -0,0 +1,127 @@
+/*
+ * 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.idea.spring.references
+
+import com.intellij.codeInsight.lookup.LookupElement
+import com.intellij.psi.*
+import com.intellij.spring.model.DefaultSpringBeanQualifier
+import com.intellij.spring.model.converters.SpringConverterUtil
+import com.intellij.spring.model.jam.qualifiers.SpringJamQualifier
+import com.intellij.spring.model.utils.SpringAutowireUtil
+import com.intellij.spring.model.utils.SpringModelSearchers
+import com.intellij.spring.references.SpringQualifierReference
+import org.jetbrains.kotlin.asJava.elements.KtLightElement
+import org.jetbrains.kotlin.asJava.toLightAnnotation
+import org.jetbrains.kotlin.asJava.toLightElements
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.imports.importableFqName
+import org.jetbrains.kotlin.idea.search.allScope
+import org.jetbrains.kotlin.idea.spring.springModel
+import org.jetbrains.kotlin.psi.KtAnnotationEntry
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
+import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
+import org.jetbrains.kotlin.psi.psiUtil.plainContent
+import org.jetbrains.kotlin.psi.psiUtil.startOffset
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import java.util.*
+
+// Based on com.intellij.spring.references.SpringQualifierReference
+// It inherits from SpringQualifierReference to allow reuse of existing Java inspections which explicitly check for SpringQualifierReference
+class KtSpringQualifierReference(element: KtStringTemplateExpression) : SpringQualifierReference(StringTemplatePsiLiteralWrapper(element)) {
+ class StringTemplatePsiLiteralWrapper(
+ val element: KtStringTemplateExpression
+ ) : PsiElement by element, PsiLiteralExpression, KtLightElement, PsiCompiledElement {
+
+ override fun getValue() = element.plainContent
+ override fun getType() = PsiType.getJavaLangString(element.manager, element.project.allScope())
+
+ override val clsDelegate: KtStringTemplateExpression
+ get() = element
+ override val kotlinOrigin: KtStringTemplateExpression
+ get() = element
+
+ override fun getMirror() = null
+ }
+
+ private fun getAnnotationFqName(): String? {
+ val annotationEntry = element.getStrictParentOfType() ?: return null
+ val context = annotationEntry.analyze(BodyResolveMode.PARTIAL)
+ val annotationType = context[BindingContext.TYPE, annotationEntry.typeReference] ?: return null
+ return annotationType.constructor.declarationDescriptor?.importableFqName?.asString()
+ }
+
+ override fun multiResolve(incompleteCode: Boolean): Array {
+ val annotationEntry = element.getStrictParentOfType() ?: return ResolveResult.EMPTY_ARRAY
+ val lightAnnotation = annotationEntry.toLightAnnotation() ?: return ResolveResult.EMPTY_ARRAY
+ val springModel = element.springModel ?: return ResolveResult.EMPTY_ARRAY
+
+ val results = ArrayList()
+ val jamQualifier = SpringJamQualifier(lightAnnotation, null)
+
+ val qualifiedBeans = springModel.findQualifiedBeans(jamQualifier)
+ qualifiedBeans.mapTo(results) { PsiElementResolveResult(it.springBean.springQualifier!!.identifyingPsiElement) }
+
+ val qualifierValue = jamQualifier.qualifierValue
+ if (qualifierValue != null) {
+ val beanPointer = SpringModelSearchers.findBean(springModel, qualifierValue)
+ val psiElement = if (beanPointer != null && beanPointer.isValid) beanPointer.psiElement else null
+ if (psiElement != null) results += PsiElementResolveResult(psiElement)
+ }
+
+ return results.toTypedArray()
+ }
+
+ // We can't get light elements for property in the synthetic completion KtFile, so look for original one instead
+ private fun getOriginalProperty(): KtProperty? {
+ val currentProperty = element.getStrictParentOfType() ?: return null
+ val originalFile = element.containingFile.originalFile as? KtFile ?: return null
+ return originalFile.findElementAt(currentProperty.startOffset)?.getNonStrictParentOfType()
+ }
+
+ override fun getVariants(): Array {
+ val annotationFqName = getAnnotationFqName() ?: return LookupElement.EMPTY_ARRAY
+ val springModel = element.springModel ?: return LookupElement.EMPTY_ARRAY
+ val property = getOriginalProperty() ?: return LookupElement.EMPTY_ARRAY
+ val lightElement = property.toLightElements().firstOrNull {
+ it is PsiField || (it is PsiMethod && !it.name.startsWith("set"))
+ }
+ val expectedPsiType = when (lightElement) {
+ is PsiMethod -> lightElement.returnType
+ is PsiField -> lightElement.type
+ else -> null
+ } ?: return LookupElement.EMPTY_ARRAY
+ return SpringAutowireUtil
+ .autowireByType(springModel, expectedPsiType)
+ .mapNotNull {
+ val qualifier = it.springBean.springQualifier
+ val value = qualifier?.qualifierValue
+ when {
+ qualifier == null ->
+ SpringConverterUtil.createCompletionVariant(it)
+ value != null && (qualifier is DefaultSpringBeanQualifier || qualifier.qualifierType?.qualifiedName == annotationFqName) ->
+ SpringConverterUtil.createCompletionVariant(it, value)
+ else ->
+ null
+ }
+ }
+ .toTypedArray()
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.172 b/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.172
new file mode 100644
index 00000000000..41ee6c3cbd4
--- /dev/null
+++ b/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.172
@@ -0,0 +1,11 @@
+// ELEMENT: java
+// CHAR: \n
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("java"))
+open class App {
+
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.after.172 b/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.after.172
new file mode 100644
index 00000000000..2a2eadee882
--- /dev/null
+++ b/ultimate/testData/spring/core/references/completion/handler/packageReferenceEnter.kt.after.172
@@ -0,0 +1,11 @@
+// ELEMENT: java
+// CHAR: \n
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("javava"))
+open class App {
+
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.172 b/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.172
new file mode 100644
index 00000000000..db5ba7d9225
--- /dev/null
+++ b/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.172
@@ -0,0 +1,11 @@
+// ELEMENT: java
+// CHAR: \t
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("java"))
+open class App {
+
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.after.172 b/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.after.172
new file mode 100644
index 00000000000..17e1f5d7589
--- /dev/null
+++ b/ultimate/testData/spring/core/references/completion/handler/packageReferenceTab.kt.after.172
@@ -0,0 +1,11 @@
+// ELEMENT: java
+// CHAR: \t
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("java"))
+open class App {
+
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/references/completion/variants/packageReference.kt.172 b/ultimate/testData/spring/core/references/completion/variants/packageReference.kt.172
new file mode 100644
index 00000000000..326f884cbb3
--- /dev/null
+++ b/ultimate/testData/spring/core/references/completion/variants/packageReference.kt.172
@@ -0,0 +1,12 @@
+// NUMBER: 2
+// EXIST: { lookupString:"java" }
+// EXIST: { lookupString:"javax" }
+
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = arrayOf("java"))
+open class App {
+
+}
\ No newline at end of file