private static void processElementDescriptors(
      XmlElementDescriptor descriptor,
      XmlTag tag,
      ElementNames names,
      Set<XmlElementDescriptor> history) {
    if (!history.add(descriptor)) {
      return;
    }
    final String namespace =
        descriptor instanceof XmlElementDescriptorImpl
            ? ((XmlElementDescriptorImpl) descriptor).getNamespace()
            : tag.getNamespace();
    names.elementNames.add(new QName(namespace, descriptor.getName()));

    final XmlAttributeDescriptor[] attributesDescriptors =
        descriptor.getAttributesDescriptors(null);
    for (XmlAttributeDescriptor attributesDescriptor : attributesDescriptors) {
      final String localPart = attributesDescriptor.getName();
      if (!"xmlns".equals(localPart)) names.attributeNames.add(new QName(localPart));
    }

    final XmlElementDescriptor[] descriptors = descriptor.getElementsDescriptors(tag);
    for (XmlElementDescriptor elem : descriptors) {
      processElementDescriptors(elem, tag, names, history);
    }
  }
  // Read-only calculation
  protected XmlAttributeDescriptor[] collectAttributeDescriptors(final XmlTag context) {
    final XmlAttributeDescriptor[] attributesDescriptors =
        myDelegate.getAttributesDescriptors(context);
    XmlAttributeDescriptor[] temp = new XmlAttributeDescriptor[attributesDescriptors.length];

    for (int i = 0; i < attributesDescriptors.length; i++) {
      temp[i] = new HtmlAttributeDescriptorImpl(attributesDescriptors[i], myCaseSensitive);
    }
    return temp;
  }
  // Read-only calculation
  protected HashMap<String, XmlAttributeDescriptor> collectAttributeDescriptorsMap(
      final XmlTag context) {
    final HashMap<String, XmlAttributeDescriptor> hashMap =
        new HashMap<String, XmlAttributeDescriptor>();
    XmlAttributeDescriptor[] elementAttributeDescriptors =
        myDelegate.getAttributesDescriptors(context);

    for (final XmlAttributeDescriptor attributeDescriptor : elementAttributeDescriptors) {
      hashMap.put(
          attributeDescriptor.getName(),
          new HtmlAttributeDescriptorImpl(attributeDescriptor, myCaseSensitive));
    }
    return hashMap;
  }
  private void checkRequiredAttributes(
      XmlTag tag, String name, XmlElementDescriptor elementDescriptor) {
    XmlAttributeDescriptor[] attributeDescriptors = elementDescriptor.getAttributesDescriptors(tag);
    Set<String> requiredAttributes = null;

    for (XmlAttributeDescriptor attribute : attributeDescriptors) {
      if (attribute != null && attribute.isRequired()) {
        if (requiredAttributes == null) {
          requiredAttributes = new HashSet<String>();
        }
        requiredAttributes.add(attribute.getName(tag));
      }
    }

    if (requiredAttributes != null) {
      for (final String attrName : requiredAttributes) {
        if (tag.getAttribute(attrName, "") == null
            && !XmlExtension.getExtension(tag.getContainingFile())
                .isRequiredAttributeImplicitlyPresent(tag, attrName)) {

          final InsertRequiredAttributeFix insertRequiredAttributeIntention =
              new InsertRequiredAttributeFix(tag, attrName, null);
          final String localizedMessage =
              XmlErrorMessages.message("element.doesnt.have.required.attribute", name, attrName);
          final InspectionProfile profile =
              InspectionProjectProfileManager.getInstance(tag.getProject()).getInspectionProfile();
          final LocalInspectionToolWrapper toolWrapper =
              (LocalInspectionToolWrapper)
                  profile.getInspectionTool(RequiredAttributesInspection.SHORT_NAME, tag);
          if (toolWrapper != null) {
            RequiredAttributesInspection inspection =
                (RequiredAttributesInspection) toolWrapper.getTool();
            reportOneTagProblem(
                tag,
                attrName,
                localizedMessage,
                insertRequiredAttributeIntention,
                HighlightDisplayKey.find(RequiredAttributesInspection.SHORT_NAME),
                inspection,
                XmlEntitiesInspection.NOT_REQUIRED_ATTRIBUTE);
          }
        }
      }
    }
  }
 private static void generateRaw(final @NotNull XmlTag newTag) {
   XmlElementDescriptor selected = newTag.getDescriptor();
   if (selected == null) return;
   switch (selected.getContentType()) {
     case XmlElementDescriptor.CONTENT_TYPE_EMPTY:
       newTag.collapseIfEmpty();
       ASTNode node = newTag.getNode();
       assert node != null;
       ASTNode elementEnd = node.findChildByType(XmlTokenType.XML_EMPTY_ELEMENT_END);
       if (elementEnd == null) {
         LeafElement emptyTagEnd =
             Factory.createSingleLeafElement(
                 XmlTokenType.XML_EMPTY_ELEMENT_END, "/>", 0, 2, null, newTag.getManager());
         node.addChild(emptyTagEnd);
       }
       break;
     case XmlElementDescriptor.CONTENT_TYPE_MIXED:
       newTag.getValue().setText("");
   }
   for (XmlAttributeDescriptor descriptor : selected.getAttributesDescriptors(newTag)) {
     if (descriptor.isRequired()) {
       newTag.setAttribute(descriptor.getName(), "");
     }
   }
   List<XmlElementDescriptor> tags = getRequiredSubTags(selected);
   for (XmlElementDescriptor descriptor : tags) {
     if (descriptor == null) {
       XmlTag tag =
           XmlElementFactory.getInstance(newTag.getProject())
               .createTagFromText("<", newTag.getLanguage());
       newTag.addSubTag(tag, false);
     } else {
       XmlTag subTag = newTag.addSubTag(createTag(newTag, descriptor), false);
       generateRaw(subTag);
     }
   }
 }
 public XmlAttributeDescriptor[] getAttributesDescriptors(final XmlTag context) {
   return RelaxedHtmlFromSchemaElementDescriptor.addAttrDescriptorsForFacelets(
       context, myDelegate.getAttributesDescriptors(context));
 }