diff --git a/plstackapi/planetstack/config.py b/plstackapi/planetstack/config.py
new file mode 100644
index 0000000..c9ee5f2
--- /dev/null
+++ b/plstackapi/planetstack/config.py
@@ -0,0 +1,240 @@
+#!/usr/bin/python
+import sys
+import os
+import time
+import ConfigParser
+import tempfile
+import codecs
+from StringIO import StringIO
+from PLC.Xml import Xml
+
+default_config = \
+"""
+"""
+
+def isbool(v):
+    return v.lower() in ("true", "false")
+
+def str2bool(v):
+    return v.lower() in ("true", "1")
+
+class Config:
+
+    def __init__(self, config_file='/etc/planetlab/plcapi_config'):
+        self._files = []
+        self.config_path = os.path.dirname(config_file)
+        self.config = ConfigParser.ConfigParser()
+        self.filename = config_file
+        if not os.path.isfile(self.filename):
+            self.create(self.filename)
+        self.load(self.filename)
+
+
+    def _header(self):
+        header = """
+DO NOT EDIT. This file was automatically generated at
+%s from:
+
+%s
+""" % (time.asctime(), os.linesep.join(self._files))
+
+        # Get rid of the surrounding newlines
+        return header.strip().split(os.linesep)
+
+    def create(self, filename):
+        if not os.path.exists(os.path.dirname(filename)):
+            os.makedirs(os.path.dirname(filename))
+        configfile = open(filename, 'w')
+        configfile.write(default_config)
+        configfile.close()
+
+
+    def load(self, filename):
+        if filename:
+            try:
+                self.config.read(filename)
+            except ConfigParser.MissingSectionHeaderError:
+                if filename.endswith('.xml'):
+                    self.load_xml(filename)
+                else:
+                    self.load_shell(filename)
+            self._files.append(filename)
+            self.set_attributes()
+
+    def load_xml(self, filename):
+        xml = XML(filename)
+        categories = xml.xpath('//configuration/variables/category')
+        for category in categories:
+            section_name = category.get('id')
+            if not self.config.has_section(section_name):
+                self.config.add_section(section_name)
+            options = category.xpath('./variablelist/variable')
+            for option in options:
+                option_name = option.get('id')
+                value = option.xpath('./value')[0].text
+                if not value:
+                    value = ""
+                self.config.set(section_name, option_name, value)
+
+    def load_shell(self, filename):
+        f = open(filename, 'r')
+        for line in f:
+            try:
+                if line.startswith('#'):
+                    continue
+                parts = line.strip().split("=")
+                if len(parts) < 2:
+                    continue
+                option = parts[0]
+                value = parts[1].replace('"', '').replace("'","")
+                section, var = self.locate_varname(option, strict=False)
+                if section and var:
+                    self.set(section, var, value)
+            except:
+                pass
+        f.close()
+
+    def locate_varname(self, varname, strict=True):
+        varname = varname.lower()
+        sections = self.config.sections()
+        section_name = ""
+        var_name = ""
+        for section in sections:
+            if varname.startswith(section.lower()) and len(section) > len(section_name):
+                section_name = section.lower()
+                var_name = varname.replace(section_name, "")[1:]
+        if strict and not self.config.has_option(section_name, var_name):
+            raise ConfigParser.NoOptionError(var_name, section_name)
+        return (section_name, var_name)
+
+    def set_attributes(self):
+        sections = self.config.sections()
+        for section in sections:
+            for item in self.config.items(section):
+                name = "%s_%s" % (section, item[0])
+                value = item[1]
+                if isbool(value):
+                    value = str2bool(value)
+                elif value.isdigit():
+                    value = int(value)
+                setattr(self, name, value)
+                setattr(self, name.upper(), value)
+
+
+    def verify(self, config1, config2, validate_method):
+        return True
+
+    def validate_type(self, var_type, value):
+        return True
+
+    @staticmethod
+    def is_xml(config_file):
+        try:
+            x = Xml(config_file)
+            return True
+        except:
+            return False
+
+    @staticmethod
+    def is_ini(config_file):
+        try:
+            c = ConfigParser.ConfigParser()
+            c.read(config_file)
+            return True
+        except ConfigParser.MissingSectionHeaderError:
+            return False
+
+
+    def dump(self, sections = []):
+        sys.stdout.write(output_python())
+
+    def output_python(self, encoding = "utf-8"):
+        buf = codecs.lookup(encoding)[3](StringIO())
+        buf.writelines(["# " + line + os.linesep for line in self._header()])
+
+        for section in self.sections():
+            buf.write("[%s]%s" % (section, os.linesep))
+            for (name,value) in self.items(section):
+                buf.write("%s=%s%s" % (name,value,os.linesep))
+            buf.write(os.linesep)
+        return buf.getvalue()
+
+    def output_shell(self, show_comments = True, encoding = "utf-8"):
+        """
+        Return variables as a shell script.
+        """
+
+        buf = codecs.lookup(encoding)[3](StringIO())
+        buf.writelines(["# " + line + os.linesep for line in self._header()])
+
+        for section in self.sections():
+            for (name,value) in self.items(section):
+                # bash does not have the concept of NULL
+                if value:
+                    option = "%s_%s" % (section.upper(), name.upper())
+                    if isbool(value):
+                        value = str(str2bool(value))
+                    elif not value.isdigit():
+                        value = '"%s"' % value
+                    buf.write(option + "=" + value + os.linesep)
+        return buf.getvalue()
+
+    def output_php(self, encoding = "utf-8"):
+        """
+        Return variables as a PHP script.
+        """
+
+        buf = codecs.lookup(encoding)[3](StringIO())
+        buf.write("<?php" + os.linesep)
+        buf.writelines(["// " + line + os.linesep for line in self._header()])
+
+        for section in self.sections():
+            for (name,value) in self.items(section):
+                option = "%s_%s" % (section, name)
+                buf.write(os.linesep)
+                buf.write("// " + option + os.linesep)
+                if value is None:
+                    value = 'NULL'
+                buf.write("define('%s', %s);" % (option, value) + os.linesep)
+
+        buf.write("?>" + os.linesep)
+
+        return buf.getvalue()
+
+    def output_xml(self, encoding = "utf-8"):
+        pass
+
+    def output_variables(self, encoding="utf-8"):
+        """
+        Return list of all variable names.
+        """
+
+        buf = codecs.lookup(encoding)[3](StringIO())
+        for section in self.sections():
+            for (name,value) in self.items(section):
+                option = "%s_%s" % (section,name)
+                buf.write(option + os.linesep)
+
+        return buf.getvalue()
+        pass
+
+    def write(self, filename=None):
+        if not filename:
+            filename = self.filename
+        configfile = open(filename, 'w')
+        self.config.write(configfile)
+
+    def save(self, filename=None):
+        self.write(filename)
+
+    def __getattr__(self, attr):
+        return getattr(self.config, attr)
+
+if __name__ == '__main__':
+    filename = None
+    if len(sys.argv) > 1:
+        filename = sys.argv[1]
+        config = Config(filename)
+    else:
+        config = Config()
+    config.dump()
diff --git a/plstackapi/util/__init__.py b/plstackapi/util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plstackapi/util/__init__.py
diff --git a/plstackapi/util/xml.py b/plstackapi/util/xml.py
new file mode 100644
index 0000000..7b6c72a
--- /dev/null
+++ b/plstackapi/util/xml.py
@@ -0,0 +1,347 @@
+#!/usr/bin/python
+from types import StringTypes
+from lxml import etree
+from StringIO import StringIO
+
+# helper functions to help build xpaths
+class XpathFilter:
+    @staticmethod
+
+    def filter_value(key, value):
+        xpath = ""
+        if isinstance(value, str):
+            if '*' in value:
+                value = value.replace('*', '')
+                xpath = 'contains(%s, "%s")' % (key, value)
+            else:
+                xpath = '%s="%s"' % (key, value)
+        return xpath
+
+    @staticmethod
+    def xpath(filter={}):
+        xpath = ""
+        if filter:
+            filter_list = []
+            for (key, value) in filter.items():
+                if key == 'text':
+                    key = 'text()'
+                else:
+                    key = '@'+key
+                if isinstance(value, str):
+                    filter_list.append(XpathFilter.filter_value(key, value))
+                elif isinstance(value, list):
+                    stmt = ' or '.join([XpathFilter.filter_value(key, str(val)) for val in value])
+                    filter_list.append(stmt)
+            if filter_list:
+                xpath = ' and '.join(filter_list)
+                xpath = '[' + xpath + ']'
+        return xpath
+
+# a wrapper class around lxml.etree._Element
+# the reason why we need this one is because of the limitations
+# we've found in xpath to address documents with multiple namespaces defined
+# in a nutshell, we deal with xml documents that have
+# a default namespace defined (xmlns="http://default.com/") and specific prefixes defined
+# (xmlns:foo="http://foo.com")
+# according to the documentation instead of writing
+# element.xpath ( "//node/foo:subnode" )
+# we'd then need to write xpaths like
+# element.xpath ( "//{http://default.com/}node/{http://foo.com}subnode" )
+# which is a real pain..
+# So just so we can keep some reasonable programming style we need to manage the
+# namespace map that goes with the _Element (its internal .nsmap being unmutable)
+class XmlElement:
+    def __init__(self, element, namespaces):
+        self.element = element
+        self.namespaces = namespaces
+
+    # redefine as few methods as possible
+    def xpath(self, xpath, namespaces=None):
+        if not namespaces:
+            namespaces = self.namespaces
+        elems = self.element.xpath(xpath, namespaces=namespaces)
+        return [XmlElement(elem, namespaces) for elem in elems]
+
+    def add_element(self, tagname, **kwds):
+        element = etree.SubElement(self.element, tagname, **kwds)
+        return XmlElement(element, self.namespaces)
+
+    def append(self, elem):
+        if isinstance(elem, XmlElement):
+            self.element.append(elem.element)
+        else:
+            self.element.append(elem)
+
+    def getparent(self):
+        return XmlElement(self.element.getparent(), self.namespaces)
+
+    def get_instance(self, instance_class=None, fields=[]):
+        """
+        Returns an instance (dict) of this xml element. The instance
+        holds a reference to this xml element.
+        """
+        if not instance_class:
+            instance_class = Object
+        if not fields and hasattr(instance_class, 'fields'):
+            fields = instance_class.fields
+
+        if not fields:
+            instance = instance_class(self.attrib, self)
+        else:
+            instance = instance_class({}, self)
+            for field in fields:
+                if field in self.attrib:
+                   instance[field] = self.attrib[field]
+        return instance
+
+    def add_instance(self, name, instance, fields=[]):
+        """
+        Adds the specifed instance(s) as a child element of this xml
+        element.
+        """
+        if not fields and hasattr(instance, 'keys'):
+            fields = instance.keys()
+        elem = self.add_element(name)
+        for field in fields:
+            if field in instance and instance[field]:
+                elem.set(field, unicode(instance[field]))
+        return elem
+
+    def remove_elements(self, name):
+        """
+        Removes all occurences of an element from the tree. Start at
+        specified root_node if specified, otherwise start at tree's root.
+        """
+
+        if not element_name.startswith('//'):
+            element_name = '//' + element_name
+        elements = self.element.xpath('%s ' % name, namespaces=self.namespaces)
+        for element in elements:
+            parent = element.getparent()
+            parent.remove(element)
+
+    def delete(self):
+        parent = self.getparent()
+        parent.remove(self)
+
+    def remove(self, element):
+        if isinstance(element, XmlElement):
+            self.element.remove(element.element)
+        else:
+            self.element.remove(element)
+
+    def set_text(self, text):
+        self.element.text = text
+
+    # Element does not have unset ?!?
+    def unset(self, key):
+        del self.element.attrib[key]
+
+    def toxml(self):
+        return etree.tostring(self.element, encoding='UTF-8', pretty_print=True)
+
+    def __str__(self):
+        return self.toxml()
+
+    # are redirected on self.element
+    def __getattr__ (self, name):
+        if not hasattr(self.element, name):
+            raise AttributeError, name
+        return getattr(self.element, name)
+
+class Xml:
+
+    def __init__(self, xml=None, namespaces=None):
+        self.root = None
+        self.namespaces = namespaces
+        self.default_namespace = None
+        self.schema = None
+        if isinstance(xml, basestring):
+            self.parse_xml(xml)
+        if isinstance(xml, XmlElement):
+            self.root = xml
+            self.namespaces = xml.namespaces
+        elif isinstance(xml, etree._ElementTree) or isinstance(xml, etree._Element):
+            self.parse_xml(etree.tostring(xml))
+
+    def parse_xml(self, xml):
+        """
+        parse rspec into etree
+        """
+        parser = etree.XMLParser(remove_blank_text=True)
+        try:
+            tree = etree.parse(xml, parser)
+        except IOError:
+            # 'rspec' file doesnt exist. 'rspec' is proably an xml string
+            try:
+                tree = etree.parse(StringIO(xml), parser)
+            except Exception, e:
+                raise Exception, str(e)
+        root = tree.getroot()
+        self.namespaces = dict(root.nsmap)
+        # set namespaces map
+        if 'default' not in self.namespaces and None in self.namespaces:
+            # If the 'None' exist, then it's pointing to the default namespace. This makes
+            # it hard for us to write xpath queries for the default naemspace because lxml
+            # wont understand a None prefix. We will just associate the default namespeace
+            # with a key named 'default'.
+            self.namespaces['default'] = self.namespaces.pop(None)
+
+        else:
+            self.namespaces['default'] = 'default'
+
+        self.root = XmlElement(root, self.namespaces)
+        # set schema
+        for key in self.root.attrib.keys():
+            if key.endswith('schemaLocation'):
+                # schemaLocation should be at the end of the list.
+                # Use list comprehension to filter out empty strings
+                schema_parts  = [x for x in self.root.attrib[key].split(' ') if x]
+                self.schema = schema_parts[1]
+                namespace, schema  = schema_parts[0], schema_parts[1]
+                break
+
+    def parse_dict(self, d, root_tag_name='xml', element = None):
+        if element is None:
+            if self.root is None:
+                self.parse_xml('<%s/>' % root_tag_name)
+            element = self.root.element
+
+        if 'text' in d:
+            text = d.pop('text')
+            element.text = text
+
+        # handle repeating fields
+        for (key, value) in d.items():
+            if isinstance(value, list):
+                value = d.pop(key)
+                for val in value:
+                    if isinstance(val, dict):
+                        child_element = etree.SubElement(element, key)
+                        self.parse_dict(val, key, child_element)
+                    elif isinstance(val, basestring):
+                        child_element = etree.SubElement(element, key).text = val
+
+            elif isinstance(value, int):
+                d[key] = unicode(d[key])
+            elif value is None:
+                d.pop(key)
+
+        # element.attrib.update will explode if DateTimes are in the
+        # dcitionary.
+        d=d.copy()
+        # looks like iteritems won't stand side-effects
+        for k in d.keys():
+            if not isinstance(d[k],StringTypes):
+                del d[k]
+
+        element.attrib.update(d)
+
+    def validate(self, schema):
+        """
+        Validate against rng schema
+        """
+        relaxng_doc = etree.parse(schema)
+        relaxng = etree.RelaxNG(relaxng_doc)
+        if not relaxng(self.root):
+            error = relaxng.error_log.last_error
+            message = "%s (line %s)" % (error.message, error.line)
+            raise Exception, message
+        return True
+
+    def xpath(self, xpath, namespaces=None):
+        if not namespaces:
+            namespaces = self.namespaces
+        return self.root.xpath(xpath, namespaces=namespaces)
+
+    def set(self, key, value):
+        return self.root.set(key, value)
+
+    def remove_attribute(self, name, element=None):
+        if not element:
+            element = self.root
+        element.remove_attribute(name)
+
+    def add_element(self, *args, **kwds):
+        """
+        Wrapper around etree.SubElement(). Adds an element to
+        specified parent node. Adds element to root node is parent is
+        not specified.
+        """
+        return self.root.add_element(*args, **kwds)
+
+    def remove_elements(self, name, element = None):
+        """
+        Removes all occurences of an element from the tree. Start at
+        specified root_node if specified, otherwise start at tree's root.
+        """
+        if not element:
+            element = self.root
+
+        element.remove_elements(name)
+
+    def add_instance(self, *args, **kwds):
+        return self.root.add_instance(*args, **kwds)
+
+    def get_instance(self, *args, **kwds):
+        return self.root.get_instnace(*args, **kwds)
+
+    def get_element_attributes(self, elem=None, depth=0):
+        if elem == None:
+            elem = self.root
+        if not hasattr(elem, 'attrib'):
+            # this is probably not an element node with attribute. could be just and an
+            # attribute, return it
+            return elem
+        attrs = dict(elem.attrib)
+        attrs['text'] = str(elem.text).strip()
+        attrs['parent'] = elem.getparent()
+        if isinstance(depth, int) and depth > 0:
+            for child_elem in list(elem):
+                key = str(child_elem.tag)
+                if key not in attrs:
+                    attrs[key] = [self.get_element_attributes(child_elem, depth-1)]
+                else:
+                    attrs[key].append(self.get_element_attributes(child_elem, depth-1))
+        else:
+            attrs['child_nodes'] = list(elem)
+        return attrs
+
+    def append(self, elem):
+        return self.root.append(elem)
+
+    def iterchildren(self):
+        return self.root.iterchildren()
+
+    def merge(self, in_xml):
+        pass
+
+    def __str__(self):
+        return self.toxml()
+
+    def toxml(self):
+        return etree.tostring(self.root.element, encoding='UTF-8', pretty_print=True)
+
+    # XXX smbaker, for record.load_from_string
+    def todict(self, elem=None):
+        if elem is None:
+            elem = self.root
+        d = {}
+        d.update(elem.attrib)
+        d['text'] = elem.text
+        for child in elem.iterchildren():
+            if child.tag not in d:
+                d[child.tag] = []
+            d[child.tag].append(self.todict(child))
+
+        if len(d)==1 and ("text" in d):
+            d = d["text"]
+
+        return d
+
+    def save(self, filename):
+        f = open(filename, 'w')
+        f.write(self.toxml())
+        f.close()
+
+    
