void (XmlTag tag, final Map<String, List<String>> tagsMap, final Map<String, List<MyAttributeInfo>> attributesMap, final boolean processIncludes) { if (tag == null) { return; } final String tagName = tag.getName(); List<MyAttributeInfo> list = attributesMap.get(tagName); if (list == null) { list = new ArrayList<>(); final XmlAttribute[] attributes = tag.getAttributes(); for (final XmlAttribute attribute : attributes) { list.add(new MyAttributeInfo(attribute.getName())); } } else { final XmlAttribute[] attributes = tag.getAttributes().clone(); list.sort(null); Arrays.sort(attributes, Comparator.comparing(XmlAttribute::getName)); final Iterator<MyAttributeInfo> iter = list.iterator(); list = new ArrayList<>(); int index = 0; while (iter.hasNext()) { final MyAttributeInfo info = iter.next(); boolean requiredFlag = false; while (attributes.length > index) { if (info.compareTo(attributes[index]) != 0) { if (info.compareTo(attributes[index]) < 0) { break; } if (attributes[index].getValue() != null) list.add(new MyAttributeInfo(attributes[index].getName(), false)); index++; } else { requiredFlag = true; index++; break; } } info.myRequired &= requiredFlag; list.add(info); } while (attributes.length > index) { if (attributes[index].getValue() != null) { list.add(new MyAttributeInfo(attributes[index++].getName(), false)); } else { index++; } } } attributesMap.put(tagName, list); final List<String> tags = tagsMap.get(tagName) != null ? tagsMap.get(tagName) : new ArrayList<>(); tagsMap.put(tagName, tags); PsiFile file = tag.isValid() ? tag.getContainingFile() : null; processXmlElements(tag, new FilterElementProcessor(XmlTagFilter.INSTANCE) { @Override public void add(PsiElement element) { XmlTag tag = (XmlTag)element; if (!tags.contains(tag.getName())) { tags.add(tag.getName()); } computeTag(tag, tagsMap, attributesMap, processIncludes); } }, false, false, file, processIncludes); /*tag.processElements(new FilterElementProcessor(XmlTagFilter.INSTANCE) { public void add(PsiElement element) { XmlTag tag = (XmlTag)element; if (!tags.contains(tag.getName())) { tags.add(tag.getName()); } computeTag(tag, tagsMap, attributesMap); } }, tag);*/ }