@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;
  }
 @Nullable
 private PsiElement findAnchor(String name) {
   final int myPriority = PRIORITY.get(name);
   final PsiElement[] modifiers = getModifiers();
   PsiElement anchor = null;
   for (int i = modifiers.length - 1; i >= 0; i--) {
     PsiElement modifier = modifiers[i];
     if (PRIORITY.get(modifier.getText()) <= myPriority) {
       anchor = modifier;
       break;
     }
   }
   return anchor;
 }
 @Nullable
 public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) {
   final GrModifierListStub stub = getStub();
   if (stub != null) {
     for (StubElement stubElement : stub.getChildrenStubs()) {
       final PsiElement child = stubElement.getPsi();
       if (child instanceof PsiAnnotation
           && qualifiedName.equals(((PsiAnnotation) child).getQualifiedName())) {
         return (PsiAnnotation) child;
       }
     }
   } else {
     PsiElement child = getFirstChild();
     while (child != null) {
       if (child instanceof PsiAnnotation
           && qualifiedName.equals(((PsiAnnotation) child).getQualifiedName())) {
         return (PsiAnnotation) child;
       }
       child = child.getNextSibling();
     }
   }
   return null;
 }
  private void setModifierPropertyInternal(String name, boolean doSet) {
    if (doSet) {
      PsiElement modifier =
          GroovyPsiElementFactory.getInstance(getProject()).createModifierFromText(name);
      PsiElement anchor = findAnchor(name);
      addAfter(modifier, anchor);
    } else {
      final PsiElement[] modifiers = findChildrenByType(TokenSets.MODIFIERS, PsiElement.class);
      for (PsiElement modifier : modifiers) {
        if (name.equals(modifier.getText())) {
          deleteChildRange(modifier, modifier);
          break;
        }
      }

      if (getTextLength() == 0) {
        final PsiElement nextSibling = getNextSibling();
        if (nextSibling != null
            && TokenSets.WHITE_SPACES_SET.contains(nextSibling.getNode().getElementType())) {
          nextSibling.delete();
        }
      }
    }
  }
  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;
  }