@NotNull
  public GrAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
    final PsiClass psiClass =
        JavaPsiFacade.getInstance(getProject()).findClass(qualifiedName, getResolveScope());
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject());
    GrAnnotation annotation;
    if (psiClass != null && psiClass.isAnnotationType()) {
      annotation = (GrAnnotation) addAfter(factory.createModifierFromText("@xxx"), null);
      annotation.getClassReference().bindToElement(psiClass);
    } else {
      annotation =
          (GrAnnotation) addAfter(factory.createModifierFromText("@" + qualifiedName), null);
    }

    final PsiElement parent = getParent();
    if (!(parent instanceof GrParameter)) {
      final ASTNode node = annotation.getNode();
      final ASTNode treeNext = node.getTreeNext();
      if (treeNext != null) {
        getNode().addLeaf(TokenType.WHITE_SPACE, "\n", treeNext);
      } else {
        parent.getNode().addLeaf(TokenType.WHITE_SPACE, "\n", getNode().getTreeNext());
      }
    }

    return annotation;
  }
  public static boolean checkModifierProperty(
      @NotNull GrModifierList modifierList,
      @GrModifier.GrModifierConstant @NotNull String modifier) {
    final PsiElement owner = modifierList.getParent();
    if (owner instanceof GrVariableDeclaration
        && owner.getParent() instanceof GrTypeDefinitionBody) {
      PsiElement pParent = owner.getParent().getParent();
      if (!modifierList
          .hasExplicitVisibilityModifiers()) { // properties are backed by private fields
        if (!(pParent instanceof PsiClass) || !((PsiClass) pParent).isInterface()) {
          if (modifier.equals(GrModifier.PRIVATE)) return true;
          if (modifier.equals(GrModifier.PROTECTED)) return false;
          if (modifier.equals(GrModifier.PUBLIC)) return false;
        }
      }

      if (pParent instanceof PsiClass && ((PsiClass) pParent).isInterface()) {
        if (modifier.equals(GrModifier.STATIC)) return true;
        if (modifier.equals(GrModifier.FINAL)) return true;
      }
      if (pParent instanceof GrTypeDefinition) {
        PsiModifierList pModifierList = ((GrTypeDefinition) pParent).getModifierList();
        if (pModifierList != null
            && pModifierList.findAnnotation(ConstructorAnnotationsProcessor.IMMUTABLE) != null) {
          if (modifier.equals(GrModifier.FINAL)) return true;
        }
      }
    }

    // top level classes cannot have private and protected modifiers
    if (owner instanceof GrTypeDefinition
        && ((GrTypeDefinition) owner).getContainingClass() == null) {
      if (modifier.equals(PROTECTED) || modifier.equals(PRIVATE)) return false;
      if (modifier.equals(PACKAGE_LOCAL))
        return modifierList.hasExplicitModifier(PRIVATE)
            || modifierList.hasExplicitModifier(PROTECTED);
    }

    if (modifierList.hasExplicitModifier(modifier)) {
      return true;
    }

    if (modifier.equals(GrModifier.PUBLIC)) {
      if (owner instanceof GrPackageDefinition) return false;
      if (owner instanceof GrVariableDeclaration
              && !(owner.getParent() instanceof GrTypeDefinitionBody)
          || owner instanceof GrVariable) {
        return false;
      }
      // groovy type definitions and methods are public by default
      return !modifierList.hasExplicitModifier(GrModifier.PRIVATE)
          && !modifierList.hasExplicitModifier(GrModifier.PROTECTED);
    }

    if (owner instanceof GrTypeDefinition) {
      if (modifier.equals(GrModifier.STATIC)) {
        final PsiClass containingClass = ((GrTypeDefinition) owner).getContainingClass();
        return containingClass != null && containingClass.isInterface();
      }
      if (modifier.equals(GrModifier.ABSTRACT)) {
        return ((GrTypeDefinition) owner).isInterface();
      }
    }

    return false;
  }