var Builder = {
    node : function(elementName)
    {
        var element = document.createElement(elementName);
        if (!element) {
            return null;
        }

        if (arguments[1]) {
            var attrs = arguments[1];
            if (this._isScalar(attrs) || attrs instanceof Array || attrs.tagName) {
                this._children(element, attrs);
            }
            else {
                this._attributes(element, attrs);
            }
        }

        if (arguments[2]) {
            this._children(element, arguments[2]);
        }

        return $(element);
    },
    _isScalar : function(x)
    {
        var t = typeof x;
        return 'string' == t || 'number' == t;
    },
    _text : function(text)
    {
        return document.createTextNode(text);
    },
    _attributes : function(element, attributes)
    {
        for (var attribute in attributes) {
            var value = attributes[attribute];
            if ('class' == attribute || 'className' == attribute) {
                element.className = value;
            }
            else if ('style' == attribute && element.style.setAttribute) {
                element.style.setAttribute('cssText', value);
            }
            else {
                element.setAttribute(attribute, value);
            }
        }

        return element;
    },
    _children : function(element, children)
    {
        if (children.tagName) {
            element.appendChild(children);
            return;
        }

        if ('object' == typeof children) {
            children.flatten().each(
                function(node)
                {
                    if ('object' == typeof node) {
                        element.appendChild(node);
                    }
                    else if (true == this._isScalar(node)) {
                        element.appendChild(this._text(node));
                    }
                }.bind(this)
            );
        }
        else {
            if (true == this._isScalar(children)) {
                element.appendChild(this._text(children));
            }
        }
    },
    build : function(html)
    {
        return this.node('div').update(html.strip()).down();
    }
};
