private static void replaceElements(XmlTag tag, TemplateBuilder builder) {
   for (XmlAttribute attribute : tag.getAttributes()) {
     XmlAttributeValue value = attribute.getValueElement();
     if (value != null) {
       builder.replaceElement(value, TextRange.from(1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   if ("<".equals(tag.getText())) {
     builder.replaceElement(
         tag, TextRange.from(1, 0), new MacroCallNode(new CompleteSmartMacro()));
   } else if (tag.getSubTags().length == 0) {
     int i = tag.getText().indexOf("></");
     if (i > 0) {
       builder.replaceElement(
           tag, TextRange.from(i + 1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   for (XmlTag subTag : tag.getSubTags()) {
     replaceElements(subTag, builder);
   }
 }
 @Nullable
 private static XmlTag getAnchor(
     @NotNull XmlTag contextTag, Editor editor, XmlElementDescriptor selected) {
   XmlContentDFA contentDFA = XmlContentDFA.getContentDFA(contextTag);
   int offset = editor.getCaretModel().getOffset();
   if (contentDFA == null) {
     return null;
   }
   XmlTag anchor = null;
   boolean previousPositionIsPossible = true;
   for (XmlTag subTag : contextTag.getSubTags()) {
     if (contentDFA.getPossibleElements().contains(selected)) {
       if (subTag.getTextOffset() > offset) {
         break;
       }
       anchor = subTag;
       previousPositionIsPossible = true;
     } else {
       previousPositionIsPossible = false;
     }
     contentDFA.transition(subTag);
   }
   return previousPositionIsPossible ? null : anchor;
 }