public static void addImportForItem(InsertionContext context, PsiClass aClass) {
    if (aClass.getQualifiedName() == null) return;
    PsiFile file = context.getFile();

    int startOffset = context.getStartOffset();
    int tail = context.getTailOffset();
    int newTail = JavaCompletionUtil.insertClassReference(aClass, file, startOffset, tail);
    if (newTail > context.getDocument().getTextLength() || newTail < 0) {
      LOG.error(
          LogMessageEx.createEvent(
              "Invalid offset after insertion ",
              "offset="
                  + newTail
                  + "\n"
                  + "start="
                  + startOffset
                  + "\n"
                  + "tail="
                  + tail
                  + "\n"
                  + "file.length="
                  + file.getTextLength()
                  + "\n"
                  + "document="
                  + context.getDocument()
                  + "\n"
                  + DebugUtil.currentStackTrace(),
              AttachmentFactory.createAttachment(context.getDocument())));
      return;
    }
    context.setTailOffset(newTail);
    JavaCompletionUtil.shortenReference(file, context.getStartOffset());
    PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
  }
 @Override
 public void handleInsert(final InsertionContext context) {
   context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset());
   context.setAddCompletionChar(false);
   TemplateManager templateManager = TemplateManager.getInstance(context.getProject());
   templateManager.startTemplate(context.getEditor(), "", myTemplate);
 }
 public static void invokeCompletion(
     @NotNull final InsertionContext context, final CompletionType completionType) {
   context.setLaterRunnable(
       () ->
           new CodeCompletionHandlerBase(completionType)
               .invokeCompletion(context.getProject(), context.getEditor()));
 }
  @Nullable
  @Override
  protected List<ClosureParameterInfo> getParameterInfos(
      InsertionContext context,
      PsiMethod method,
      PsiSubstitutor substitutor,
      Document document,
      int offset,
      PsiElement parent) {
    final String name = method.getName();
    if (!"eachWithIndex".equals(name)) return null;

    if (method instanceof GrGdkMethod) method = ((GrGdkMethod) method).getStaticMethod();

    final PsiClass containingClass = method.getContainingClass();
    if (containingClass == null) return null;

    final String qname = containingClass.getQualifiedName();

    if (!GroovyCommonClassNames.DEFAULT_GROOVY_METHODS.equals(qname)) return null;

    final PsiParameter[] parameters = method.getParameterList().getParameters();
    if (parameters.length != 2) return null;

    final PsiType type = parameters[0].getType();
    final PsiType collection = substitutor.substitute(type);

    final PsiType iterable = getIteratedType(parent, collection);
    if (iterable != null) {
      return Arrays.asList(
          new ClosureParameterInfo(iterable.getCanonicalText(), "entry"),
          new ClosureParameterInfo("int", "i"));
    }

    if (InheritanceUtil.isInheritor(collection, CommonClassNames.JAVA_UTIL_MAP)) {
      final PsiType[] typeParams = ((PsiClassType) collection).getParameters();

      final Project project = context.getProject();

      final PsiClass entry =
          JavaPsiFacade.getInstance(project)
              .findClass("java.util.Map.Entry", parent.getResolveScope());
      if (entry == null) return null;

      final PsiClassType entryType =
          JavaPsiFacade.getElementFactory(project).createType(entry, typeParams);

      return Arrays.asList(
          new ClosureParameterInfo(entryType.getCanonicalText(), "entry"),
          new ClosureParameterInfo("int", "i"));
    }

    return Arrays.asList(
        new ClosureParameterInfo(collection.getCanonicalText(), "entry"),
        new ClosureParameterInfo("int", "i"));
  }
  @Override
  public void handleInsert(final InsertionContext context, LookupElement item) {
    final PsiClassType.ClassResolveResult resolveResult = myClassType.resolveGenerics();
    final PsiClass psiClass = resolveResult.getElement();
    if (psiClass == null || !psiClass.isValid()) {
      return;
    }

    GroovyPsiElement place =
        PsiTreeUtil.findElementOfClassAtOffset(
            context.getFile(), context.getStartOffset(), GroovyPsiElement.class, false);
    boolean hasParams =
        place != null && GroovyCompletionUtil.hasConstructorParameters(psiClass, place);
    if (myTriggerFeature) {
      FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
    }

    if (hasParams) {
      ParenthesesInsertHandler.WITH_PARAMETERS.handleInsert(context, item);
    } else {
      ParenthesesInsertHandler.NO_PARAMETERS.handleInsert(context, item);
    }

    shortenRefsInGenerics(context);
    if (hasParams) {
      AutoPopupController.getInstance(context.getProject())
          .autoPopupParameterInfo(context.getEditor(), null);
    }

    PsiDocumentManager.getInstance(context.getProject())
        .doPostponedOperationsAndUnblockDocument(context.getDocument());

    if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
      final Editor editor = context.getEditor();
      final int offset = context.getTailOffset();
      editor.getDocument().insertString(offset, " {}");
      editor.getCaretModel().moveToOffset(offset + 2);

      context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
    }
  }
  public static void addTypeAndClassifierAndVersion(
      @NotNull InsertionContext context,
      @NotNull MavenDomDependency dependency,
      @NotNull String groupId,
      @NotNull String artifactId) {
    if (!StringUtil.isEmpty(dependency.getVersion().getStringValue())) return;

    Project project = context.getProject();

    if (!isInsideManagedDependency(dependency)) {
      MavenDomProjectModel model =
          DomUtil.<MavenDomProjectModel>getFileElement(dependency).getRootElement();
      MavenDomDependency managedDependency =
          findManagedDependency(model, project, groupId, artifactId);
      if (managedDependency != null) {
        if (dependency.getClassifier().getXmlTag() == null
            && dependency.getType().getXmlTag() == null) {
          String classifier = managedDependency.getClassifier().getRawText();
          if (StringUtil.isNotEmpty(classifier)) {
            dependency.getClassifier().setStringValue(classifier);
          }
          String type = managedDependency.getType().getRawText();
          if (StringUtil.isNotEmpty(type)) {
            dependency.getType().setStringValue(type);
          }
        }
        return;
      }
    }

    MavenProjectIndicesManager manager = MavenProjectIndicesManager.getInstance(project);

    Set<String> versions = manager.getVersions(groupId, artifactId);
    if (versions.size() == 1) {
      dependency.getVersion().setStringValue(ContainerUtil.getFirstItem(versions));
      return;
    }

    dependency.getVersion().setStringValue("");

    int versionPosition =
        dependency.getVersion().getXmlTag().getValue().getTextRange().getStartOffset();

    context.getEditor().getCaretModel().moveToOffset(versionPosition);

    if (versions.size() > 0) {
      invokeCompletion(context, CompletionType.BASIC);
    }
  }
  private static void qualifyFieldReference(InsertionContext context, PsiField field) {
    context.commitDocument();
    PsiFile file = context.getFile();
    final PsiReference reference = file.findReferenceAt(context.getStartOffset());
    if (reference instanceof PsiJavaCodeReferenceElement
        && ((PsiJavaCodeReferenceElement) reference).isQualified()) {
      return;
    }

    PsiClass containingClass = field.getContainingClass();
    if (containingClass != null && containingClass.getName() != null) {
      OffsetKey oldStart = context.trackOffset(context.getStartOffset(), true);
      JavaCompletionUtil.insertClassReference(containingClass, file, context.getStartOffset());
      context.getDocument().insertString(context.getOffsetMap().getOffset(oldStart), ".");
      PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
    }
  }
  private boolean shouldQualify(PsiField field, InsertionContext context) {
    if (myHelper != null && !myHelper.willBeImported()) {
      return true;
    }

    if (getAttribute(FORCE_QUALIFY) != null) {
      return true;
    }

    PsiReference reference = context.getFile().findReferenceAt(context.getStartOffset());
    if (reference instanceof PsiReferenceExpression
        && !((PsiReferenceExpression) reference).isQualified()) {
      final PsiVariable target =
          JavaPsiFacade.getInstance(context.getProject())
              .getResolveHelper()
              .resolveReferencedVariable(field.getName(), (PsiElement) reference);
      return !field
          .getManager()
          .areElementsEquivalent(target, CompletionUtil.getOriginalOrSelf(field));
    }
    return false;
  }
  @Override
  public void handleInsert(InsertionContext context) {
    PsiVariable variable = getObject();

    Document document = context.getDocument();
    document.replaceString(context.getStartOffset(), context.getTailOffset(), variable.getName());
    context.commitDocument();

    if (variable instanceof PsiField) {
      if (willBeImported()) {
        RangeMarker toDelete =
            JavaCompletionUtil.insertTemporary(context.getTailOffset(), document, " ");
        context.commitDocument();
        final PsiReferenceExpression ref =
            PsiTreeUtil.findElementOfClassAtOffset(
                context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
        if (ref != null) {
          ref.bindToElementViaStaticImport(((PsiField) variable).getContainingClass());
          PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting();
        }
        if (toDelete.isValid()) {
          document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset());
        }
        context.commitDocument();
      } else if (shouldQualify((PsiField) variable, context)) {
        qualifyFieldReference(context, (PsiField) variable);
      }
    }

    PsiReferenceExpression ref =
        PsiTreeUtil.findElementOfClassAtOffset(
            context.getFile(), context.getTailOffset() - 1, PsiReferenceExpression.class, false);
    if (ref != null) {
      JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(ref);
    }

    ref =
        PsiTreeUtil.findElementOfClassAtOffset(
            context.getFile(), context.getTailOffset() - 1, PsiReferenceExpression.class, false);
    makeVariableFinalIfNeeded(context, ref);

    final char completionChar = context.getCompletionChar();
    if (completionChar == '=') {
      context.setAddCompletionChar(false);
      TailType.EQ.processTail(context.getEditor(), context.getTailOffset());
    } else if (completionChar == ','
        && getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
      context.setAddCompletionChar(false);
      TailType.COMMA.processTail(context.getEditor(), context.getTailOffset());
      AutoPopupController.getInstance(context.getProject())
          .autoPopupParameterInfo(context.getEditor(), null);
    } else if (completionChar == ':') {
      context.setAddCompletionChar(false);
      TailType.COND_EXPR_COLON.processTail(context.getEditor(), context.getTailOffset());
    } else if (completionChar == '.') {
      AutoPopupController.getInstance(context.getProject())
          .autoPopupMemberLookup(context.getEditor(), null);
    } else if (completionChar == '!' && PsiType.BOOLEAN.isAssignableFrom(variable.getType())) {
      context.setAddCompletionChar(false);
      if (ref != null) {
        FeatureUsageTracker.getInstance()
            .triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
        document.insertString(ref.getTextRange().getStartOffset(), "!");
      }
    }
  }