Index: trunk/src/VBox/Runtime/r3/xml.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/xml.cpp	(revision 48828)
+++ trunk/src/VBox/Runtime/r3/xml.cpp	(revision 48834)
@@ -47,5 +47,4 @@
 
 #include <map>
-#include <boost/shared_ptr.hpp> /* This is the ONLY use of boost. */
 
 
@@ -156,5 +155,5 @@
     RTStrAPrintfV(&pszContext2, pcszContext, args);
     char *newMsg;
-    RTStrAPrintf(&newMsg, "%s: %d (%s)", pszContext2, aRC, RTErrGetShort(aRC));
+    RTStrAPrintf(&newMsg, "%s: %d(%s)", pszContext2, aRC, RTErrGetShort(aRC));
     setWhat(newMsg);
     RTStrFree(newMsg);
@@ -241,5 +240,5 @@
 }
 
-const char* File::uri() const
+const char *File::uri() const
 {
     return m->strFileName.c_str();
@@ -291,17 +290,15 @@
 {
     size_t len = aLen;
-    int vrc = RTFileWrite (m->handle, aBuf, len, &len);
-    if (RT_SUCCESS (vrc))
+    int vrc = RTFileWrite(m->handle, aBuf, len, &len);
+    if (RT_SUCCESS(vrc))
         return (int)len;
 
     throw EIPRTFailure(vrc, "Runtime error writing to file '%s'", m->strFileName.c_str());
-
-    return -1 /* failure */;
 }
 
 void File::truncate()
 {
-    int vrc = RTFileSetSize (m->handle, pos());
-    if (RT_SUCCESS (vrc))
+    int vrc = RTFileSetSize(m->handle, pos());
+    if (RT_SUCCESS(vrc))
         return;
 
@@ -318,5 +315,5 @@
 {
     Data()
-        : buf (NULL), len (0), uri (NULL), pos (0) {}
+        : buf(NULL), len(0), uri(NULL), pos(0) {}
 
     const char *buf;
@@ -327,18 +324,18 @@
 };
 
-MemoryBuf::MemoryBuf (const char *aBuf, size_t aLen, const char *aURI /* = NULL */)
-    : m (new Data())
+MemoryBuf::MemoryBuf(const char *aBuf, size_t aLen, const char *aURI /* = NULL */)
+    : m(new Data())
 {
     if (aBuf == NULL)
-        throw EInvalidArg (RT_SRC_POS);
+        throw EInvalidArg(RT_SRC_POS);
 
     m->buf = aBuf;
     m->len = aLen;
-    m->uri = RTStrDup (aURI);
+    m->uri = RTStrDup(aURI);
 }
 
 MemoryBuf::~MemoryBuf()
 {
-    RTStrFree (m->uri);
+    RTStrFree(m->uri);
 }
 
@@ -353,7 +350,7 @@
 }
 
-void MemoryBuf::setPos (uint64_t aPos)
-{
-    size_t off = (size_t) aPos;
+void MemoryBuf::setPos(uint64_t aPos)
+{
+    size_t off = (size_t)aPos;
     if ((uint64_t) off != aPos)
         throw EInvalidArg();
@@ -365,5 +362,5 @@
 }
 
-int MemoryBuf::read (char *aBuf, int aLen)
+int MemoryBuf::read(char *aBuf, int aLen)
 {
     if (m->pos >= m->len)
@@ -371,5 +368,5 @@
 
     size_t len = m->pos + aLen < m->len ? aLen : m->len - m->pos;
-    memcpy (aBuf, m->buf + m->pos, len);
+    memcpy(aBuf, m->buf + m->pos, len);
     m->pos += len;
 
@@ -422,4 +419,6 @@
 }
 
+
+
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -427,108 +426,24 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
-
-struct Node::Data
-{
-    struct compare_const_char
-    {
-        bool operator()(const char* s1, const char* s2) const
-        {
-            return strcmp(s1, s2) < 0;
-        }
-    };
-
-    // attributes, if this is an element; can be empty
-    typedef std::map<const char*, boost::shared_ptr<AttributeNode>, compare_const_char > AttributesMap;
-    AttributesMap attribs;
-
-#ifdef USE_STD_LIST_FOR_CHILDREN
-    // child elements, if this is an element; can be empty
-    typedef std::list< boost::shared_ptr<Node> > InternalNodesList;
-    InternalNodesList children;
-#endif
-};
 
 Node::Node(EnumType type,
            Node *pParent,
-           xmlNode *plibNode,
-           xmlAttr *plibAttr)
+           PRTLISTANCHOR pListAnchor,
+           xmlNode *pLibNode,
+           xmlAttr *pLibAttr)
     : m_Type(type)
     , m_pParent(pParent)
-    , m_plibNode(plibNode)
-    , m_plibAttr(plibAttr)
+    , m_pLibNode(pLibNode)
+    , m_pLibAttr(pLibAttr)
     , m_pcszNamespacePrefix(NULL)
     , m_pcszNamespaceHref(NULL)
     , m_pcszName(NULL)
-    , m(new Data)
-{
-#ifndef USE_STD_LIST_FOR_CHILDREN
-    RTListInit(&m_childEntry);
-    RTListInit(&m_children);
-#endif
+    , m_pParentListAnchor(pListAnchor)
+{
+    RTListInit(&m_listEntry);
 }
 
 Node::~Node()
 {
-#ifndef USE_STD_LIST_FOR_CHILDREN
-    Node *pCur, *pNext;
-    RTListForEachSafeCpp(&m_children, pCur, pNext, Node, m_childEntry)
-    {
-        delete pCur;
-    }
-    RTListInit(&m_children);
-#endif
-    delete m;
-}
-
-/**
- * Private implementation.
- * @param elmRoot
- */
-void Node::buildChildren(const ElementNode &elmRoot)       // private
-{
-    // go thru this element's attributes
-    xmlAttr *plibAttr = m_plibNode->properties;
-    while (plibAttr)
-    {
-        const char *pcszKey;
-        boost::shared_ptr<AttributeNode> pNew(new AttributeNode(elmRoot, this, plibAttr, &pcszKey));
-        // store
-        m->attribs[pcszKey] = pNew;
-
-        plibAttr = plibAttr->next;
-    }
-
-    // go thru this element's child elements
-    for (xmlNodePtr plibNode = m_plibNode->children; plibNode; plibNode = plibNode->next)
-    {
-#ifndef USE_STD_LIST_FOR_CHILDREN
-        Node *pNew;
-        if (plibNode->type == XML_ELEMENT_NODE)
-            pNew = new ElementNode(&elmRoot, this, plibNode);
-        else if (plibNode->type == XML_TEXT_NODE)
-            pNew = new ContentNode(this, plibNode);
-        else
-            continue;
-        RTListAppend(&m_children, &pNew->m_childEntry);
-
-        /* Recurse for this child element to get its own children. */
-        pNew->buildChildren(elmRoot);
-#else
-        boost::shared_ptr<Node> pNew;
-
-        if (plibNode->type == XML_ELEMENT_NODE)
-            pNew = boost::shared_ptr<Node>(new ElementNode(&elmRoot, this, plibNode));
-        else if (plibNode->type == XML_TEXT_NODE)
-            pNew = boost::shared_ptr<Node>(new ContentNode(this, plibNode));
-        if (pNew)
-        {
-            // store
-            m->children.push_back(pNew);
-
-            // recurse for this child element to get its own children
-            pNew->buildChildren(elmRoot);
-        }
-#endif
-    }
 }
 
@@ -538,5 +453,5 @@
  * @return
  */
-const char* Node::getName() const
+const char *Node::getName() const
 {
     return m_pcszName;
@@ -548,5 +463,5 @@
  * @return
  */
-const char* Node::getPrefix() const
+const char *Node::getPrefix() const
 {
     return m_pcszNamespacePrefix;
@@ -558,5 +473,5 @@
  * @return
  */
-const char* Node::getNamespaceURI() const
+const char *Node::getNamespaceURI() const
 {
     return m_pcszNamespaceHref;
@@ -627,14 +542,14 @@
 const char *Node::getValue() const
 {
-    if (   m_plibAttr
-        && m_plibAttr->children
+    if (   m_pLibAttr
+        && m_pLibAttr->children
         )
         // libxml hides attribute values in another node created as a
         // single child of the attribute node, and it's in the content field
-        return (const char *)m_plibAttr->children->content;
-
-    if (   m_plibNode
-        && m_plibNode->children)
-        return (const char *)m_plibNode->children->content;
+        return (const char *)m_pLibAttr->children->content;
+
+    if (   m_pLibNode
+        && m_pLibNode->children)
+        return (const char *)m_pLibNode->children->content;
 
     return NULL;
@@ -716,36 +631,129 @@
 int Node::getLineNumber() const
 {
-    if (m_plibAttr)
-        return m_pParent->m_plibNode->line;
-
-    return m_plibNode->line;
+    if (m_pLibAttr)
+        return m_pParent->m_pLibNode->line;
+
+    return m_pLibNode->line;
 }
 
 /**
  * Private element constructor.
- * @param pelmRoot
- * @param pParent
- * @param plibNode
- */
-ElementNode::ElementNode(const ElementNode *pelmRoot,
+ *
+ * @param   pElmRoot    Pointer to the root element.
+ * @param   pParent     Pointer to the parent element (always an ElementNode,
+ *                      despite the type).  NULL for the root node.
+ * @param   pListAnchor Pointer to the m_children member of the parent.  NULL
+ *                      for the root node.
+ * @param   pLibNode    Pointer to the libxml2 node structure.
+ */
+ElementNode::ElementNode(const ElementNode *pElmRoot,
                          Node *pParent,
-                         xmlNode *plibNode)
+                         PRTLISTANCHOR pListAnchor,
+                         xmlNode *pLibNode)
     : Node(IsElement,
            pParent,
-           plibNode,
+           pListAnchor,
+           pLibNode,
            NULL)
 {
-    if (!(m_pelmRoot = pelmRoot))
-        // NULL passed, then this is the root element
-        m_pelmRoot = this;
-
-    m_pcszName = (const char*)plibNode->name;
-
-    if (plibNode->ns)
-    {
-        m_pcszNamespacePrefix = (const char*)m_plibNode->ns->prefix;
-        m_pcszNamespaceHref = (const char*)m_plibNode->ns->href;
-    }
-}
+    m_pElmRoot = pElmRoot ? pElmRoot : this; // If NULL is passed, then this is the root element.
+    m_pcszName = (const char *)pLibNode->name;
+
+    if (pLibNode->ns)
+    {
+        m_pcszNamespacePrefix = (const char *)m_pLibNode->ns->prefix;
+        m_pcszNamespaceHref = (const char *)m_pLibNode->ns->href;
+    }
+
+    RTListInit(&m_children);
+    RTListInit(&m_attributes);
+}
+
+ElementNode::~ElementNode()
+{
+    Node *pCur, *pNext;
+    RTListForEachSafeCpp(&m_children, pCur, pNext, Node, m_listEntry)
+    {
+        delete pCur;
+    }
+    RTListInit(&m_children);
+
+    RTListForEachSafeCpp(&m_attributes, pCur, pNext, Node, m_listEntry)
+    {
+        delete pCur;
+    }
+    RTListInit(&m_attributes);
+}
+
+
+/**
+ * Gets the next tree element in a full tree enumeration.
+ *
+ * @returns Pointer to the next element in the tree, NULL if we're done.
+ * @param   pElmRoot            The root of the tree we're enumerating.  NULL if
+ *                              it's the entire tree.
+ */
+ElementNode const *ElementNode::getNextTreeElement(ElementNode const *pElmRoot /*= NULL */) const
+{
+    /*
+     * Consider children first.
+     */
+    ElementNode const *pChild = getFirstChildElement();
+    if (pChild)
+        return pChild;
+
+    /*
+     * Then siblings, aunts and uncles.
+     */
+    ElementNode const *pCur = this;
+    do
+    {
+        ElementNode const *pSibling = pCur->getNextSibilingElement();
+        if (pSibling != NULL)
+            return pSibling;
+
+        pCur = static_cast<const xml::ElementNode *>(pCur->m_pParent);
+        Assert(pCur || pCur == pElmRoot);
+    } while (pCur != pElmRoot);
+
+    return NULL;
+}
+
+
+/**
+ * Private implementation.
+ *
+ * @param   pElmRoot        The root element.
+ */
+/*static*/ void ElementNode::buildChildren(ElementNode *pElmRoot)       // protected
+{
+    for (ElementNode *pCur = pElmRoot; pCur; pCur = pCur->getNextTreeElement(pElmRoot))
+    {
+        /*
+         * Go thru this element's attributes creating AttributeNodes for them.
+         */
+        for (xmlAttr *pLibAttr = pCur->m_pLibNode->properties; pLibAttr; pLibAttr = pLibAttr->next)
+        {
+            AttributeNode *pNew = new AttributeNode(pElmRoot, pCur, &pCur->m_attributes, pLibAttr);
+            RTListAppend(&pCur->m_attributes, &pNew->m_listEntry);
+        }
+
+        /*
+         * Go thru this element's child elements (element and text nodes).
+         */
+        for (xmlNodePtr pLibNode = pCur->m_pLibNode->children; pLibNode; pLibNode = pLibNode->next)
+        {
+            Node *pNew;
+            if (pLibNode->type == XML_ELEMENT_NODE)
+                pNew = new ElementNode(pElmRoot, pCur, &pCur->m_children, pLibNode);
+            else if (pLibNode->type == XML_TEXT_NODE)
+                pNew = new ContentNode(pCur, &pCur->m_children, pLibNode);
+            else
+                continue;
+            RTListAppend(&pCur->m_children, &pNew->m_listEntry);
+        }
+    }
+}
+
 
 /**
@@ -762,17 +770,8 @@
 {
     int i = 0;
-#ifndef USE_STD_LIST_FOR_CHILDREN
     Node *p;
-    RTListForEachCpp(&m_children, p, Node, m_childEntry)
-#else
-    for (Data::InternalNodesList::iterator it = m->children.begin();
-         it != m->children.end();
-         ++it)
-#endif
+    RTListForEachCpp(&m_children, p, Node, m_listEntry)
     {
         // export this child node if ...
-#ifdef USE_STD_LIST_FOR_CHILDREN
-        Node *p = it->get();
-#endif
         if (p->isElement())
             if (   !pcszMatch                       // ... the caller wants all nodes or ...
@@ -796,7 +795,6 @@
 const ElementNode *ElementNode::findChildElement(const char *pcszNamespace, const char *pcszMatch) const
 {
-#ifndef USE_STD_LIST_FOR_CHILDREN
     Node *p;
-    RTListForEachCpp(&m_children, p, Node, m_childEntry)
+    RTListForEachCpp(&m_children, p, Node, m_listEntry)
     {
         if (p->isElement())
@@ -807,17 +805,4 @@
         }
     }
-#else
-    Data::InternalNodesList::const_iterator
-        it,
-        last = m->children.end();
-    for (it = m->children.begin(); it != last; ++it)
-        if ((**it).isElement())
-        {
-            ElementNode *pelm = static_cast<ElementNode*>((*it).get());
-            if (pelm->nameEquals(pcszNamespace, pcszMatch))
-                return pelm;
-        }
-#endif
-
     return NULL;
 }
@@ -828,37 +813,17 @@
  * @return child element or NULL if not found.
  */
-const ElementNode * ElementNode::findChildElementFromId(const char *pcszId) const
-{
-#ifndef USE_STD_LIST_FOR_CHILDREN
-    Node *p;
-    RTListForEachCpp(&m_children, p, Node, m_childEntry)
+const ElementNode *ElementNode::findChildElementFromId(const char *pcszId) const
+{
+    const Node *p;
+    RTListForEachCpp(&m_children, p, Node, m_listEntry)
     {
         if (p->isElement())
         {
-            ElementNode *pelm = static_cast<ElementNode*>(p);
-            const AttributeNode *pAttr = pelm->findAttribute("id");
+            const ElementNode   *pElm  = static_cast<const ElementNode *>(p);
+            const AttributeNode *pAttr = pElm->findAttribute("id");
             if (pAttr && !strcmp(pAttr->getValue(), pcszId))
-                return pelm;
+                return pElm;
         }
     }
-#else
-    Data::InternalNodesList::const_iterator
-        it,
-        last = m->children.end();
-    for (it = m->children.begin();
-         it != last;
-         ++it)
-    {
-        if ((**it).isElement())
-        {
-            ElementNode *pelm = static_cast<ElementNode*>((*it).get());
-            const AttributeNode *pAttr;
-            if (    ((pAttr = pelm->findAttribute("id")))
-                 && (!strcmp(pAttr->getValue(), pcszId))
-               )
-                return pelm;
-        }
-    }
-#endif
     return NULL;
 }
@@ -871,13 +836,12 @@
         return this->findChildElement(pcszNamespace, pcszPath);
 
-#ifndef USE_STD_LIST_FOR_CHILDREN
     /** @todo Can be done without recursion as we have both sibling lists and parent
      *        pointers in this variant.  */
-    Node *p;
-    RTListForEachCpp(&m_children, p, Node, m_childEntry)
+    const Node *p;
+    RTListForEachCpp(&m_children, p, Node, m_listEntry)
     {
         if (p->isElement())
         {
-            const ElementNode *pElm = static_cast<ElementNode*>(p);
+            const ElementNode *pElm = static_cast<const ElementNode *>(p);
             if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis))
             {
@@ -888,21 +852,27 @@
         }
     }
-#else
-    Data::InternalNodesList::const_iterator  itLast = m->children.end();
-    for (Data::InternalNodesList::const_iterator it = m->children.begin(); it != itLast; ++it)
-    {
-        if ((**it).isElement())
-        {
-            const ElementNode *pElm = static_cast<ElementNode*>((*it).get());
-            if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis))
-            {
-                pElm = findChildElementP(pcszPath + cchThis, pcszNamespace);
-                if (pElm)
-                    return pElm;
-            }
-        }
-    }
-#endif
-
+
+    return NULL;
+}
+
+const ElementNode *ElementNode::getFirstChildElement() const
+{
+    const Node *p;
+    RTListForEachCpp(&m_children, p, Node, m_listEntry)
+    {
+        if (p->isElement())
+            return static_cast<const ElementNode *>(p);
+    }
+    return NULL;
+}
+
+const ElementNode *ElementNode::getLastChildElement() const
+{
+    const Node *p;
+    RTListForEachReverseCpp(&m_children, p, Node, m_listEntry)
+    {
+        if (p->isElement())
+            return static_cast<const ElementNode *>(p);
+    }
     return NULL;
 }
@@ -915,5 +885,5 @@
     for (;;)
     {
-        pSibling = RTListGetPrevCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry);
+        pSibling = RTListGetPrevCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry);
         if (!pSibling)
             return NULL;
@@ -930,5 +900,5 @@
     for (;;)
     {
-        pSibling = RTListGetNextCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry);
+        pSibling = RTListGetNextCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry);
         if (!pSibling)
             return NULL;
@@ -945,5 +915,5 @@
     for (;;)
     {
-        pSibling = RTListGetPrevCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry);
+        pSibling = RTListGetPrevCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry);
         if (!pSibling)
             return NULL;
