private static PsiSubstitutor obtainFinalSubstitutor(
      PsiClass superClass,
      PsiSubstitutor superSubstitutor,
      PsiSubstitutor derivedSubstitutor,
      boolean inRawContext) {
    if (inRawContext) {
      Set<PsiTypeParameter> typeParams = superSubstitutor.getSubstitutionMap().keySet();
      PsiElementFactory factory = JavaPsiFacade.getElementFactory(superClass.getProject());
      superSubstitutor =
          factory.createRawSubstitutor(
              derivedSubstitutor, typeParams.toArray(new PsiTypeParameter[typeParams.size()]));
    }
    Map<PsiTypeParameter, PsiType> map = null;
    for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(superClass)) {
      PsiType type = superSubstitutor.substitute(typeParameter);
      final PsiType t = derivedSubstitutor.substitute(type);
      if (map == null) {
        map = new THashMap<PsiTypeParameter, PsiType>();
      }
      map.put(typeParameter, t);
    }

    return map == null
        ? PsiSubstitutor.EMPTY
        : JavaPsiFacade.getInstance(superClass.getProject())
            .getElementFactory()
            .createSubstitutor(map);
  }
 @NotNull
 @Override
 public PsiClassType rawType() {
   PsiClass psiClass = resolve();
   PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject());
   return factory.createType(psiClass, factory.createRawSubstitutor(psiClass));
 }
 private static PsiSubstitutor checkRaw(
     boolean isRaw,
     @NotNull PsiElementFactory factory,
     @NotNull PsiMethod candidateMethod,
     @NotNull PsiSubstitutor substitutor) {
   if (isRaw
       && !candidateMethod.hasModifierProperty(
           PsiModifier.STATIC)) { // static methods are not erased due to raw overriding
     PsiTypeParameter[] methodTypeParameters = candidateMethod.getTypeParameters();
     substitutor = factory.createRawSubstitutor(substitutor, methodTypeParameters);
   }
   return substitutor;
 }
 public static PsiSubstitutor obtainFinalSubstitutor(
     @NotNull PsiClass candidateClass,
     @NotNull PsiSubstitutor candidateSubstitutor,
     @NotNull PsiClass aClass,
     @NotNull PsiSubstitutor substitutor,
     @NotNull PsiElementFactory elementFactory,
     @NotNull LanguageLevel languageLevel) {
   if (PsiUtil.isRawSubstitutor(aClass, substitutor)) {
     return elementFactory.createRawSubstitutor(candidateClass);
   }
   final PsiType containingType =
       elementFactory.createType(candidateClass, candidateSubstitutor, languageLevel);
   PsiType type = substitutor.substitute(containingType);
   if (!(type instanceof PsiClassType)) return candidateSubstitutor;
   return ((PsiClassType) type).resolveGenerics().getSubstitutor();
 }
  public static PsiType buildTypeFromTypeString(
      @NotNull final String typeName,
      @NotNull final PsiElement context,
      @NotNull final PsiFile psiFile) {
    PsiType resultType;
    final PsiManager psiManager = psiFile.getManager();

    if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) {
      try {
        return JavaPsiFacade.getInstance(psiManager.getProject())
            .getElementFactory()
            .createTypeFromText(typeName, context);
      } catch (Exception ignored) {
      } // invalid syntax will produce unresolved class type
    }

    PsiClass aClass =
        JavaPsiFacade.getInstance(psiManager.getProject())
            .findClass(typeName, context.getResolveScope());

    if (aClass == null) {
      final LightClassReference ref =
          new LightClassReference(
              psiManager,
              PsiNameHelper.getShortClassName(typeName),
              typeName,
              PsiSubstitutor.EMPTY,
              psiFile);
      resultType = new PsiClassReferenceType(ref, null);
    } else {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
      PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass);
      resultType = factory.createType(aClass, substitutor);
    }

    return resultType;
  }