public function convertToXml($data, $prefix)
    {
        $nodeName = $prefix;
        // figure out the prefix
        if (!self::isValidPrefix($prefix)) {
            throw new DomiException("invalid prefix '$prefix'");
        }
        
        // if the data needs a list node, change the name to use the list-suffix
        if (self::isListNode($data)) {
            $nodeName = $prefix . $this->listSuffix;
        }

        switch (self::getDataType($data)) {
            // if this array has attributes, do some additional work
            case self::DT_ATTR_ARRAY:
                // create the node, with the optionally specified value
                $node = $this->createElement(
                    $nodeName, 
                    isset($data['values']) ? $data['values'] : null
                );
                $data['attributes'] = 
                    isset($data['attributes']) ? 
                    $data['attributes'] : 
                    array();
                
                // set all of the attributes onto the node
                foreach ($data['attributes'] as $key=>$val) {
                    $node->setAttribute($key, $val);
                }

                // remove the attributes and value so they aren't repeated
                // as children of the element
                unset($data['attributes']);
                unset($data['values']);
            case self::DT_ARRAY:
                // in the case of DT_ATTR_ARRAY, the node is already created
                if (!isset($node)) {
                    $node = $this->createElement($nodeName);
                }

                // attach each child as a subnode
                foreach ($data as $k=>$d) {
                    // figure out the child prefix
                    $childPrefix = self::isValidPrefix($k) ? $k : $prefix;
                    // recurse and attach
                    $node->appendChild($this->convertToXml($d, $childPrefix));
                }
                break;
            
            // when converting DOMi or DOMDocuments, just get the root node
            case self::DT_DOMI:
                // no break
            case self::DT_DOMDOCUMENT:
                $data = $data->childNodes->item(0);
                // no break
            case self::DT_DOMNODE:
                // the node must be imported to be usable in this DOMDocument
                $domNode = $this->importNode($data, true);
                // only create a new node if the prefix and current root
                // node name aren't the same
                if ($prefix == $domNode->nodeName) {
                    $node = $domNode;
                } else {
                    $node = $this->createElement($prefix);
                    $node->appendChild($domNode);
                }
                break;
            
            case self::DT_OBJECT:
                $node = $this->convertToXml(
                    $this->convertObjectToArray($data), 
                    $prefix
                );
                break;
            
            case self::DT_BOOL:
                $data = $data ? 'TRUE' : 'FALSE';
                // no break
            default:
                $node = $this->createElement(
                    $nodeName, 
                    htmlspecialchars((string)$data)
                );
                break;
        }
        
        return $node;
    }