public static @NotNull List<DomElementProblemDescriptor> checkExtendClass(final GenericDomValue element,
                                                                            final PsiClass value,
                                                                            final String[] names,
                                                                            final boolean instantiatable,
                                                                            final boolean canBeDecorator,
                                                                            final boolean allowInterface,
                                                                            final boolean allowNonPublic,
                                                                            final boolean allowAbstract,
                                                                            final boolean allowEnum,
                                                                            final DomElementAnnotationHolder holder) {
    final Project project = element.getManager().getProject();
    Set<PsiClass> toExtend =
      Arrays.stream(names)
        .filter(Objects::nonNull)
        .map(s -> JavaPsiFacade.getInstance(project).findClass(s, GlobalSearchScope.allScope(project)))
        .filter(Objects::nonNull)
        .collect(Collectors.toSet());

    final SmartList<DomElementProblemDescriptor> list = new SmartList<>();
    if (toExtend.size() > 0) {
      if (!Arrays.asList(names).contains(value.getQualifiedName())
          && ContainerUtil.find(toExtend, aClass -> value.isInheritor(aClass, true)) == null) {
        String message = JavaBundle.message("class.is.not.a.subclass", value.getQualifiedName(), StringUtil.join(names, ","));
        list.add(holder.createProblem(element, message));
      }
    }

    if (instantiatable) {
      if (value.hasModifierProperty(PsiModifier.ABSTRACT)) {
        list.add(holder.createProblem(element, JavaBundle.message("class.is.not.concrete", value.getQualifiedName())));
      }
      else if (!allowNonPublic && !value.hasModifierProperty(PsiModifier.PUBLIC)) {
        list.add(holder.createProblem(element, JavaBundle.message("class.is.not.public", value.getQualifiedName())));
      }
      else if (!PsiUtil.hasDefaultConstructor(value, true, true)) {
        if (canBeDecorator) {
          boolean hasConstructor = false;

          for (PsiMethod method : value.getConstructors()) {
            final PsiParameterList psiParameterList = method.getParameterList();
            if (psiParameterList.getParametersCount() != 1) continue;
            PsiTypeElement typeElement = psiParameterList.getParameters()[0].getTypeElement();
            if (typeElement != null) {
              final PsiType psiType = typeElement.getType();
              if (psiType instanceof PsiClassType) {
                final PsiClass psiClass = ((PsiClassType)psiType).resolve();
                if (psiClass != null &&
                    ContainerUtil.find(toExtend, aClass -> InheritanceUtil.isInheritorOrSelf(psiClass, aClass, true)) != null) {
                  hasConstructor = true;
                  break;
                }
              }
            }
          }
          if (!hasConstructor) {
            list.add(
              holder.createProblem(element, JavaBundle.message("class.decorator.or.has.default.constructor", value.getQualifiedName())));
          }
        }
        else {
          list.add(holder.createProblem(element, JavaBundle.message("class.has.no.default.constructor", value.getQualifiedName())));
        }
      }
    }
    if (!allowInterface && value.isInterface()) {
      list.add(holder.createProblem(element, JavaBundle.message("interface.not.allowed", value.getQualifiedName())));
    }
    if (!allowEnum && value.isEnum()) {
      list.add(holder.createProblem(element, JavaBundle.message("enum.not.allowed", value.getQualifiedName())));
    }
    if (!allowAbstract && value.hasModifierProperty(PsiModifier.ABSTRACT) && !value.isInterface()) {
      list.add(holder.createProblem(element, JavaBundle.message("abstract.class.not.allowed", value.getQualifiedName())));
    }
    return list;
  }
public static @NotNull List<DomElementProblemDescriptor> checkExtendClass(final GenericDomValue element,
                                                                            final PsiClass value,
                                                                            final String[] names,
                                                                            final boolean instantiatable,
                                                                            final boolean canBeDecorator,
                                                                            final boolean allowInterface,
                                                                            final boolean allowNonPublic,
                                                                            final boolean allowAbstract,
                                                                            final boolean allowEnum,
                                                                            final DomElementAnnotationHolder holder)