static CharFilter.Result getLookupAction(final char charTyped, final LookupImpl lookup) {
    final CharFilter.Result filtersDecision = getFiltersDecision(charTyped, lookup);
    if (!Registry.is("ide.completion.allow.finishing.by.chars")
        && filtersDecision == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP) {
      return CharFilter.Result.HIDE_LOOKUP;
    }

    final LookupElement currentItem = lookup.getCurrentItem();
    if (currentItem != null && charTyped != ' ') {
      String postfix = lookup.getAdditionalPrefix() + charTyped;
      final PrefixMatcher matcher = lookup.itemMatcher(currentItem);
      for (String lookupString : currentItem.getAllLookupStrings()) {
        if (lookupString.startsWith(matcher.getPrefix() + postfix)) {
          return CharFilter.Result.ADD_TO_PREFIX;
        }
      }
    }

    if (filtersDecision != null) {
      return filtersDecision;
    }
    throw new AssertionError(
        "Typed char not handler by char filter: c="
            + charTyped
            + "; prefix="
            + currentItem
            + "; filters="
            + Arrays.toString(getFilters()));
  }
 private static boolean completeTillTypedCharOccurrence(
     char charTyped, LookupImpl lookup, LookupElement item) {
   PrefixMatcher matcher = lookup.itemMatcher(item);
   final String oldPrefix = matcher.getPrefix() + lookup.getAdditionalPrefix();
   PrefixMatcher expanded = matcher.cloneWithPrefix(oldPrefix + charTyped);
   if (expanded.prefixMatches(item)) {
     for (String s : item.getAllLookupStrings()) {
       if (matcher.prefixMatches(s)) {
         int i = -1;
         while (true) {
           i = s.indexOf(charTyped, i + 1);
           if (i < 0) break;
           final String newPrefix = s.substring(0, i + 1);
           if (expanded.prefixMatches(newPrefix)) {
             lookup.replacePrefix(oldPrefix, newPrefix);
             return true;
           }
         }
       }
     }
   }
   return false;
 }