public static boolean resolvesTo(PsiType type, String fqn) {
   if (type instanceof PsiClassType) {
     final PsiClass resolved = ((PsiClassType) type).resolve();
     return resolved != null && fqn.equals(resolved.getQualifiedName());
   }
   return false;
 }
  private static boolean containsAllCases(GrSwitchStatement statement) {
    final GrCaseSection[] sections = statement.getCaseSections();
    for (GrCaseSection section : sections) {
      if (section.isDefault()) return true;
    }

    final GrExpression condition = statement.getCondition();
    if (!(condition instanceof GrReferenceExpression)) return false;

    PsiType type = TypesUtil.unboxPrimitiveTypeWrapper(getNominalTypeNoRecursion(condition));
    if (type == null) return false;

    if (type instanceof PsiPrimitiveType) {
      if (type == PsiType.BOOLEAN) return sections.length == 2;
      if (type == PsiType.BYTE || type == PsiType.CHAR) return sections.length == 128;
      return false;
    }

    if (type instanceof PsiClassType) {
      final PsiClass resolved = ((PsiClassType) type).resolve();
      if (resolved != null && resolved.isEnum()) {
        int enumConstantCount = 0;
        final PsiField[] fields = resolved.getFields();
        for (PsiField field : fields) {
          if (field instanceof PsiEnumConstant) enumConstantCount++;
        }

        if (sections.length == enumConstantCount) return true;
      }
    }

    return false;
  }
 public static boolean isClassType(@Nullable PsiType type, @NotNull String qName) {
   if (type instanceof PsiClassType) {
     final PsiClass psiClass = ((PsiClassType) type).resolve();
     return psiClass != null && qName.equals(psiClass.getQualifiedName());
   }
   return false;
 }
  @Nullable
  public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) {
    final Set<PsiType> expectedTypes = getDefaultExpectedTypes(closure);

    List<PsiType> expectedReturnTypes = new ArrayList<PsiType>();
    for (PsiType expectedType : expectedTypes) {
      if (!(expectedType instanceof PsiClassType)) return null;

      final PsiClassType.ClassResolveResult resolveResult =
          ((PsiClassType) expectedType).resolveGenerics();
      final PsiClass resolved = resolveResult.getElement();
      if (resolved == null
          || !(GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(resolved.getQualifiedName())))
        return null;

      final PsiTypeParameter[] typeParameters = resolved.getTypeParameters();
      if (typeParameters.length != 1) return null;

      final PsiTypeParameter expected = typeParameters[0];
      final PsiType expectedReturnType = resolveResult.getSubstitutor().substitute(expected);
      if (expectedReturnType == PsiType.VOID || expectedReturnType == null) return null;

      expectedReturnTypes.add(expectedReturnType);
    }

    return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager());
  }
 public static PsiType unboxPrimitiveTypeWrapper(@Nullable PsiType type) {
   if (type instanceof PsiClassType) {
     final PsiClass psiClass = ((PsiClassType) type).resolve();
     if (psiClass != null) {
       PsiType unboxed = ourQNameToUnboxed.get(psiClass.getQualifiedName());
       if (unboxed != null) type = unboxed;
     }
   }
   return type;
 }
  @NotNull
  public static PsiType createSetType(@NotNull PsiElement context, @NotNull PsiType type) {
    JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
    GlobalSearchScope resolveScope = context.getResolveScope();

    PsiClass setClass = facade.findClass(JAVA_UTIL_SET, resolveScope);
    if (setClass != null && setClass.getTypeParameters().length == 1) {
      return facade.getElementFactory().createType(setClass, type);
    }

    return facade.getElementFactory().createTypeByFQClassName(JAVA_UTIL_SET, resolveScope);
  }
 @NotNull
 public static PsiClassType createListType(@NotNull PsiClass elements) {
   JavaPsiFacade facade = JavaPsiFacade.getInstance(elements.getProject());
   GlobalSearchScope resolveScope = elements.getResolveScope();
   PsiClass listClass = facade.findClass(JAVA_UTIL_LIST, resolveScope);
   if (listClass == null) {
     return facade.getElementFactory().createTypeByFQClassName(JAVA_UTIL_LIST, resolveScope);
   }
   return facade
       .getElementFactory()
       .createType(listClass, facade.getElementFactory().createType(elements));
 }
  @Nullable
  private static PsiClassType createCollection(
      Project project, String collectionName, PsiType... item) {
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    PsiClass collection =
        JavaPsiFacade.getInstance(project)
            .findClass(collectionName, GlobalSearchScope.allScope(project));
    if (collection == null) return null;

    PsiTypeParameter[] parameters = collection.getTypeParameters();
    if (parameters.length != 1) return null;

    return factory.createType(collection, item);
  }
  public static boolean isAnnotatedCheckHierarchyWithCache(
      @NotNull PsiClass aClass, @NotNull String annotationFQN) {
    Map<String, PsiClass> classMap = getSuperClassesWithCache(aClass);

    for (PsiClass psiClass : classMap.values()) {
      PsiModifierList modifierList = psiClass.getModifierList();
      if (modifierList != null) {
        if (modifierList.findAnnotation(annotationFQN) != null) {
          return true;
        }
      }
    }

    return false;
  }
 @Nullable
 public static PsiType createJavaLangClassType(
     @Nullable PsiType type, Project project, GlobalSearchScope resolveScope) {
   final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
   PsiType result = null;
   PsiClass javaLangClass = facade.findClass(JAVA_LANG_CLASS, resolveScope);
   if (javaLangClass != null) {
     PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
     final PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
     if (typeParameters.length == 1) {
       substitutor = substitutor.put(typeParameters[0], type);
     }
     result = facade.getElementFactory().createType(javaLangClass, substitutor);
   }
   return result;
 }
    @Override
    public void visitAnnotationArrayInitializer(GrAnnotationArrayInitializer arrayInitializer) {
      final GrAnnotationNameValuePair nameValuePair =
          PsiTreeUtil.getParentOfType(
              arrayInitializer,
              GrAnnotationNameValuePair.class,
              true,
              GrDefaultAnnotationValue.class);
      if (nameValuePair != null) {

        final PsiClass annot = ResolveUtil.resolveAnnotation(arrayInitializer);
        if (annot == null) return;

        final String name = nameValuePair.getName();
        if (name == null) return;

        final PsiMethod[] attrs = annot.findMethodsByName(name, false);
        if (attrs.length > 0) {
          PsiType type = attrs[0].getReturnType();
          while (type instanceof PsiArrayType) type = ((PsiArrayType) type).getComponentType();
          if (type != null && isAcceptableAnnotationValueType(type)) {
            myResult = createSimpleSubTypeResult(type);
          }
        }
      } else {
        final GrAnnotationMethod method =
            PsiTreeUtil.getParentOfType(arrayInitializer, GrAnnotationMethod.class);
        assert method != null;

        PsiType type = method.getReturnType();

        int count = 1;
        PsiElement parent = arrayInitializer.getParent();
        while (parent instanceof GrAnnotationArrayInitializer) {
          count++;
          parent = parent.getParent();
        }

        while (type instanceof PsiArrayType && count > 0) {
          type = ((PsiArrayType) type).getComponentType();
          count--;
        }
        if (type != null && isAcceptableAnnotationValueType(type)) {
          myResult = createSimpleSubTypeResult(type);
        }
      }
    }
  public static Map<String, PsiClass> getSuperClassesWithCache(@NotNull PsiClass aClass) {
    Map<String, PsiClass> superClassNames = PARENT_CACHE_KEY.getCachedValue(aClass);
    if (superClassNames == null) {
      Set<PsiClass> superClasses = new THashSet<PsiClass>();
      superClasses.add(aClass);
      InheritanceUtil.getSuperClasses(aClass, superClasses, true);

      superClassNames = new LinkedHashMap<String, PsiClass>();
      for (PsiClass superClass : superClasses) {
        superClassNames.put(superClass.getQualifiedName(), superClass);
      }

      superClassNames = PARENT_CACHE_KEY.putCachedValue(aClass, superClassNames);
    }

    return superClassNames;
  }
  @Nullable
  public static PsiElement getOriginalElement(PsiClass clazz, PsiFile containingFile) {
    VirtualFile vFile = containingFile.getVirtualFile();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(clazz.getProject());
    final ProjectFileIndex idx = ProjectRootManager.getInstance(facade.getProject()).getFileIndex();

    if (vFile == null || !idx.isInLibrarySource(vFile)) return clazz;
    final String qName = clazz.getQualifiedName();
    if (qName == null) return null;
    final List<OrderEntry> orderEntries = idx.getOrderEntriesForFile(vFile);
    PsiClass original =
        facade.findClass(
            qName,
            new GlobalSearchScope(facade.getProject()) {
              public int compare(VirtualFile file1, VirtualFile file2) {
                return 0;
              }

              public boolean contains(VirtualFile file) {
                // order for file and vFile has non empty intersection.
                List<OrderEntry> entries = idx.getOrderEntriesForFile(file);
                //noinspection ForLoopReplaceableByForEach
                for (int i = 0; i < entries.size(); i++) {
                  final OrderEntry entry = entries.get(i);
                  if (orderEntries.contains(entry)) return true;
                }
                return false;
              }

              public boolean isSearchInModuleContent(@NotNull Module aModule) {
                return false;
              }

              public boolean isSearchInLibraries() {
                return true;
              }
            });

    return original != null ? original : clazz;
  }
  @Nullable
  private static Boolean isAssignableForNativeTypes(
      @NotNull PsiType lType, @NotNull PsiClassType rType, @NotNull PsiElement context) {
    if (!(lType instanceof PsiClassType)) return null;
    final PsiClassType.ClassResolveResult leftResult = ((PsiClassType) lType).resolveGenerics();
    final PsiClassType.ClassResolveResult rightResult = rType.resolveGenerics();
    final PsiClass leftClass = leftResult.getElement();
    PsiClass rightClass = rightResult.getElement();
    if (rightClass == null || leftClass == null) return null;

    if (!InheritanceUtil.isInheritorOrSelf(rightClass, leftClass, true)) return Boolean.FALSE;

    PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor();

    if (!leftClass.hasTypeParameters()) return Boolean.TRUE;
    PsiSubstitutor leftSubstitutor = leftResult.getSubstitutor();

    if (!leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) {
      rightSubstitutor =
          TypeConversionUtil.getSuperClassSubstitutor(leftClass, rightClass, rightSubstitutor);
      rightClass = leftClass;
    } else if (!rightClass.hasTypeParameters()) return Boolean.TRUE;

    Iterator<PsiTypeParameter> li = PsiUtil.typeParametersIterator(leftClass);
    Iterator<PsiTypeParameter> ri = PsiUtil.typeParametersIterator(rightClass);
    while (li.hasNext()) {
      if (!ri.hasNext()) return Boolean.FALSE;
      PsiTypeParameter lp = li.next();
      PsiTypeParameter rp = ri.next();
      final PsiType typeLeft = leftSubstitutor.substitute(lp);
      if (typeLeft == null) continue;
      final PsiType typeRight = rightSubstitutor.substituteWithBoundsPromotion(rp);
      if (typeRight == null) {
        return Boolean.TRUE;
      }
      if (!isAssignableWithoutConversions(typeLeft, typeRight, context)) return Boolean.FALSE;
    }
    return Boolean.TRUE;
  }
    @Override
    public void visitAnnotationNameValuePair(GrAnnotationNameValuePair nameValuePair) {
      if (myExpression.equals(nameValuePair.getValue())) {
        final PsiClass annot = ResolveUtil.resolveAnnotation(nameValuePair.getParent());
        if (annot != null) {
          final String name = nameValuePair.getName();
          if (name != null) {
            final PsiMethod[] attrs = annot.findMethodsByName(name, false);
            if (attrs.length > 0) {
              PsiType type = attrs[0].getReturnType();
              while (type instanceof PsiArrayType) type = ((PsiArrayType) type).getComponentType();
              if (type != null && isAcceptableAnnotationValueType(type)) {
                myResult = createSimpleSubTypeResult(type);
              }
            }
          } else {
            final PsiMethod[] valueAttr = annot.findMethodsByName("value", false);
            boolean canHaveSimpleExpr = valueAttr.length > 0;
            final PsiMethod[] methods = annot.getMethods();
            for (PsiMethod method : methods) {
              if (!("value".equals(method.getName())
                  || method instanceof PsiAnnotationMethod
                      && ((PsiAnnotationMethod) method).getDefaultValue() != null)) {
                canHaveSimpleExpr = false;
              }
            }

            if (canHaveSimpleExpr) {
              PsiType type = valueAttr[0].getReturnType();
              while (type instanceof PsiArrayType) type = ((PsiArrayType) type).getComponentType();
              if (type != null && isAcceptableAnnotationValueType(type)) {
                myResult = createSimpleSubTypeResult(type);
              }
            }
          }
        }
      }
    }
 private static boolean isFromDGM(GrGdkMethod resolved) {
   final PsiClass containingClass = resolved.getStaticMethod().getContainingClass();
   return containingClass != null
       && GroovyCommonClassNames.DEFAULT_GROOVY_METHODS.equals(containingClass.getQualifiedName());
 }