protected void resolveBounds(final Collection<InferenceVariable> inferenceVariables,
                             @NotNull PsiSubstitutor substitutor) {
    final UniqueNameGenerator uniqueNameGenerator = new UniqueNameGenerator();
    final List<InferenceVariable> allVars = new ArrayList<>(inferenceVariables);
    Map<InferenceVariable, Set<InferenceVariable>> dependencies = InferenceVariablesOrder.getDependencies(allVars, this);
    while (!allVars.isEmpty()) {
      final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, dependencies);
      List<InferenceVariable> unresolved = new ArrayList<>();
      for (InferenceVariable var : vars) {
        final PsiType eqBound = getEqualsBound(var, substitutor);
        if (eqBound == PsiTypes.nullType()) {
          unresolved.add(var);
        }
      }
      if (!unresolved.isEmpty() && vars.size() > unresolved.size()) {
        vars.removeAll(unresolved);
        vars.addAll(unresolved);
      }
      if (!myIncorporationPhase.hasCaptureConstraints(unresolved)) {
        PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
        if (myErrorMessages == null && hasBoundProblems(vars, firstSubstitutor)) {
          firstSubstitutor = null;
          unresolved = vars;
        }
        if (firstSubstitutor != null) {
          substitutor = firstSubstitutor;
          allVars.removeAll(vars);
          continue;
        }
      }

      if (!initFreshVariables(substitutor, unresolved, uniqueNameGenerator)) {
        return;
      }

      myIncorporationPhase.forgetCaptures(vars);
      if (!repeatInferencePhases()) {
        return;
      }
    }

    final Map<PsiTypeParameter, PsiType> map = substitutor.getSubstitutionMap();
    for (PsiTypeParameter parameter : map.keySet()) {
      final PsiType mapping = map.get(parameter);
      PsiTypeParameter param;
      if (parameter instanceof InferenceVariable) {
        ((InferenceVariable)parameter).setInstantiation(mapping);
        if (((InferenceVariable)parameter).getCallContext() != myContext) {
          //don't include in result substitutor foreign inference variables
          continue;
        }
        param = ((InferenceVariable)parameter).getParameter();
      }
      else {
        param = parameter;
      }
      mySiteSubstitutor = mySiteSubstitutor.put(param, mapping);
    }
  }
protected void resolveBounds(final Collection<InferenceVariable> inferenceVariables,
                             @NotNull PsiSubstitutor substitutor)