diff --git a/annotations/com/intellij/openapi/roots/annotations.xml b/annotations/com/intellij/openapi/roots/annotations.xml
index f0bdec252df..5308bd0edbe 100644
--- a/annotations/com/intellij/openapi/roots/annotations.xml
+++ b/annotations/com/intellij/openapi/roots/annotations.xml
@@ -22,7 +22,11 @@
-
- -
+
+
+ -
diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/LibraryDependenciesCache.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/LibraryDependenciesCache.kt
new file mode 100644
index 00000000000..6037282135e
--- /dev/null
+++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/caches/resolve/LibraryDependenciesCache.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010-2014 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.jet.plugin.caches.resolve
+
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.roots.libraries.Library
+import com.intellij.util.containers.MultiMap
+import com.intellij.psi.util.CachedValuesManager
+import com.intellij.psi.util.CachedValueProvider
+import com.intellij.openapi.roots.ProjectRootModificationTracker
+import com.intellij.openapi.module.ModuleManager
+import com.intellij.openapi.roots.ModuleRootManager
+import com.intellij.openapi.roots.LibraryOrderEntry
+import com.intellij.openapi.roots.OrderEntry
+import com.intellij.openapi.roots.ModuleOrderEntry
+import com.intellij.openapi.util.Condition
+import java.util.LinkedHashSet
+import com.intellij.openapi.roots.RootPolicy
+import org.jetbrains.jet.utils.addIfNotNull
+import com.intellij.openapi.projectRoots.Sdk
+import com.intellij.openapi.roots.JdkOrderEntry
+import com.intellij.openapi.roots.ModuleSourceOrderEntry
+
+public class LibraryDependenciesCache(private val project: Project) {
+
+ //NOTE: used LibraryRuntimeClasspathScope as reference
+ public fun getLibrariesAndSdksUsedWith(library: Library): Pair, List> {
+ val processedModules = LinkedHashSet()
+ val condition = Condition() { orderEntry ->
+ if (orderEntry is ModuleOrderEntry) {
+ val module = orderEntry.getModule()
+ module != null && module !in processedModules
+ }
+ else {
+ true
+ }
+ }
+
+ val libraries = LinkedHashSet()
+ val sdks = LinkedHashSet()
+
+ fun collectLibrariesAndSdksAcrossDependencies(module: Module) {
+ if (!processedModules.add(module)) return
+
+ ModuleRootManager.getInstance(module).orderEntries().recursively().satisfying(condition).process(object : RootPolicy() {
+ override fun visitModuleSourceOrderEntry(moduleSourceOrderEntry: ModuleSourceOrderEntry?, value: Unit?): Unit? {
+ processedModules.addIfNotNull(moduleSourceOrderEntry?.getOwnerModule())
+ return Unit
+ }
+
+ public override fun visitLibraryOrderEntry(libraryOrderEntry: LibraryOrderEntry?, value: Unit?): Unit? {
+ libraries.addIfNotNull(libraryOrderEntry?.getLibrary())
+ return Unit
+ }
+
+ override fun visitJdkOrderEntry(jdkOrderEntry: JdkOrderEntry?, value: Unit?): Unit? {
+ sdks.addIfNotNull(jdkOrderEntry?.getJdk())
+ return Unit
+ }
+ }, Unit)
+ }
+
+ getLibraryUsageIndex().modulesLibraryIsUsedIn[library].forEach { module -> collectLibrariesAndSdksAcrossDependencies(module) }
+
+ return Pair(libraries.toList(), sdks.toList())
+ }
+
+ public fun getLibraryUsageIndex(): LibraryUsageIndex {
+ return CachedValuesManager.getManager(project).getCachedValue(project) {
+ CachedValueProvider.Result(LibraryUsageIndex(), ProjectRootModificationTracker.getInstance(project))
+ }!!
+ }
+
+ private inner class LibraryUsageIndex {
+ val modulesLibraryIsUsedIn: MultiMap = MultiMap.createSet();
+ {
+ ModuleManager.getInstance(project).getModules().forEach {
+ module ->
+ ModuleRootManager.getInstance(module).getOrderEntries().forEach {
+ entry ->
+ if (entry is LibraryOrderEntry) {
+ val library = entry.getLibrary()
+ if (library != null) {
+ modulesLibraryIsUsedIn.putValue(library, module)
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file