SmartTypePointer (@NotNull PsiClassType classType) { final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); final PsiClass aClass = resolveResult.getElement(); if (aClass == null) { return createClassReferenceTypePointer(classType); } final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); final HashMap<SmartPsiElementPointer<PsiTypeParameter>, SmartTypePointer> pointerMap = new HashMap<>(); final Map<PsiTypeParameter, PsiType> map = new HashMap<>(); for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) { final PsiType substitutionResult = substitutor.substitute(typeParameter); if (substitutionResult != null) { final SmartPsiElementPointer<PsiTypeParameter> pointer = myPsiPointerManager.createSmartPsiElementPointer(typeParameter); SmartTypePointer typePointer = substitutionResult.accept(this); pointerMap.put(pointer, typePointer); map.put(typeParameter, typePointer.getType()); } else { map.put(typeParameter, null); } } SmartPsiElementPointer<?>[] annotationPointers = Stream .of(classType.getAnnotations()) .map(myPsiPointerManager::createSmartPsiElementPointer) .toArray(SmartPsiElementPointer<?>[]::new); LanguageLevel languageLevel = classType.getLanguageLevel(); return new ClassTypePointer(new PsiImmediateClassType(aClass, PsiSubstitutor.createSubstitutor(map), languageLevel, classType.getAnnotations()), myPsiPointerManager.createSmartPsiElementPointer(aClass), languageLevel, pointerMap, annotationPointers); }