package org.jetbrains.kotlin.ui.editors.completion;

import java.util.Collection;
import java.util.List;

import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.eclipse.ui.utils.EditorUtil;
import org.jetbrains.kotlin.eclipse.ui.utils.LineEndUtil;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.psi.JetSimpleNameExpression;
import org.jetbrains.kotlin.core.builder.KotlinPsiManager;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;

public class KotlinCompletionUtils {

    public static final KotlinCompletionUtils INSTANCE = new KotlinCompletionUtils();
    
    private KotlinCompletionUtils() {
    }
    
    @NotNull
    public Collection<DeclarationDescriptor> filterCompletionProposals(@NotNull List<DeclarationDescriptor> descriptors, 
            @NotNull final String prefix) {
        return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
            @Override
            public boolean apply(DeclarationDescriptor descriptor) {
                String identifier = descriptor.getName().getIdentifier();
                return identifier.startsWith(prefix) || 
                       identifier.toLowerCase().startsWith(prefix) || 
                       SearchPattern.camelCaseMatch(prefix, identifier);
            }
        });
    }
    
    @Nullable
    public JetSimpleNameExpression getSimpleNameExpression(@NotNull JavaEditor editor, int identOffset) {
        String sourceCode = EditorUtil.getSourceCode(editor);
        String sourceCodeWithMarker = new StringBuilder(sourceCode).insert(identOffset, "KotlinRulezzz").toString();
        
        JetFile jetFile = KotlinPsiManager.INSTANCE.getParsedFile(EditorUtil.getFile(editor), sourceCodeWithMarker);
        
        int offsetWithourCR = LineEndUtil.convertCrToOsOffset(sourceCodeWithMarker, identOffset);
        PsiElement psiElement = jetFile.findElementAt(offsetWithourCR);
        
        return PsiTreeUtil.getParentOfType(psiElement, JetSimpleNameExpression.class);
    }
}

@@ -288,24 +288,83 @@
 s.Nullable;%0A
+import org.jetbrains.kotlin.core.builder.KotlinPsiManager;%0A
 import org.j
@@ -410,24 +410,24 @@
 Descriptor;%0A
-
 import org.j
@@ -630,67 +630,8 @@
 ion;
-%0Aimport org.jetbrains.kotlin.core.builder.KotlinPsiManager;
 %0A%0Aim
@@ -832,16 +832,90 @@
 Utils %7B%0A
+    private static final String KOTLIN_DUMMY_IDENTIFIER = %22KotlinRulezzz%22;
 %0A    pub
@@ -1988,31 +1988,39 @@
 Offset, 
-%22KotlinRulezzz%22
+KOTLIN_DUMMY_IDENTIFIER
 ).toStri

extract constant