/**
 *
 * Taken almost verbatim from ECTYPE.xml.XMLDocument.parseXML
 *
 */
var HTMLFragment = function(source)
{
    if (!source) return;

function translateAttributeName(attrName)
{
    altNames = {
        'class': 'className',
        'colspan': 'colSpan'
    }
    return altNames[attrName] || attrName;
}

    // Internal "constants"
    var CLOSING_TAG = 'closingTag';
    var OPENING_TAG = 'openingTag';
    var SELF_CLOSING_TAG = 'selfClosingTag';
    var TEXT = 'text';
    var COMMENT = 'comment';
    var DIRECTIVE = 'directive';

    //
    //
    // Parse the String; create an Array of all the tags and text nodes.
    //
    //
    
    var xmlChunks = source.split('<');
    var tmp;
    var text;
this.shitaki = new HTMLElement(document.createElement('div'));
//    var currentParent = this;
var currentParent = this.shitaki;
    
    for (var i = 0; i < xmlChunks.length; i++)
    {
        tmp = xmlChunks[i];

        if (tmp.charAt(tmp.length - 1) == '>')
        {
            // The chunk is a single tag.
            text = null;
        }
        else
        {
            // The chunk contains a text node. Get it out.
            var lastGTIndex = tmp.lastIndexOf('>');
            text = tmp.substring(lastGTIndex + 1);
            tmp = tmp.substring(0, lastGTIndex + 1);
        }

        if (tmp)
        {
            var fragmentType;
            var firstChar = tmp.charAt(0);

            // Determine the fragment type.
            switch(firstChar)
            {
                case '/':
                    fragmentType = CLOSING_TAG;
                    break;
                case '!':
                    fragmentType = COMMENT;
                    break;
                case '?':
                    fragmentType = DIRECTIVE;
                    break;
                default:
                    fragmentType = OPENING_TAG;
                    var isSelfClosing = tmp.substring(tmp.length - 2) == '/>';
                    break;
            }

            //
            // Build the node.
            //

            var node = null;

            switch (fragmentType)
            {
                case OPENING_TAG:

                    tmp = isSelfClosing ? tmp.substring(0, tmp.length - 2) : tmp.substring(0, tmp.length - 1);
   
                    // Split the node into chunks so we can get the attributes, etc.
                    tmp = tmp.replace(/^\s+|\s+$/g, '');
                    var firstSpace = tmp.indexOf(' ');
                    var nodeName = tmp.substring(0, firstSpace == -1 ? tmp.length : firstSpace);
                    tmp = tmp.substring(firstSpace + 1);
                    var tagChunks = tmp.split('="');

                    //
                    // Create the node.
                    //
//                    node = this.createElement(nodeName);
                    node = new HTMLElement(document.createElement(nodeName));

                    //
                    // Get the attributes.
                    //
                    for (var j = 1; j < tagChunks.length; j++)
                    {
                        var lastSpace = tagChunks[j - 1].lastIndexOf(' ');
                        var attrName = tagChunks[j - 1].substring(lastSpace == -1 ? 0 : lastSpace).replace(/^\s+|\s+$/g, '');                            
                        
                        tmp = tagChunks[j];
                        if (j != tagChunks.length - 1)
                        {
                            lastSpace = tmp.lastIndexOf(' ');
                            tmp = tmp.substring(0, lastSpace);
                        }
                        var attrValue = tmp.substring(0, tmp.length - 1);

//                        node.attributes[attrName] = attrValue;
                        node[translateAttributeName(attrName)] = attrValue;
                    }

                    break;
                   case CLOSING_TAG:
                       currentParent = currentParent.parentNode;
                       break;
               }

            // Append the node to the tree.
            if (node && (node != currentParent))
            {
                currentParent.appendChild(node);
            }
            
            // If this is an opening tag, then make subsequent nodes its
            // children.
            if (!isSelfClosing && (fragmentType == OPENING_TAG))
            {
                currentParent = node;
            }                
            
            if (text)
            {
                // Create the text node, unless ignoreWhite is true and the
                // node is all whitespace.
                if (!this.ignoreWhite || text.replace(/\s+/, '').length)
                {
//                    node = this.createTextNode(text);
                    node = document.createTextNode(text);
                    currentParent.appendChild(node);
                }
            }
        }
    }
    
return this.shitaki;
}
