public static void trackStatistics(InsertionContext context, final StatisticsUpdate update) {
    if (ourPendingUpdate != update) {
      return;
    }

    final Document document = context.getDocument();
    int startOffset = context.getStartOffset();
    int tailOffset = context.getEditor().getCaretModel().getOffset();
    if (startOffset < 0 || tailOffset <= startOffset) {
      return;
    }

    final RangeMarker marker = document.createRangeMarker(startOffset, tailOffset);
    final DocumentAdapter listener =
        new DocumentAdapter() {
          @Override
          public void beforeDocumentChange(DocumentEvent e) {
            if (!marker.isValid()
                || e.getOffset() > marker.getStartOffset()
                    && e.getOffset() < marker.getEndOffset()) {
              cancelLastCompletionStatisticsUpdate();
            }
          }
        };

    ourStatsAlarm.addRequest(
        new Runnable() {
          @Override
          public void run() {
            if (ourPendingUpdate == update) {
              applyLastCompletionStatisticsUpdate();
            }
          }
        },
        20 * 1000);

    document.addDocumentListener(listener);
    Disposer.register(
        update,
        new Disposable() {
          @Override
          public void dispose() {
            document.removeDocumentListener(listener);
            marker.dispose();
            ourStatsAlarm.cancelAllRequests();
          }
        });
  }
  private static void insertGenerationInfos(
      InsertionContext context, List<PsiGenerationInfo<PsiMethod>> infos) {
    List<PsiGenerationInfo<PsiMethod>> newInfos =
        GenerateMembersUtil.insertMembersAtOffset(
            context.getFile(), context.getStartOffset(), infos);
    if (!newInfos.isEmpty()) {
      final List<PsiElement> elements = new ArrayList<PsiElement>();
      for (GenerationInfo member : newInfos) {
        if (!(member instanceof TemplateGenerationInfo)) {
          final PsiMember psiMember = member.getPsiMember();
          if (psiMember != null) {
            elements.add(psiMember);
          }
        }
      }

      GlobalInspectionContextBase.cleanupElements(
          context.getProject(), null, elements.toArray(new PsiElement[elements.size()]));
      newInfos.get(0).positionCaret(context.getEditor(), true);
    }
  }
 public void addSparedChars(
     CompletionProgressIndicator indicator,
     LookupElement item,
     InsertionContext context,
     char completionChar) {
   String textInserted;
   if (context.getStartOffset() >= 0 && context.getTailOffset() >= context.getStartOffset()) {
     textInserted =
         context
             .getDocument()
             .getText()
             .substring(context.getStartOffset(), context.getTailOffset());
   } else {
     textInserted = item.getLookupString();
   }
   String withoutSpaces =
       StringUtil.replace(
           textInserted, new String[] {" ", "\t", "\n"}, new String[] {"", "", ""});
   int spared = withoutSpaces.length() - indicator.getLookup().itemPattern(item).length();
   if (!LookupEvent.isSpecialCompletionChar(completionChar)
       && withoutSpaces.contains(String.valueOf(completionChar))) {
     spared--;
   }
   if (spared > 0) {
     mySpared += spared;
   }
 }
 private static void removeLookupString(InsertionContext context) {
   context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset());
   context.commitDocument();
 }