diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 618bf01be3d..091439bdeef 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -265,6 +265,7 @@
+
diff --git a/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java
new file mode 100644
index 00000000000..bf178ed0013
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java
@@ -0,0 +1,105 @@
+package org.jetbrains.jet.plugin.vfilefinder;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.indexing.*;
+import com.intellij.util.io.KeyDescriptor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.resolve.java.resolver.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.name.FqName;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class KotlinClassFileIndex extends ScalarIndexExtension {
+
+ private static final Logger LOG = Logger.getInstance(KotlinClassFileIndex.class);
+ private static final int VERSION = 1;
+ public static final ID KEY = ID.create(KotlinClassFileIndex.class.getCanonicalName());
+
+ private static final KeyDescriptor KEY_DESCRIPTOR = new KeyDescriptor() {
+ @Override
+ public void save(DataOutput out, FqName value) throws IOException {
+ out.writeUTF(value.asString());
+ }
+
+ @Override
+ public FqName read(DataInput in) throws IOException {
+ return new FqName(in.readUTF());
+ }
+
+ @Override
+ public int getHashCode(FqName value) {
+ return value.asString().hashCode();
+ }
+
+ @Override
+ public boolean isEqual(FqName val1, FqName val2) {
+ if (val1 == null) {
+ return val2 == null;
+ }
+ return val1.equals(val1);
+ }
+ };
+
+ private static final FileBasedIndex.InputFilter INPUT_FILTER = new FileBasedIndex.InputFilter() {
+ @Override
+ public boolean acceptInput(VirtualFile file) {
+ return file.getFileType() == StdFileTypes.CLASS;
+ }
+ };
+ public static final DataIndexer INDEXER = new DataIndexer() {
+ @NotNull
+ @Override
+ public Map map(FileContent inputData) {
+ try {
+ KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(inputData.getFile());
+ if (header.isKotlinCompiledFile()) {
+ FqName fqName = header.getJvmClassName().getFqName();
+ return Collections.singletonMap(fqName, null);
+ }
+ }
+ catch (Throwable e) {
+ LOG.error("Error while indexing file " + inputData.getFileName(), e);
+ }
+ return Collections.emptyMap();
+ }
+ };
+
+ @NotNull
+ @Override
+ public ID getName() {
+ return KEY;
+ }
+
+ @NotNull
+ @Override
+ public DataIndexer getIndexer() {
+ return INDEXER;
+ }
+
+ @Override
+ public KeyDescriptor getKeyDescriptor() {
+ return KEY_DESCRIPTOR;
+ }
+
+ @Override
+ public FileBasedIndex.InputFilter getInputFilter() {
+ return INPUT_FILTER;
+ }
+
+ @Override
+ public boolean dependsOnFileContent() {
+ return true;
+ }
+
+ @Override
+ public int getVersion() {
+ return VERSION;
+ }
+}