@NotNull
  private static List<PyClassLikeType> mroLinearize(@NotNull PyClassLikeType type,
                                                    boolean addThisType,
                                                    @NotNull TypeEvalContext context,
                                                    @NotNull Map<PyClassLikeType, Ref<List<PyClassLikeType>>> cache) throws MROException {
    final Ref<List<PyClassLikeType>> computed = cache.get(type);
    if (computed != null) {
      if (computed.isNull()) {
        throw new MROException("Circular class inheritance");
      }
      return computed.get();
    }
    cache.put(type, Ref.create());
    List<PyClassLikeType> result = null;
    try {
      final List<PyClassLikeType> bases = removeNotNullDuplicates(type.getSuperClassTypes(context));
      final List<List<PyClassLikeType>> lines = new ArrayList<>();
      for (PyClassLikeType base : bases) {
        if (base != null) {
          // Don't include ancestors of a metaclass instance
          final List<PyClassLikeType> baseClassMRO;
          if (base.isDefinition()) {
            baseClassMRO = mroLinearize(base, true, context, cache);
          }
          else {
            List<PyClassLikeType> metaclassInstanceMro = new ArrayList<>();
            metaclassInstanceMro.add(base);
            if (base instanceof PyClassType) {
              final PyClassImpl pyClass = as(((PyClassType)base).getPyClass(), PyClassImpl.class);
              if (pyClass != null) {
                ContainerUtil.addIfNotNull(metaclassInstanceMro, pyClass.getImplicitSuper());
              }
            }
            baseClassMRO = metaclassInstanceMro;
          }
          if (!baseClassMRO.isEmpty()) {
            // mroMerge() updates passed MRO lists internally
            lines.add(new LinkedList<>(baseClassMRO));
          }
        }
      }
      if (!bases.isEmpty()) {
        lines.add(bases);
      }
      result = mroMerge(lines);
      if (addThisType) {
        result.add(0, type);
      }
      result = Collections.unmodifiableList(result);
    }
    finally {
      cache.put(type, Ref.create(result));
    }
    return result;
  }
@NotNull
  private static List<PyClassLikeType> mroLinearize(@NotNull PyClassLikeType type,
                                                    boolean addThisType,
                                                    @NotNull TypeEvalContext context,
                                                    @NotNull Map<PyClassLikeType, Ref<List<PyClassLikeType>>> cache)