private void processVariableType(PsiVariable variable) {
    final PsiTypeElement type = variable.getTypeElement();
    final PsiExpression initializer = variable.getInitializer();
    if (initializer != null) {
      addLink(type, initializer);
    }

    for (PsiReference ref : ReferencesSearch.search(variable)) {
      final PsiElement element = ref.getElement();
      addLink(element, type);
      addLink(type, element);
      analyzeVarUsage(element);
    }

    if (variable instanceof PsiParameter) {
      final PsiElement declScope = ((PsiParameter)variable).getDeclarationScope();
      if (declScope instanceof PsiCatchSection) {
        markNode(type);
      }
      else if (declScope instanceof PsiForeachStatement) {
        final PsiExpression iteratedValue = ((PsiForeachStatement)declScope).getIteratedValue();
        addLink(type, iteratedValue);
      }
      else if (declScope instanceof PsiMethod method) {
        final int index = method.getParameterList().getParameterIndex((PsiParameter)variable);

        {
          for (PsiReference call : ReferencesSearch.search(method)) {
            PsiElement ref = call.getElement();
            PsiExpressionList argumentList;
            if (ref.getParent() instanceof PsiCall) {
              argumentList = ((PsiCall)ref.getParent()).getArgumentList();
            }
            else if (ref.getParent() instanceof PsiAnonymousClass) {
              argumentList = ((PsiConstructorCall)ref.getParent().getParent()).getArgumentList();
            }
            else {
              continue;
            }
            if (argumentList == null) continue;
            PsiExpression[] args = argumentList.getExpressions();
            if (index >= args.length) continue;
            addLink(type, args[index]);
          }
        }

        final class Inner {
          void linkInheritors(final PsiMethod[] methods) {
            for (final PsiMethod superMethod : methods) {
              final PsiParameter[] parameters = superMethod.getParameterList().getParameters();
              if (index >= parameters.length) continue;
              final PsiTypeElement superType = parameters[index].getTypeElement();
              addLink(superType, type);
              addLink(type, superType);
            }
          }
        }

        final PsiMethod[] superMethods = method.findSuperMethods();
        new Inner().linkInheritors(superMethods);
        PsiClass containingClass = method.getContainingClass();
        List<PsiClass> subClasses = new ArrayList<>(ClassInheritorsSearch.search(containingClass, false).findAll());
        // ??? In the theory this is non-efficient way: too many inheritors can be processed.
        // ??? But in real use it seems reasonably fast. If poor performance problems emerged,
        // ??? should be optimized
        for (int i1 = 0; i1 != subClasses.size(); ++i1) {
          final PsiMethod[] mBSs = subClasses.get(i1).findMethodsBySignature(method, true);
          new Inner().linkInheritors(mBSs);
        }
      }
      else {
        LOG.error("Unexpected scope: " + declScope);
      }
    }
    else if (variable instanceof PsiResourceVariable) {
      final PsiJavaParserFacade facade = JavaPsiFacade.getInstance(myProject).getParserFacade();
      checkConstrainingType(type, facade.createTypeFromText(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, variable));
    }
  }
private void processVariableType(PsiVariable variable)