private String getCaseCorrectedLookupString(LookupElement item) {
    String lookupString = item.getLookupString();
    if (item.isCaseSensitive()) {
      return lookupString;
    }

    final String prefix = itemPattern(item);
    final int length = prefix.length();
    if (length == 0 || !itemMatcher(item).prefixMatches(prefix)) return lookupString;
    boolean isAllLower = true;
    boolean isAllUpper = true;
    boolean sameCase = true;
    for (int i = 0; i < length && (isAllLower || isAllUpper || sameCase); i++) {
      final char c = prefix.charAt(i);
      boolean isLower = Character.isLowerCase(c);
      boolean isUpper = Character.isUpperCase(c);
      // do not take this kind of symbols into account ('_', '@', etc.)
      if (!isLower && !isUpper) continue;
      isAllLower = isAllLower && isLower;
      isAllUpper = isAllUpper && isUpper;
      sameCase = sameCase && isLower == Character.isLowerCase(lookupString.charAt(i));
    }
    if (sameCase) return lookupString;
    if (isAllLower) return lookupString.toLowerCase();
    if (isAllUpper) return StringUtil.toUpperCase(lookupString);
    return lookupString;
  }
 @Override
 public boolean isStartMatch(LookupElement element) {
   if (super.isStartMatch(element)) {
     return true;
   }
   if (element.isCaseSensitive()) {
     return false;
   }
   return ContainerUtil.or(
       element.getAllLookupStrings(),
       new Condition<String>() {
         @Override
         public boolean value(String s) {
           return myCaseInsensitiveMatcher.isStartMatch(s);
         }
       });
 }
 @Override
 public boolean prefixMatches(@NotNull final LookupElement element) {
   return prefixMatchersInternal(element, !element.isCaseSensitive());
 }