/**
  * Get the completions based on the arguments received
  *
  * @param state this is the state used for the completion
  * @param localScope this is the scope we're currently on (may be null)
  */
 public static Collection<AbstractToken> getCompletionsForTokenWithUndefinedType(
     CompletionState state, LocalScope localScope) {
   AbstractToken[] localTokens = localScope.getLocalTokens(-1, -1, false); // only to get the
   // args
   String activationToken = state.getActivationToken();
   String firstPart = FullRepIterable.getFirstPart(activationToken);
   for (AbstractToken token : localTokens) {
     if (token.getRepresentation().equals(firstPart)) {
       Collection<AbstractToken> interfaceForLocal =
           localScope.getInterfaceForLocal(state.getActivationToken());
       Collection<AbstractToken> argsCompletionFromParticipants =
           getCompletionsForTokenWithUndefinedTypeFromParticipants(
               state, localScope, interfaceForLocal);
       return argsCompletionFromParticipants;
     }
   }
   return getCompletionsForTokenWithUndefinedTypeFromParticipants(state, localScope, null);
 }
  private static void addCompletionVariant(
      @NotNull PsiBuilder builder, @NotNull CompletionState completionState, Object o) {
    int offset = builder.getCurrentOffset();
    if (!builder.eof() && offset == builder.rawTokenTypeStart(1))
      return; // suppress for zero-length tokens

    boolean add = false;
    int diff = completionState.offset - offset;
    String text = completionState.convertItem(o);
    int length = text == null ? 0 : text.length();
    if (length == 0) return;
    if (diff == 0) {
      add = true;
    } else if (diff > 0 && diff <= length) {
      CharSequence fragment = builder.getOriginalText().subSequence(offset, completionState.offset);
      add = completionState.prefixMatches(fragment.toString(), text);
    } else if (diff < 0) {
      for (int i = -1; ; i--) {
        IElementType type = builder.rawLookup(i);
        int tokenStart = builder.rawTokenTypeStart(i);
        if (isWhitespaceOrComment(builder, type)) {
          diff = completionState.offset - tokenStart;
        } else if (type != null && tokenStart < completionState.offset) {
          CharSequence fragment =
              builder.getOriginalText().subSequence(tokenStart, completionState.offset);
          if (completionState.prefixMatches(fragment.toString(), text)) {
            diff = completionState.offset - tokenStart;
          }
          break;
        } else break;
      }
      add = diff >= 0 && diff < length;
    }
    add =
        add
            && length > 1
            && !(text.charAt(0) == '<' && text.charAt(length - 1) == '>')
            && !(text.charAt(0) == '\'' && text.charAt(length - 1) == '\'' && length < 5);
    if (add) {
      completionState.addItem(builder, text);
    }
  }
 /**
  * Get the completions based on the arguments received
  *
  * @param state this is the state used for the completion
  * @param localScope this is the scope we're currently on (may be null)
  */
 public static Collection<AbstractToken> getCompletionsForMethodParameter(
     CompletionState state, LocalScope localScope) {
   AbstractToken[] args = localScope.getLocalTokens(-1, -1, true); // only to get the args
   String activationToken = state.getActivationToken();
   String firstPart = FullRepIterable.getFirstPart(activationToken);
   for (AbstractToken token : args) {
     if (token.getRepresentation().equals(firstPart)) {
       Collection<AbstractToken> interfaceForLocal =
           localScope.getInterfaceForLocal(state.getActivationToken());
       Collection<AbstractToken> argsCompletionFromParticipants =
           getCompletionsForMethodParameterFromParticipants(state, localScope, interfaceForLocal);
       for (AbstractToken t : interfaceForLocal) {
         if (!t.getRepresentation().equals(state.getQualifier())) {
           argsCompletionFromParticipants.add(t);
         }
       }
       return argsCompletionFromParticipants;
     }
   }
   return new ArrayList<AbstractToken>();
 }
  public void invoke(
      @NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
    if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;

    LookupManager.getInstance(project).hideActiveLookup();

    final CharSequence charsSequence = editor.getDocument().getCharsSequence();

    final CompletionData data = computeData(editor, charsSequence);
    String currentPrefix = data.myPrefix;

    final CompletionState completionState = getCompletionState(editor);

    String oldPrefix = completionState.oldPrefix;
    CompletionVariant lastProposedVariant = completionState.lastProposedVariant;

    if (lastProposedVariant == null
        || oldPrefix == null
        || !new CamelHumpMatcher(oldPrefix).prefixMatches(currentPrefix)
        || // oldPrefix.length() == 0 ||
        !currentPrefix.equals(lastProposedVariant.variant)) {
      // we are starting over
      oldPrefix = currentPrefix;
      completionState.oldPrefix = oldPrefix;
      lastProposedVariant = null;
    }

    CompletionVariant nextVariant =
        computeNextVariant(editor, oldPrefix, lastProposedVariant, data);
    if (nextVariant == null) return;

    int replacementEnd = data.startOffset + data.myWordUnderCursor.length();
    editor.getDocument().replaceString(data.startOffset, replacementEnd, nextVariant.variant);
    editor.getCaretModel().moveToOffset(data.startOffset + nextVariant.variant.length());
    completionState.lastProposedVariant = nextVariant;
    highlightWord(editor, nextVariant, project, data);
  }
 private static void addCompletionVariant(
     ErrorState state,
     CompletionState completionState,
     PsiBuilder builder_,
     Object o,
     int offset) {
   boolean add = false;
   int diff = completionState.offset - offset;
   String text = completionState.convertItem(o);
   int length = text == null ? 0 : text.length();
   if (length == 0) return;
   if (diff == 0) {
     add = true;
   } else if (diff > 0 && diff <= length) {
     CharSequence fragment =
         builder_.getOriginalText().subSequence(offset, completionState.offset);
     add = StringUtil.startsWithIgnoreCase(text, fragment.toString());
   } else if (diff < 0) {
     for (int i = -1; ; i--) {
       IElementType type = builder_.rawLookup(i);
       int tokenStart = builder_.rawTokenTypeStart(i);
       if (state.whitespaceTokens.contains(type) || state.commentTokens.contains(type)) {
         diff = completionState.offset - tokenStart;
       } else if (type != null && tokenStart < completionState.offset) {
         CharSequence fragment =
             builder_.getOriginalText().subSequence(tokenStart, completionState.offset);
         if (StringUtil.startsWithIgnoreCase(text, fragment.toString())) {
           diff = completionState.offset - tokenStart;
         }
         break;
       } else break;
     }
     add = diff >= 0 && diff < length;
   }
   add =
       add
           && length > 1
           && !(text.charAt(0) == '<' && text.charAt(length - 1) == '>')
           && !(text.charAt(0) == '\'' && text.charAt(length - 1) == '\'' && length < 5);
   if (add) {
     completionState.items.add(text);
   }
 }