void (boolean multipleRootTagError) { assert token() == XML_START_TAG_START : "Tag start expected"; final PsiBuilder.Marker tag = mark(); final String tagName = parseTagHeader(multipleRootTagError, tag); if (tagName == null) return; final PsiBuilder.Marker content = mark(); parseTagContent(); if (token() == XML_END_TAG_START) { final PsiBuilder.Marker footer = mark(); advance(); if (token() == XML_NAME) { String endName = myBuilder.getTokenText(); if (!tagName.equals(endName) && myTagNamesStack.contains(endName)) { footer.rollbackTo(); myTagNamesStack.pop(); tag.doneBefore(XML_TAG, content, XmlPsiBundle.message("xml.parsing.named.element.is.not.closed", tagName)); content.drop(); return; } advance(); } else { error(XmlPsiBundle.message("xml.parsing.closing.tag.name.missing")); } footer.drop(); while (token() != XmlTokenType.XML_TAG_END && token() != XmlTokenType.XML_START_TAG_START && token() != XmlTokenType.XML_END_TAG_START && !eof()) { error(XmlPsiBundle.message("xml.parsing.unexpected.token")); advance(); } if (token() == XML_TAG_END) { advance(); } else { error(XmlPsiBundle.message("xml.parsing.closing.tag.is.not.done")); } } else { error(XmlPsiBundle.message("xml.parsing.unexpected.end.of.file")); } content.drop(); myTagNamesStack.pop(); tag.done(XML_TAG); }