@NotNull
 private static MultiMap<String, GoImportSpec> collectImportsWithSameString(
     @NotNull Collection<GoImportSpec> importsWithSameName) {
   MultiMap<String, GoImportSpec> importsWithSameString = MultiMap.create();
   for (PsiElement duplicateCandidate : importsWithSameName) {
     GoImportSpec importSpec = getImportSpec(duplicateCandidate);
     if (importSpec != null) {
       importsWithSameString.putValue(importSpec.getPath(), importSpec);
     }
   }
   return importsWithSameString;
 }
 @NotNull
 public static Set<PsiElement> findRedundantImportIdentifiers(
     @NotNull MultiMap<String, GoImportSpec> importMap) {
   Set<PsiElement> importIdentifiersToDelete = ContainerUtil.newLinkedHashSet();
   for (PsiElement importEntry : importMap.values()) {
     GoImportSpec importSpec = getImportSpec(importEntry);
     if (importSpec != null) {
       String localPackageName = importSpec.getLocalPackageName();
       if (!StringUtil.isEmpty(localPackageName)) {
         if (Comparing.equal(importSpec.getAlias(), localPackageName)) {
           importIdentifiersToDelete.add(importSpec.getIdentifier());
         }
       }
     }
   }
   return importIdentifiersToDelete;
 }
 private static boolean hasImportUsers(@NotNull GoImportSpec spec) {
   //noinspection SynchronizationOnLocalVariableOrMethodParameter
   synchronized (spec) {
     List<PsiElement> list = spec.getUserData(GoReferenceBase.IMPORT_USERS);
     if (list != null) {
       for (PsiElement e : list) {
         if (e.isValid()) {
           return true;
         }
         ProgressManager.checkCanceled();
       }
     }
   }
   return false;
 }
  public static MultiMap<String, GoImportSpec> filterUnusedImports(
      @NotNull PsiFile file, @NotNull MultiMap<String, GoImportSpec> importMap) {
    MultiMap<String, GoImportSpec> result = MultiMap.create();
    result.putAllValues(importMap);
    result.remove("_"); // imports for side effects are always used

    Collection<GoImportSpec> implicitImports = ContainerUtil.newArrayList(result.get("."));
    for (GoImportSpec importEntry : implicitImports) {
      GoImportSpec spec = getImportSpec(importEntry);
      if (spec != null && spec.isDot() && hasImportUsers(spec)) {
        result.remove(".", importEntry);
      }
    }

    file.accept(
        new GoRecursiveVisitor() {
          @Override
          public void visitTypeReferenceExpression(@NotNull GoTypeReferenceExpression o) {
            GoTypeReferenceExpression lastQualifier = o.getQualifier();
            if (lastQualifier != null) {
              GoTypeReferenceExpression previousQualifier;
              while ((previousQualifier = lastQualifier.getQualifier()) != null) {
                lastQualifier = previousQualifier;
              }
              markAsUsed(lastQualifier.getIdentifier(), lastQualifier.getReference());
            }
          }

          @Override
          public void visitReferenceExpression(@NotNull GoReferenceExpression o) {
            GoReferenceExpression lastQualifier = o.getQualifier();
            if (lastQualifier != null) {
              GoReferenceExpression previousQualifier;
              while ((previousQualifier = lastQualifier.getQualifier()) != null) {
                lastQualifier = previousQualifier;
              }
              markAsUsed(lastQualifier.getIdentifier(), lastQualifier.getReference());
            }
          }

          private void markAsUsed(@NotNull PsiElement qualifier, @NotNull PsiReference reference) {
            String qualifierText = qualifier.getText();
            if (!result.containsKey(qualifierText)) {
              // already marked
              return;
            }
            PsiElement resolve = reference.resolve();
            if (!(resolve instanceof PsiDirectory
                || resolve instanceof GoImportSpec
                || resolve instanceof PsiDirectoryContainer)) {
              return;
            }
            Collection<String> qualifiersToDelete = ContainerUtil.newHashSet();
            for (GoImportSpec spec : result.get(qualifierText)) {
              for (Map.Entry<String, Collection<GoImportSpec>> entry : result.entrySet()) {
                for (GoImportSpec importSpec : entry.getValue()) {
                  if (importSpec == spec) {
                    qualifiersToDelete.add(entry.getKey());
                  }
                }
              }
            }
            for (String qualifierToDelete : qualifiersToDelete) {
              result.remove(qualifierToDelete);
            }
          }
        });
    return result;
  }