@@ -964,5 +934,5 @@
     for (;;)
     {
-        pSibling = RTListGetNextCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry);
+        pSibling = RTListGetNextCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry);
         if (!pSibling)
             return NULL;
@@ -998,12 +968,12 @@
  * @return
  */
-const AttributeNode* ElementNode::findAttribute(const char *pcszMatch) const
-{
-    Data::AttributesMap::const_iterator it;
-
-    it = m->attribs.find(pcszMatch);
-    if (it != m->attribs.end())
-        return it->second.get();
-
+const AttributeNode *ElementNode::findAttribute(const char *pcszMatch) const
+{
+    AttributeNode *p;
+    RTListForEachCpp(&m_attributes, p, AttributeNode, m_listEntry)
+    {
+        if (p->nameEquals(pcszMatch))
+            return p;
+    }
     return NULL;
 }
@@ -1013,17 +983,17 @@
  * name and returns its value as a string.
  *
- * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
- * @param ppcsz out: attribute value
- * @return TRUE if attribute was found and str was thus updated.
- */
-bool ElementNode::getAttributeValue(const char *pcszMatch, const char *&ppcsz) const
-{
-    const Node* pAttr;
-    if ((pAttr = findAttribute(pcszMatch)))
-    {
-        ppcsz = pAttr->getValue();
+ * @param   pcszMatch   Name of attribute to find (see findAttribute() for
+ *                      namespace remarks).
+ * @param   ppcsz       Where to return the attribute.
+ * @returns Boolean success indicator.
+ */
+bool ElementNode::getAttributeValue(const char *pcszMatch, const char **ppcsz) const
+{
+    const AttributeNode *pAttr = findAttribute(pcszMatch);
+    if (pAttr)
+    {
+        *ppcsz = pAttr->getValue();
         return true;
     }
-
     return false;
 }
@@ -1033,14 +1003,18 @@
  * name and returns its value as a string.
  *
- * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
- * @param str out: attribute value; overwritten only if attribute was found
- * @return TRUE if attribute was found and str was thus updated.
- */
-bool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &str) const
-{
-    const Node* pAttr;
-    if ((pAttr = findAttribute(pcszMatch)))
-    {
-        str = pAttr->getValue();
+ * @param   pcszMatch   Name of attribute to find (see findAttribute() for
+ *                      namespace remarks).
+ * @param   rStr        Reference to the string object that should receive the
+ *                      attribute value.
+ * @returns Boolean success indicator.
+ *
+ * @throws  Whatever the string class may throw on assignment.
+ */
+bool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &rStr) const
+{
+    const AttributeNode *pAttr = findAttribute(pcszMatch);
+    if (pAttr)
+    {
+        rStr = pAttr->getValue();
         return true;
     }
@@ -1115,16 +1089,18 @@
  * function returns no error.
  *
- * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
- * @param i out: attribute value
- * @return TRUE if attribute was found and str was thus updated.
- */
-bool ElementNode::getAttributeValue(const char *pcszMatch, int64_t &i) const
-{
-    const char *pcsz;
-    if (    (getAttributeValue(pcszMatch, pcsz))
-         && (VINF_SUCCESS == RTStrToInt64Ex(pcsz, NULL, 0, &i))
-       )
-        return true;
-
+ * @param   pcszMatch   Name of attribute to find (see findAttribute() for
+ *                      namespace remarks).
+ * @param   i           Where to return the attribute value on success.
+ * @returns Boolean success indicator.
+ */
+bool ElementNode::getAttributeValue(const char *pcszMatch, int64_t *piValue) const
+{
+    const char *pcsz = findAttributeValue(pcszMatch);
+    if (pcsz)
+    {
+        int rc = RTStrToInt64Ex(pcsz, NULL, 0, piValue);
+        if (rc == VINF_SUCCESS)
+            return true;
+    }
     return false;
 }
@@ -1165,7 +1141,7 @@
     if (getAttributeValue(pcszMatch, pcsz))
     {
-        if (    (!strcmp(pcsz, "true"))
-             || (!strcmp(pcsz, "yes"))
-             || (!strcmp(pcsz, "1"))
+        if (   !strcmp(pcsz, "true")
+            || !strcmp(pcsz, "yes")
+            || !strcmp(pcsz, "1")
            )
         {
@@ -1173,7 +1149,7 @@
             return true;
         }
-        if (    (!strcmp(pcsz, "false"))
-             || (!strcmp(pcsz, "no"))
-             || (!strcmp(pcsz, "0"))
+        if (   !strcmp(pcsz, "false")
+            || !strcmp(pcsz, "no")
+            || !strcmp(pcsz, "0")
            )
         {
@@ -1186,4 +1162,79 @@
 }
 
+
+bool ElementNode::getElementValue(int32_t *piValue) const
+{
+    const char *pszValue = getValue();
+    if (pszValue)
+    {
+        int rc = RTStrToInt32Ex(pszValue, NULL, 0, piValue);
+        if (rc == VINF_SUCCESS)
+            return true;
+    }
+    return false;
+}
+
+bool ElementNode::getElementValue(uint32_t *puValue) const
+{
+    const char *pszValue = getValue();
+    if (pszValue)
+    {
+        int rc = RTStrToUInt32Ex(pszValue, NULL, 0, puValue);
+        if (rc == VINF_SUCCESS)
+            return true;
+    }
+    return false;
+}
+
+bool ElementNode::getElementValue(int64_t *piValue) const
+{
+    const char *pszValue = getValue();
+    if (pszValue)
+    {
+        int rc = RTStrToInt64Ex(pszValue, NULL, 0, piValue);
+        if (rc == VINF_SUCCESS)
+            return true;
+    }
+    return false;
+}
+
+bool ElementNode::getElementValue(uint64_t *puValue) const
+{
+    const char *pszValue = getValue();
+    if (pszValue)
+    {
+        int rc = RTStrToUInt64Ex(pszValue, NULL, 0, puValue);
+        if (rc == VINF_SUCCESS)
+            return true;
+    }
+    return false;
+}
+
+bool ElementNode::getElementValue(bool *pfValue) const
+{
+    const char *pszValue = getValue();
+    if (pszValue)
+    {
+        if (   !strcmp(pszValue, "true")
+            || !strcmp(pszValue, "yes")
+            || !strcmp(pszValue, "1")
+           )
+        {
+            *pfValue = true;
+            return true;
+        }
+        if (   !strcmp(pszValue, "false")
+            || !strcmp(pszValue, "no")
+            || !strcmp(pszValue, "0")
+           )
+        {
+            *pfValue = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+
 /**
  * Creates a new child element node and appends it to the list
@@ -1196,22 +1247,17 @@
 {
     // we must be an element, not an attribute
-    if (!m_plibNode)
+    if (!m_pLibNode)
         throw ENodeIsNotElement(RT_SRC_POS);
 
     // libxml side: create new node
-    xmlNode *plibNode;
-    if (!(plibNode = xmlNewNode(NULL,        // namespace
+    xmlNode *pLibNode;
+    if (!(pLibNode = xmlNewNode(NULL,        // namespace
                                 (const xmlChar*)pcszElementName)))
         throw std::bad_alloc();
-    xmlAddChild(m_plibNode, plibNode);
+    xmlAddChild(m_pLibNode, pLibNode);
 
     // now wrap this in C++
-    ElementNode *p = new ElementNode(m_pelmRoot, this, plibNode);
-#ifndef USE_STD_LIST_FOR_CHILDREN
-    RTListAppend(&m_children, &p->m_childEntry);
-#else
-    boost::shared_ptr<ElementNode> pNew(p);
-    m->children.push_back(pNew);
-#endif
+    ElementNode *p = new ElementNode(m_pElmRoot, this, &m_children, pLibNode);
+    RTListAppend(&m_children, &p->m_listEntry);
 
     return p;
@@ -1229,17 +1275,12 @@
 {
     // libxml side: create new node
-    xmlNode *plibNode = xmlNewText((const xmlChar*)pcszContent);
-    if (!plibNode)
+    xmlNode *pLibNode = xmlNewText((const xmlChar*)pcszContent);
+    if (!pLibNode)
         throw std::bad_alloc();
-    xmlAddChild(m_plibNode, plibNode);
+    xmlAddChild(m_pLibNode, pLibNode);
 
     // now wrap this in C++
-    ContentNode *p = new ContentNode(this, plibNode);
-#ifndef USE_STD_LIST_FOR_CHILDREN
-    RTListAppend(&m_children, &p->m_childEntry);
-#else
-    boost::shared_ptr<ContentNode> pNew(p);
-    m->children.push_back(pNew);
-#endif
+    ContentNode *p = new ContentNode(this, &m_children, pLibNode);
+    RTListAppend(&m_children, &p->m_listEntry);
 
     return p;
@@ -1253,40 +1294,38 @@
  * that was either created or changed.
  *
- * @param pcszName
- * @param pcszValue
- * @return
- */
-AttributeNode* ElementNode::setAttribute(const char *pcszName, const char *pcszValue)
-{
-    AttributeNode *pattrReturn;
-    Data::AttributesMap::const_iterator it;
-
-    it = m->attribs.find(pcszName);
-    if (it == m->attribs.end())
-    {
-        // libxml side: xmlNewProp creates an attribute
-        xmlAttr *plibAttr = xmlNewProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue);
-
-        // C++ side: create an attribute node around it
-        const char *pcszKey;
-        boost::shared_ptr<AttributeNode> pNew(new AttributeNode(*m_pelmRoot, this, plibAttr, &pcszKey));
-        // store
-        m->attribs[pcszKey] = pNew;
-        pattrReturn = pNew.get();
-    }
-    else
-    {
-        // overwrite existing libxml attribute node
-        xmlAttrPtr plibAttr = xmlSetProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue);
-
-        // and fix our existing C++ side around it
-        boost::shared_ptr<AttributeNode> pattr = it->second;
-        pattr->m_plibAttr = plibAttr;       // in case the xmlAttrPtr is different, I'm not sure
-
-        pattrReturn = pattr.get();
-    }
-
-    return pattrReturn;
-
+ * @param   pcszName        The attribute name.
+ * @param   pcszValue       The attribute value.
+ * @return  Pointer to the attribute node that was created or modified.
+ */
+AttributeNode *ElementNode::setAttribute(const char *pcszName, const char *pcszValue)
+{
+    /*
+     * Do we already have an attribute and should we just update it?
+     */
+    AttributeNode *pAttr;
+    RTListForEachCpp(&m_attributes, pAttr, AttributeNode, m_listEntry)
+    {
+        if (pAttr->nameEquals(pcszName))
+        {
+            /* Overwrite existing libxml attribute node ... */
+            xmlAttrPtr pLibAttr = xmlSetProp(m_pLibNode, (xmlChar *)pcszName, (xmlChar *)pcszValue);
+
+            /* ... and update our C++ wrapper in case the attrib pointer changed. */
+            pAttr->m_pLibAttr = pLibAttr;
+            return pAttr;
+        }
+    }
+
+    /*
+     * No existing attribute, create a new one.
+     */
+    /* libxml side: xmlNewProp creates an attribute. */
+    xmlAttr *pLibAttr = xmlNewProp(m_pLibNode, (xmlChar *)pcszName, (xmlChar *)pcszValue);
+
+    /* C++ side: Create an attribute node around it. */
+    pAttr = new AttributeNode(m_pElmRoot, this, &m_attributes, pLibAttr);
+    RTListAppend(&m_attributes, &pAttr->m_listEntry);
+
+    return pAttr;
 }
 
@@ -1417,36 +1456,34 @@
 
 /**
- * Private constructor for a new attribute node. This one is special:
- * in ppcszKey, it returns a pointer to a string buffer that should be
- * used to index the attribute correctly with namespaces.
- *
- * @param pParent
- * @param elmRoot
- * @param plibAttr
- * @param ppcszKey
- */
-AttributeNode::AttributeNode(const ElementNode &elmRoot,
+ * Private constructor for a new attribute node.
+ *
+ * @param   pElmRoot    Pointer to the root element.  Needed for getting the
+ *                      default name space.
+ * @param   pParent     Pointer to the parent element (always an ElementNode,
+ *                      despite the type).  NULL for the root node.
+ * @param   pListAnchor Pointer to the m_children member of the parent.  NULL
+ *                      for the root node.
+ * @param   pLibNode    Pointer to the libxml2 node structure.
+ */
+AttributeNode::AttributeNode(const ElementNode *pElmRoot,
                              Node *pParent,
-                             xmlAttr *plibAttr,
-                             const char **ppcszKey)
+                             PRTLISTANCHOR pListAnchor,
+                             xmlAttr *pLibAttr)
     : Node(IsAttribute,
            pParent,
+           pListAnchor,
            NULL,
-           plibAttr)
-{
-    m_pcszName = (const char*)plibAttr->name;
-
-    *ppcszKey = m_pcszName;
-
-    if (    plibAttr->ns
-         && plibAttr->ns->prefix
-       )
-    {
-        m_pcszNamespacePrefix = (const char*)plibAttr->ns->prefix;
-        m_pcszNamespaceHref = (const char*)plibAttr->ns->href;
-
-        if (    !elmRoot.m_pcszNamespaceHref
-             || (strcmp(m_pcszNamespaceHref, elmRoot.m_pcszNamespaceHref))
-           )
+           pLibAttr)
+{
+    m_pcszName = (const char *)pLibAttr->name;
+
+    if (   pLibAttr->ns
+        && pLibAttr->ns->prefix)
+    {
+        m_pcszNamespacePrefix = (const char *)pLibAttr->ns->prefix;
+        m_pcszNamespaceHref   = (const char *)pLibAttr->ns->href;
+
+        if (   !pElmRoot->m_pcszNamespaceHref
+            || strcmp(m_pcszNamespaceHref, pElmRoot->m_pcszNamespaceHref))
         {
             // not default namespace:
@@ -1454,14 +1491,13 @@
             m_strKey.append(':');
             m_strKey.append(m_pcszName);
-
-            *ppcszKey = m_strKey.c_str();
         }
     }
 }
 
-ContentNode::ContentNode(Node *pParent, xmlNode *plibNode)
+ContentNode::ContentNode(Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode)
     : Node(IsContent,
            pParent,
-           plibNode,
+           pListAnchor,
+           pLibNode,
            NULL)
 {
@@ -1601,7 +1637,7 @@
 void Document::refreshInternals() // private
 {
-    m->pRootElement = new ElementNode(NULL, NULL, xmlDocGetRootElement(m->plibDocument));
-
-    m->pRootElement->buildChildren(*m->pRootElement);
+    m->pRootElement = new ElementNode(NULL, NULL, NULL, xmlDocGetRootElement(m->plibDocument));
+
+    ElementNode::buildChildren(m->pRootElement);
 }
 
@@ -1611,5 +1647,5 @@
  * @return
  */
-const ElementNode* Document::getRootElement() const
+const ElementNode *Document::getRootElement() const
 {
     return m->pRootElement;
@@ -1621,5 +1657,5 @@
  * @return
  */
-ElementNode* Document::getRootElement()
+ElementNode *Document::getRootElement()
 {
     return m->pRootElement;
@@ -1627,8 +1663,10 @@
 
 /**
- * Creates a new element node and sets it as the root element. This will
- * only work if the document is empty; otherwise EDocumentNotEmpty is thrown.
- */
-ElementNode* Document::createRootElement(const char *pcszRootElementName,
+ * Creates a new element node and sets it as the root element.
+ *
+ * This will only work if the document is empty; otherwise EDocumentNotEmpty is
+ * thrown.
+ */
+ElementNode *Document::createRootElement(const char *pcszRootElementName,
                                          const char *pcszComment /* = NULL */)
 {
@@ -1637,23 +1675,23 @@
 
     // libxml side: create document, create root node
-    m->plibDocument = xmlNewDoc((const xmlChar*)"1.0");
-    xmlNode *plibRootNode;
-    if (!(plibRootNode = xmlNewNode(NULL,        // namespace
-                                    (const xmlChar*)pcszRootElementName)))
+    m->plibDocument = xmlNewDoc((const xmlChar *)"1.0");
+    xmlNode *plibRootNode = xmlNewNode(NULL /*namespace*/ , (const xmlChar *)pcszRootElementName);
+    if (!plibRootNode)
         throw std::bad_alloc();
     xmlDocSetRootElement(m->plibDocument, plibRootNode);
+
     // now wrap this in C++
-    m->pRootElement = new ElementNode(NULL, NULL, plibRootNode);
+    m->pRootElement = new ElementNode(NULL, NULL, NULL, plibRootNode);
 
     // add document global comment if specified
     if (pcszComment != NULL)
     {
-        xmlNode *pComment;
-        if (!(pComment = xmlNewDocComment(m->plibDocument,
-                                          (const xmlChar *)pcszComment)))
+        xmlNode *pComment = xmlNewDocComment(m->plibDocument, (const xmlChar *)pcszComment);
+        if (!pComment)
             throw std::bad_alloc();
         xmlAddPrevSibling(plibRootNode, pComment);
+
         // now wrap this in C++
-        m->pComment = new ElementNode(NULL, NULL, pComment);
+        m->pComment = new ElementNode(NULL, NULL, NULL, pComment);
     }
 
