private static void addWordsForEditor(final Editor editor,
                                        final CamelHumpMatcher matcher,
                                        final List<? super CompletionVariant> words,
                                        final List<? super CompletionVariant> afterWords, boolean takeCaretsIntoAccount) {
    final CharSequence chars = editor.getDocument().getImmutableCharSequence();
    final int primaryCaretOffset;
    final int[] caretOffsets;
    if (takeCaretsIntoAccount) {
      CaretModel caretModel = editor.getCaretModel();
      primaryCaretOffset = caretModel.getOffset();
      caretOffsets = getCaretOffsets(caretModel);
    }
    else {
      primaryCaretOffset = 0;
      caretOffsets = new int[0];
    }
    TokenProcessor processor = new TokenProcessor() {
      @Override
      public boolean processToken(int start, int end) {
        for (int caretOffset : caretOffsets) {
          if (start <= caretOffset && end >= caretOffset) return true; //skip prefix itself
        }
        if (end - start > matcher.getPrefix().length()) {
          final String word = chars.subSequence(start, end).toString();
          if (matcher.isStartMatch(word)) {
            CompletionVariant v = new CompletionVariant(editor, word, start);
            if (end > primaryCaretOffset) {
              afterWords.add(v);
            }
            else {
              words.add(v);
            }
          }
        }
        return true;
      }
    };
    processWords(editor, 0, processor);
  }
private static void addWordsForEditor(final Editor editor,
                                        final CamelHumpMatcher matcher,
                                        final List<? super CompletionVariant> words,
                                        final List<? super CompletionVariant> afterWords, boolean takeCaretsIntoAccount)