diff --git a/src/xml/SkDOM.cpp b/src/xml/SkDOM.cpp
new file mode 100644
index 0000000..a9fc31e
--- /dev/null
+++ b/src/xml/SkDOM.cpp
@@ -0,0 +1,512 @@
+/* libs/graphics/xml/SkDOM.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include "SkDOM.h"
+
+/////////////////////////////////////////////////////////////////////////
+
+#include "SkXMLParser.h"
+
+bool SkXMLParser::parse(const SkDOM& dom, const SkDOMNode* node)
+{
+    const char* elemName = dom.getName(node);
+
+    if (this->startElement(elemName))
+        return false;
+    
+    SkDOM::AttrIter iter(dom, node);
+    const char*     name, *value;
+    
+    while ((name = iter.next(&value)) != NULL)
+        if (this->addAttribute(name, value))
+            return false;
+
+    if ((node = dom.getFirstChild(node)) != NULL)
+        do {
+            if (!this->parse(dom, node))
+                return false;
+        } while ((node = dom.getNextSibling(node)) != NULL);
+    
+    return !this->endElement(elemName);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+struct SkDOMAttr {
+    const char* fName;
+    const char* fValue;
+};
+
+struct SkDOMNode {
+    const char* fName;
+    SkDOMNode*  fFirstChild;
+    SkDOMNode*  fNextSibling;
+    uint16_t    fAttrCount;
+    uint8_t     fType;
+    uint8_t     fPad;
+
+    const SkDOMAttr* attrs() const
+    {
+        return (const SkDOMAttr*)(this + 1);
+    }
+    SkDOMAttr* attrs()
+    {
+        return (SkDOMAttr*)(this + 1);
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////
+
+#define kMinChunkSize   512
+
+SkDOM::SkDOM() : fAlloc(kMinChunkSize), fRoot(NULL)
+{
+}
+
+SkDOM::~SkDOM()
+{
+}
+
+const SkDOM::Node* SkDOM::getRootNode() const
+{
+    return fRoot;
+}
+
+const SkDOM::Node* SkDOM::getFirstChild(const Node* node, const char name[]) const
+{
+    SkASSERT(node);
+    const Node* child = node->fFirstChild;
+
+    if (name)
+    {
+        for (; child != NULL; child = child->fNextSibling)
+            if (!strcmp(name, child->fName))
+                break;
+    }
+    return child;
+}
+
+const SkDOM::Node* SkDOM::getNextSibling(const Node* node, const char name[]) const
+{
+    SkASSERT(node);
+    const Node* sibling = node->fNextSibling;
+    if (name)
+    {
+        for (; sibling != NULL; sibling = sibling->fNextSibling)
+            if (!strcmp(name, sibling->fName))
+                break;
+    }
+    return sibling;
+}
+
+SkDOM::Type SkDOM::getType(const Node* node) const
+{
+    SkASSERT(node);
+    return (Type)node->fType;
+}
+
+const char* SkDOM::getName(const Node* node) const
+{
+    SkASSERT(node);
+    return node->fName;
+}
+
+const char* SkDOM::findAttr(const Node* node, const char name[]) const
+{
+    SkASSERT(node);
+    const Attr* attr = node->attrs();
+    const Attr* stop = attr + node->fAttrCount;
+
+    while (attr < stop)
+    {
+        if (!strcmp(attr->fName, name))
+            return attr->fValue;
+        attr += 1;
+    }
+    return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+const SkDOM::Attr* SkDOM::getFirstAttr(const Node* node) const
+{
+    return node->fAttrCount ? node->attrs() : NULL;
+}
+
+const SkDOM::Attr* SkDOM::getNextAttr(const Node* node, const Attr* attr) const
+{
+    SkASSERT(node);
+    if (attr == NULL)
+        return NULL;
+    return (attr - node->attrs() + 1) < node->fAttrCount ? attr + 1 : NULL;
+}
+
+const char* SkDOM::getAttrName(const Node* node, const Attr* attr) const
+{
+    SkASSERT(node);
+    SkASSERT(attr);
+    return attr->fName;
+}
+
+const char* SkDOM::getAttrValue(const Node* node, const Attr* attr) const
+{
+    SkASSERT(node);
+    SkASSERT(attr);
+    return attr->fValue;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+SkDOM::AttrIter::AttrIter(const SkDOM&, const SkDOM::Node* node)
+{
+    SkASSERT(node);
+    fAttr = node->attrs();
+    fStop = fAttr + node->fAttrCount;
+}
+
+const char* SkDOM::AttrIter::next(const char** value)
+{
+    const char* name = NULL;
+
+    if (fAttr < fStop)
+    {
+        name = fAttr->fName;
+        if (value)
+            *value = fAttr->fValue;
+        fAttr += 1;
+    }
+    return name;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include "SkXMLParser.h"
+#include "SkTDArray.h"
+
+static char* dupstr(SkChunkAlloc* chunk, const char src[])
+{
+    SkASSERT(chunk && src);
+    size_t  len = strlen(src);
+    char*   dst = (char*)chunk->alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
+    memcpy(dst, src, len + 1);
+    return dst;
+}
+
+class SkDOMParser : public SkXMLParser {
+    bool fNeedToFlush;
+public:
+    SkDOMParser(SkChunkAlloc* chunk) : SkXMLParser(&fParserError), fAlloc(chunk)
+    {
+        fRoot = NULL;
+        fLevel = 0;
+        fNeedToFlush = true;
+    }
+    SkDOM::Node* getRoot() const { return fRoot; }
+    SkXMLParserError fParserError;
+protected:
+    void flushAttributes()
+    {
+        int attrCount = fAttrs.count();
+
+        SkDOM::Node* node = (SkDOM::Node*)fAlloc->alloc(sizeof(SkDOM::Node) + attrCount * sizeof(SkDOM::Attr),
+                                                        SkChunkAlloc::kThrow_AllocFailType);
+
+        node->fName = fElemName;
+        node->fFirstChild = NULL;
+        node->fAttrCount = SkToU16(attrCount);
+        node->fType = SkDOM::kElement_Type;
+
+        if (fRoot == NULL)
+        {
+            node->fNextSibling = NULL;
+            fRoot = node;
+        }
+        else    // this adds siblings in reverse order. gets corrected in onEndElement()
+        {
+            SkDOM::Node* parent = fParentStack.top();
+            SkASSERT(fRoot && parent);
+            node->fNextSibling = parent->fFirstChild;
+            parent->fFirstChild = node;
+        }
+        *fParentStack.push() = node;
+
+        memcpy(node->attrs(), fAttrs.begin(), attrCount * sizeof(SkDOM::Attr));
+        fAttrs.reset();
+
+    }
+    virtual bool onStartElement(const char elem[])
+    {
+        if (fLevel > 0 && fNeedToFlush)
+            this->flushAttributes();
+        fNeedToFlush = true;
+        fElemName = dupstr(fAlloc, elem);
+        ++fLevel;
+        return false;
+    }
+    virtual bool onAddAttribute(const char name[], const char value[])
+    {
+        SkDOM::Attr* attr = fAttrs.append();
+        attr->fName = dupstr(fAlloc, name);
+        attr->fValue = dupstr(fAlloc, value);
+        return false;
+    }
+    virtual bool onEndElement(const char elem[])
+    {
+        --fLevel;
+        if (fNeedToFlush)
+            this->flushAttributes();
+        fNeedToFlush = false;
+
+        SkDOM::Node* parent;
+
+        fParentStack.pop(&parent);
+
+        SkDOM::Node* child = parent->fFirstChild;
+        SkDOM::Node* prev = NULL;
+        while (child)
+        {
+            SkDOM::Node* next = child->fNextSibling;
+            child->fNextSibling = prev;
+            prev = child;
+            child = next;
+        }
+        parent->fFirstChild = prev;
+        return false;
+    }
+private:
+    SkTDArray<SkDOM::Node*> fParentStack;
+    SkChunkAlloc*   fAlloc;
+    SkDOM::Node*    fRoot;
+
+    // state needed for flushAttributes()
+    SkTDArray<SkDOM::Attr>  fAttrs;
+    char*                   fElemName;
+    int                     fLevel;
+};
+
+const SkDOM::Node* SkDOM::build(const char doc[], size_t len)
+{
+    fAlloc.reset();
+    SkDOMParser parser(&fAlloc);
+    if (!parser.parse(doc, len))
+    {
+        SkDEBUGCODE(SkDebugf("xml parse error, line %d\n", parser.fParserError.getLineNumber());)
+        fRoot = NULL;
+        fAlloc.reset();
+        return NULL;
+    }
+    fRoot = parser.getRoot();
+    return fRoot;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+static void walk_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLParser* parser)
+{
+    const char* elem = dom.getName(node);
+
+    parser->startElement(elem);
+    
+    SkDOM::AttrIter iter(dom, node);
+    const char*     name;
+    const char*     value;
+    while ((name = iter.next(&value)) != NULL)
+        parser->addAttribute(name, value);
+
+    node = dom.getFirstChild(node, NULL);
+    while (node)
+    {
+        walk_dom(dom, node, parser);
+        node = dom.getNextSibling(node, NULL);
+    }
+
+    parser->endElement(elem);
+}
+
+const SkDOM::Node* SkDOM::copy(const SkDOM& dom, const SkDOM::Node* node)
+{
+    fAlloc.reset();
+    SkDOMParser parser(&fAlloc);
+
+    walk_dom(dom, node, &parser);
+
+    fRoot = parser.getRoot();
+    return fRoot;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+int SkDOM::countChildren(const Node* node, const char elem[]) const
+{
+    int count = 0;
+
+    node = this->getFirstChild(node, elem);
+    while (node)
+    {
+        count += 1;
+        node = this->getNextSibling(node, elem);
+    }
+    return count;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "SkParse.h"
+
+bool SkDOM::findS32(const Node* node, const char name[], int32_t* value) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr && SkParse::FindS32(vstr, value);
+}
+
+bool SkDOM::findScalars(const Node* node, const char name[], SkScalar value[], int count) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr && SkParse::FindScalars(vstr, value, count);
+}
+
+bool SkDOM::findHex(const Node* node, const char name[], uint32_t* value) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr && SkParse::FindHex(vstr, value);
+}
+
+bool SkDOM::findBool(const Node* node, const char name[], bool* value) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr && SkParse::FindBool(vstr, value);
+}
+
+int SkDOM::findList(const Node* node, const char name[], const char list[]) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr ? SkParse::FindList(vstr, list) : -1;
+}
+
+bool SkDOM::hasAttr(const Node* node, const char name[], const char value[]) const
+{
+    const char* vstr = this->findAttr(node, name);
+    return vstr && !strcmp(vstr, value);
+}
+
+bool SkDOM::hasS32(const Node* node, const char name[], int32_t target) const
+{
+    const char* vstr = this->findAttr(node, name);
+    int32_t     value;
+    return vstr && SkParse::FindS32(vstr, &value) && value == target;
+}
+
+bool SkDOM::hasScalar(const Node* node, const char name[], SkScalar target) const
+{
+    const char* vstr = this->findAttr(node, name);
+    SkScalar    value;
+    return vstr && SkParse::FindScalar(vstr, &value) && value == target;
+}
+
+bool SkDOM::hasHex(const Node* node, const char name[], uint32_t target) const
+{
+    const char* vstr = this->findAttr(node, name);
+    uint32_t    value;
+    return vstr && SkParse::FindHex(vstr, &value) && value == target;
+}
+
+bool SkDOM::hasBool(const Node* node, const char name[], bool target) const
+{
+    const char* vstr = this->findAttr(node, name);
+    bool        value;
+    return vstr && SkParse::FindBool(vstr, &value) && value == target;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_DEBUG
+
+static void tab(int level)
+{
+    while (--level >= 0)
+        SkDebugf("\t");
+}
+
+void SkDOM::dump(const Node* node, int level) const
+{
+    if (node == NULL)
+        node = this->getRootNode();
+    if (node)
+    {
+        tab(level);
+        SkDebugf("<%s", this->getName(node));
+
+        const Attr* attr = node->attrs();
+        const Attr* stop = attr + node->fAttrCount;
+        for (; attr < stop; attr++)
+            SkDebugf(" %s=\"%s\"", attr->fName, attr->fValue);
+
+        const Node* child = this->getFirstChild(node);
+        if (child)
+        {
+            SkDebugf(">\n");
+            while (child)
+            {
+                this->dump(child, level+1);
+                child = this->getNextSibling(child);
+            }
+            tab(level);
+            SkDebugf("</%s>\n", node->fName);
+        }
+        else
+            SkDebugf("/>\n");
+    }
+}
+
+void SkDOM::UnitTest()
+{
+#ifdef SK_SUPPORT_UNITTEST
+    static const char gDoc[] = 
+        "<root a='1' b='2'>"
+            "<elem1 c='3' />"
+            "<elem2 d='4' />"
+            "<elem3 e='5'>"
+                "<subelem1/>"
+                "<subelem2 f='6' g='7'/>"
+            "</elem3>"
+            "<elem4 h='8'/>"
+        "</root>"
+        ;
+
+    SkDOM   dom;
+
+    SkASSERT(dom.getRootNode() == NULL);
+
+    const Node* root = dom.build(gDoc, sizeof(gDoc) - 1);
+    SkASSERT(root && dom.getRootNode() == root);
+
+    const char* v = dom.findAttr(root, "a");
+    SkASSERT(v && !strcmp(v, "1"));
+    v = dom.findAttr(root, "b");
+    SkASSERT(v && !strcmp(v, "2"));
+    v = dom.findAttr(root, "c");
+    SkASSERT(v == NULL);
+
+    SkASSERT(dom.getFirstChild(root, "elem1"));
+    SkASSERT(!dom.getFirstChild(root, "subelem1"));
+
+    dom.dump();
+#endif
+}
+
+#endif
+
