void bindTypeParameters(PsiType formal, final PsiType actual) {
      if (formal instanceof PsiWildcardType) {
        if (actual instanceof PsiCapturedWildcardType &&
            ((PsiWildcardType)formal).isExtends() == ((PsiCapturedWildcardType)actual).getWildcard().isExtends()) {
          bindTypeParameters(((PsiWildcardType)formal).getBound(), ((PsiCapturedWildcardType)actual).getWildcard().getBound());
          return;
        } else {
          formal = ((PsiWildcardType)formal).getBound();
        }
      }

      if (formal instanceof PsiArrayType && actual instanceof PsiArrayType) {
        bindTypeParameters(((PsiArrayType)formal).getComponentType(), ((PsiArrayType)actual).getComponentType());
        return;
      }

      final Pair<PsiType, PsiType> typePair = myRules.bindTypeParameters(formal, actual, myMethod, myCall, myLabeler);
      if (typePair != null) {
        bindTypeParameters(typePair.getFirst(), typePair.getSecond());
        return;
      }

      final PsiClassType.ClassResolveResult resultF = resolveType(formal);
      final PsiClass classF = resultF.getElement();
      if (classF != null) {

        if (classF instanceof PsiTypeParameter) {
          update((PsiTypeParameter)classF, actual);
          return;
        }

        final PsiClassType.ClassResolveResult resultA = resolveType(actual);

        final PsiClass classA = resultA.getElement();
        if (classA == null) {
          return;
        }


        if (!classA.equals(classF)) {
          final PsiSubstitutor superClassSubstitutor =
              TypeConversionUtil.getClassSubstitutor(classF, classA, resultA.getSubstitutor());
          if (superClassSubstitutor != null) {
            final PsiType aligned = JavaPsiFacade.getElementFactory(classF.getProject()).createType(classF, superClassSubstitutor);
            bindTypeParameters(formal, aligned);
          }
        }

        final PsiTypeParameter[] typeParms = classA.getTypeParameters();
        final PsiSubstitutor substA = resultA.getSubstitutor();
        final PsiSubstitutor substF = resultF.getSubstitutor();

        for (PsiTypeParameter typeParm : typeParms) {
          bindTypeParameters(substF.substitute(typeParm), substA.substitute(typeParm));
        }
      }
    }
void bindTypeParameters(PsiType formal, final PsiType actual)