private void processTagNode(PsiBuilder psiBuilder,
                              FlyweightCapableTreeStructure<LighterASTNode> structure,
                              LighterASTNode node,
                              XmlBuilder builder) {
    final IElementType nodeTT = node.getTokenType();
    assert nodeTT instanceof IXmlTagElementType;

    final Ref<LighterASTNode[]> childrenRef = Ref.create(null);
    final int count = structure.getChildren(node, childrenRef);
    LighterASTNode[] children = childrenRef.get();

    int stackFrameSize = myNamespacesStack.size();
    CharSequence tagName = "";
    int headerEndOffset = node.getEndOffset();
    for (int i = 0; i < count; i++) {
      LighterASTNode child = children[i];
      final IElementType tt = child.getTokenType();
      if (tt instanceof IXmlAttributeElementType) checkForXmlns(child, structure);
      if (tt == XmlTokenType.XML_TAG_END || tt == XmlTokenType.XML_EMPTY_ELEMENT_END) {
        headerEndOffset = child.getEndOffset();
        break;
      }
      if (tt == XmlTokenType.XML_NAME || tt == XmlTokenType.XML_TAG_NAME) {
        tagName = getTokenText(child);
      }
    }

    CharSequence localName = XmlUtil.getLocalName(tagName);
    String namespace = getNamespace(tagName);

    XmlBuilder.ProcessingOrder order = builder.startTag(localName, namespace, node.getStartOffset(), node.getEndOffset(), headerEndOffset);
    boolean processAttrs = order == XmlBuilder.ProcessingOrder.TAGS_AND_ATTRIBUTES ||
                           order == XmlBuilder.ProcessingOrder.TAGS_AND_ATTRIBUTES_AND_TEXTS;

    boolean processTexts = order == XmlBuilder.ProcessingOrder.TAGS_AND_TEXTS ||
                           order == XmlBuilder.ProcessingOrder.TAGS_AND_ATTRIBUTES_AND_TEXTS;

    for (int i = 0; i < count; i++) {
      LighterASTNode child = children[i];
      IElementType tt = child.getTokenType();
      if (tt == TokenType.ERROR_ELEMENT) processErrorNode(psiBuilder, child, builder);
      if (tt instanceof IXmlTagElementType) processTagNode(psiBuilder, structure, child, builder);
      if (processAttrs && tt instanceof IXmlAttributeElementType) processAttributeNode(child, structure, builder);
      if (processTexts && tt == XmlElementType.XML_TEXT) processTextNode(structure, child, builder);
      if (tt == XmlElementType.XML_ENTITY_REF) builder.entityRef(getTokenText(child), child.getStartOffset(), child.getEndOffset());
    }

    builder.endTag(localName, namespace, node.getStartOffset(), node.getEndOffset());

    int framesToDrop = myNamespacesStack.size() - stackFrameSize;
    for (int i = 0; i < framesToDrop; i++) {
      myNamespacesStack.pop();
      myPrefixesStack.pop();
    }

    structure.disposeChildren(children, count);
  }
private void processTagNode(PsiBuilder psiBuilder,
                              FlyweightCapableTreeStructure<LighterASTNode> structure,
                              LighterASTNode node,
                              XmlBuilder builder)