tmp = tmpl; tmp->GetParent(getter_AddRefs(tmpl));
tmpl = tmpl->GetParent();
nsXULContentBuilder::IsDirectlyContainedBy(nsIContent* aChild, nsIContent* aParent){    // This routine uses the <template> to determine if aChild is    // "directly contained by" aParent. It does so by walking up the    // template subtree in parallel with the generated subtree.    NS_PRECONDITION(aChild != nsnull, "null ptr");    if (! aChild)        return PR_FALSE;    // First, we need to find the template from which this element was    // generated.    nsCOMPtr<nsIContent> tmpl;    mTemplateMap.GetTemplateFor(aChild, getter_AddRefs(tmpl));    if (! tmpl)        return PR_FALSE;    // Now walk up the template subtree in parallel with the generated    // subtree.    nsCOMPtr<nsIAtom> tag;    nsCOMPtr<nsIContent> generated(aChild);    do {        // XXX - gcc 2.95.x -O3 builds are known to break if        // we declare nsCOMPtrs inside this loop.  Moving them        // out of the loop or using a normal pointer works        // around this problem.        // http://bugzilla.mozilla.org/show_bug.cgi?id=61501        // Walk up the generated tree        nsIContent *tmp = generated;        tmp->GetParent(getter_AddRefs(generated));        if (! generated)             return PR_FALSE;        // Walk up the template tree        tmp = tmpl;        tmp->GetParent(getter_AddRefs(tmpl));        if (! tmpl)            return PR_FALSE;        // The content within a template ends when we hit the        // <template> or <rule> element in the simple syntax, or the        // <action> element in the extended syntax.        tmpl->GetTag(getter_AddRefs(tag));    } while (tag.get() != nsXULAtoms::templateAtom &&             tag.get() != nsXULAtoms::rule &&             tag.get() != nsXULAtoms::action);    // Did we find the generated parent?    return PRBool(generated.get() == aParent);}