private static StringBuilder buildAttributeValueText(
     PsiAnnotationMemberValue value, StringBuilder out) {
   if (value instanceof PsiArrayInitializerMemberValue) {
     final PsiArrayInitializerMemberValue arrayValue = (PsiArrayInitializerMemberValue) value;
     final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers();
     if (initializers.length == 1) {
       return out.append(initializers[0].getText());
     }
   } else if (value instanceof PsiAnnotation) {
     return out.append(buildAnnotationText((PsiAnnotation) value));
   }
   return out.append(value.getText());
 }
  @Nullable
  private CompileTimeConstant<?> getCompileTimeConstFromArrayExpression(
      FqName annotationFqName,
      Name valueName,
      PsiArrayInitializerMemberValue value,
      PostponedTasks taskList) {
    PsiAnnotationMemberValue[] initializers = value.getInitializers();
    List<CompileTimeConstant<?>> values =
        getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers);

    ClassDescriptor classDescriptor =
        classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);

    // TODO: nullability issues
    ValueParameterDescriptor valueParameterDescriptor =
        DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(
            valueName, classDescriptor);
    if (valueParameterDescriptor == null) {
      return null;
    }
    JetType expectedArrayType = valueParameterDescriptor.getType();
    return new ArrayValue(values, expectedArrayType);
  }
 @Override
 public void visitAnnotation(PsiAnnotation annotation) {
   super.visitAnnotation(annotation);
   final PsiAnnotationParameterList parameterList = annotation.getParameterList();
   final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
   if (nameReferenceElement == null) {
     return;
   }
   final PsiNameValuePair[] attributes = parameterList.getAttributes();
   final PsiElement[] annotationChildren = annotation.getChildren();
   if (annotationChildren.length >= 2
       && annotationChildren[1] instanceof PsiWhiteSpace
       && !containsError(annotation)) {
     registerError(annotationChildren[1], Boolean.TRUE);
   }
   if (attributes.length == 0) {
     if (parameterList.getChildren().length > 0 && !containsError(annotation)) {
       registerError(parameterList, ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE);
     }
   } else if (attributes.length == 1) {
     final PsiNameValuePair attribute = attributes[0];
     final PsiIdentifier identifier = attribute.getNameIdentifier();
     final PsiAnnotationMemberValue attributeValue = attribute.getValue();
     if (identifier != null && attributeValue != null) {
       @NonNls final String name = attribute.getName();
       if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(name)
           && !containsError(annotation)) {
         registerErrorAtOffset(
             attribute,
             0,
             attributeValue.getStartOffsetInParent(),
             ProblemHighlightType.LIKE_UNUSED_SYMBOL,
             Boolean.FALSE);
       }
     }
     if (!(attributeValue instanceof PsiArrayInitializerMemberValue)) {
       return;
     }
     final PsiArrayInitializerMemberValue arrayValue =
         (PsiArrayInitializerMemberValue) attributeValue;
     final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers();
     if (initializers.length != 1) {
       return;
     }
     if (!containsError(annotation)) {
       registerError(
           arrayValue.getFirstChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE);
       registerError(
           arrayValue.getLastChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE);
     }
   } else if (attributes.length > 1) {
     for (PsiNameValuePair attribute : attributes) {
       final PsiAnnotationMemberValue value = attribute.getValue();
       if (!(value instanceof PsiArrayInitializerMemberValue)) {
         continue;
       }
       final PsiArrayInitializerMemberValue arrayValue = (PsiArrayInitializerMemberValue) value;
       final PsiAnnotationMemberValue[] initializers = arrayValue.getInitializers();
       if (initializers.length != 1) {
         continue;
       }
       if (!containsError(annotation)) {
         registerError(
             arrayValue.getFirstChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE);
         registerError(
             arrayValue.getLastChild(), ProblemHighlightType.LIKE_UNUSED_SYMBOL, Boolean.FALSE);
       }
     }
   }
 }
  /**
   * Determines the PsiModifierListOwner for the passed element depending of the specified
   * LookupType. The LookupType decides whether to prefer the element a reference expressions
   * resolves to, or the element that is implied by the usage context ("expected type").
   */
  @Nullable
  public static PsiModifierListOwner getAnnotatedElementFor(
      @Nullable PsiElement element, LookupType type) {
    while (element != null) {
      if (type == LookupType.PREFER_DECLARATION || type == LookupType.DECLARATION_ONLY) {
        if (element instanceof PsiReferenceExpression) {
          final PsiElement e = ((PsiReferenceExpression) element).resolve();
          if (e instanceof PsiModifierListOwner) {
            return (PsiModifierListOwner) e;
          }
          if (type == LookupType.DECLARATION_ONLY) {
            return null;
          }
        }
      }
      element = ContextComputationProcessor.getTopLevelInjectionTarget(element);
      final PsiElement parent = element.getParent();

      if (element instanceof PsiAssignmentExpression
          && ((PsiAssignmentExpression) element).getOperationTokenType() == JavaTokenType.PLUSEQ) {
        element = ((PsiAssignmentExpression) element).getLExpression();
        continue;
      } else if (parent instanceof PsiAssignmentExpression) {
        final PsiAssignmentExpression p = (PsiAssignmentExpression) parent;
        if (p.getRExpression() == element) {
          element = p.getLExpression();
          continue;
        }
      } else if (parent instanceof PsiReturnStatement) {
        final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
        if (m != null) {
          return m;
        }
      } else if (parent instanceof PsiModifierListOwner) {
        return (PsiModifierListOwner) parent;
      } else if (parent instanceof PsiArrayInitializerMemberValue) {
        final PsiArrayInitializerMemberValue value = (PsiArrayInitializerMemberValue) parent;
        final PsiElement pair = value.getParent();
        if (pair instanceof PsiNameValuePair) {
          return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) pair);
        }
      } else if (parent instanceof PsiNameValuePair) {
        return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) parent);
      } else {
        return PsiUtilEx.getParameterForArgument(element);
      }

      // If no annotation has been found through the usage context, check if the element
      // (i.e. the element the reference refers to) is annotated itself
      if (type != LookupType.DECLARATION_ONLY) {
        if (element instanceof PsiReferenceExpression) {
          final PsiElement e = ((PsiReferenceExpression) element).resolve();
          if (e instanceof PsiModifierListOwner) {
            return (PsiModifierListOwner) e;
          }
        }
      }
      return null;
    }
    return null;
  }