private static boolean containsError(PsiAnnotation annotation) {
      final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
      if (nameRef == null) {
        return true;
      }
      final PsiClass aClass = (PsiClass) nameRef.resolve();
      if (aClass == null || !aClass.isAnnotationType()) {
        return true;
      }
      final Set<String> names = new HashSet<String>();
      final PsiAnnotationParameterList annotationParameterList = annotation.getParameterList();
      if (PsiUtilCore.hasErrorElementChild(annotationParameterList)) {
        return true;
      }
      final PsiNameValuePair[] attributes = annotationParameterList.getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final PsiReference reference = attribute.getReference();
        if (reference == null) {
          return true;
        }
        final PsiMethod method = (PsiMethod) reference.resolve();
        if (method == null) {
          return true;
        }
        final PsiAnnotationMemberValue value = attribute.getValue();
        if (value == null || PsiUtilCore.hasErrorElementChild(value)) {
          return true;
        }
        if (value instanceof PsiAnnotation && containsError((PsiAnnotation) value)) {
          return true;
        }
        if (!hasCorrectType(value, method.getReturnType())) {
          return true;
        }
        final String name = attribute.getName();
        if (!names.add(name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME)) {
          return true;
        }
      }

      for (PsiMethod method : aClass.getMethods()) {
        if (!(method instanceof PsiAnnotationMethod)) {
          continue;
        }
        final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
        if (annotationMethod.getDefaultValue() == null
            && !names.contains(annotationMethod.getName())) {
          return true; // missing a required argument
        }
      }
      return false;
    }
  @Nullable
  public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) {
    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;
    PsiClass aClass = (PsiClass) nameRef.resolve();
    if (aClass != null && aClass.isAnnotationType()) {
      Set<String> names = new HashSet<String>();
      PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final String name = attribute.getName();
        if (name != null) {
          names.add(name);
        } else {
          names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
        }
      }

      PsiMethod[] annotationMethods = aClass.getMethods();
      List<String> missed = new ArrayList<String>();
      for (PsiMethod method : annotationMethods) {
        if (PsiUtil.isAnnotationMethod(method)) {
          PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
          if (annotationMethod.getDefaultValue() == null) {
            if (!names.contains(annotationMethod.getName())) {
              missed.add(annotationMethod.getName());
            }
          }
        }
      }

      if (!missed.isEmpty()) {
        StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'");
        for (int i = 1; i < missed.size(); i++) {
          buff.append(", ");
          buff.append("'").append(missed.get(i)).append("'");
        }

        String description = JavaErrorMessages.message("annotation.missing.attribute", buff);
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(nameRef)
            .descriptionAndTooltip(description)
            .create();
      }
    }

    return null;
  }
 @Nullable
 public static HighlightInfo checkAnnotationDeclaration(
     final PsiElement parent, final PsiReferenceList list) {
   if (PsiUtil.isAnnotationMethod(parent)) {
     PsiAnnotationMethod method = (PsiAnnotationMethod) parent;
     if (list == method.getThrowsList()) {
       String description =
           JavaErrorMessages.message("annotation.members.may.not.have.throws.list");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(list)
           .descriptionAndTooltip(description)
           .create();
     }
   } else if (parent instanceof PsiClass && ((PsiClass) parent).isAnnotationType()) {
     if (PsiKeyword.EXTENDS.equals(list.getFirstChild().getText())) {
       String description = JavaErrorMessages.message("annotation.may.not.have.extends.list");
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
           .range(list)
           .descriptionAndTooltip(description)
           .create();
     }
   }
   return null;
 }
 public static HighlightInfo checkClashesWithSuperMethods(@NotNull PsiAnnotationMethod psiMethod) {
   final PsiIdentifier nameIdentifier = psiMethod.getNameIdentifier();
   if (nameIdentifier != null) {
     final PsiMethod[] methods = psiMethod.findDeepestSuperMethods();
     for (PsiMethod method : methods) {
       final PsiClass containingClass = method.getContainingClass();
       if (containingClass != null) {
         final String qualifiedName = containingClass.getQualifiedName();
         if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)
             || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) {
           return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
               .range(nameIdentifier)
               .descriptionAndTooltip(
                   "@interface member clashes with '"
                       + JavaHighlightUtil.formatMethod(method)
                       + "' in "
                       + HighlightUtil.formatClass(containingClass))
               .create();
         }
       }
     }
   }
   return null;
 }