{
if (isCloseTag() || isEmptyTag())
return null;
// Back up to the first surrounding tag that has a different name, and ensure
// that *it* is balanced, saving our expected return value along the way.
IMXMLTagData startTag = this;
while (true)
{
IMXMLTagData parentTag = startTag.getContainingTag(startTag.getAbsoluteStart());
if (parentTag == null)
break;
startTag = parentTag;
if (!parentTag.getName().equals(this.getName()))
{
break;
}
}
// Now walk through the tags starting at startTag. Once we pop ourselves
// off the tagStack, we've found our candidate result -- but keep going
// until the stack is null, to ensure that we're balanced out to the
// surrounding tag.
IMXMLUnitData[] list = getParent().getUnits();
FastStack<IMXMLTagData> tagStack = new FastStack<IMXMLTagData>();
IMXMLTagData result = null;
for (int i = startTag.getIndex(); i < list.length; i++)
{
IMXMLUnitData curUnit = list[i];
if (curUnit.isTag())
{
IMXMLTagData curTag = (IMXMLTagData)curUnit;
if (curTag.isEmptyTag())
{
// do nothing for empty tags.
}
else if (curTag.isOpenTag())
{
tagStack.push(curTag);
}
else if (curTag.isCloseTag())
{
if (tagStack.isEmpty())
{
// document is unbalanced.
return null;
}
IMXMLTagData pop = tagStack.pop();
//check the short name in case the namespace is not spelled properly
if (!pop.getName().equals(curTag.getName()) && !pop.getShortName().equals(curTag.getShortName()))
{
// document is unbalanced.
return null;
}
if (pop == this)