CompletionVariant (final Editor editor, @Nullable final String prefix, @Nullable CompletionVariant lastProposedVariant, final CompletionData data, PsiFile file, boolean includeWordsFromOtherFiles, boolean weAlreadyDoBestAttempt ) { final List<CompletionVariant> variants = computeVariants(editor, new CamelHumpMatcher(StringUtil.notNullize(prefix)), file, includeWordsFromOtherFiles); if (variants.isEmpty()) { return weAlreadyDoBestAttempt ? null:computeNextVariant(editor, prefix, null, data, file, !includeWordsFromOtherFiles, true); } if (lastProposedVariant != null) { // intern lastProposedVariant for (CompletionVariant variant : variants) { if (variant.variant.equals(lastProposedVariant.variant)) { if (lastProposedVariant.offset > data.startOffset && variant.offset > data.startOffset) lastProposedVariant = variant; if (lastProposedVariant.offset < data.startOffset && variant.offset < data.startOffset) lastProposedVariant = variant; if (includeWordsFromOtherFiles && lastProposedVariant.editor == variant.editor) lastProposedVariant = variant; } } } if (lastProposedVariant == null) { CompletionVariant result = null; if (myForward) { if (includeWordsFromOtherFiles) { return variants.get(variants.size() - 1); } for (CompletionVariant variant : variants) { if (variant.offset < data.startOffset) { result = variant; } else if (result == null) { result = variant; break; } } } else { if (includeWordsFromOtherFiles) { return variants.get(0); } for (CompletionVariant variant : variants) { if (variant.offset > data.startOffset) { return variant; } } return variants.iterator().next(); } return result; } if (myForward) { CompletionVariant result = null; for (CompletionVariant variant : variants) { if (variant == lastProposedVariant) { if (result == null) { return computeNextVariant(editor, prefix, null, data, file, !includeWordsFromOtherFiles, true); } return result; } result = variant; } return variants.get(variants.size() - 1); } else { for (Iterator<CompletionVariant> i = variants.iterator(); i.hasNext();) { CompletionVariant variant = i.next(); if (variant == lastProposedVariant) { if (i.hasNext()) { return i.next(); } else { return computeNextVariant(editor, prefix, null, data, file, !includeWordsFromOtherFiles, true); } } } } return null; }