jQuery.fn.createAppend = function(element, attrs, content)
{
    var parentElement = this[0];    
    if (jQuery.browser.msie && element == 'input' && attrs.type) {
        var element = document.createElement('<' + element + ' type="' + attrs.type + '" />');
    } else {
        var element = document.createElement(element);

    };
    if (jQuery.browser.msie && parentElement.nodeName.toLowerCase() == 'table' && element.nodeName.toLowerCase() == 'tr') {
        if (parentElement.parentNode.getElementsByTagName('tbody')[0]) {
            var tbody = parentElement.getElementsByTagName('tbody')[0];
        } else {
            var tbody = parentElement.appendChild(document.createElement('tbody'));
        };
        var element = tbody.appendChild(element);
    } else {
        var element = parentElement.appendChild(element);
    };
    element = __FlyDOM_parseAttrs(element, attrs);
    if (typeof content == 'object' && content != null) {
        for (var i = 0; i < content.length; i = i + 3) {
            jQuery(element).createAppend(content[i], content[i + 1] || {}, content[i + 2] || []);
        };
    } else if (content != null) {
        element = __FlyDOM_setText(element, content);
    };
    return jQuery(element);
}
jQuery.fn.createPrepend = function(element, attrs, content)
{
    var element     = document.createElement(element);
    if (this[0].hasChildNodes() == false) {
        var element = this[0].appendChild(element);
    };
    element = __FlyDOM_parseAttrs(element, attrs);
    if (typeof content == 'object' && content != null) {
        for (var i = 0; i < content.length; i = i + 3) {
            jQuery(element).createAppend(content[i], content[i + 1] || {}, content[i + 2] || []);
        };
    } else if (content != null) {
        element = __FlyDOM_setText(element, content);
    };
    if (this[0].hasChildNodes() == true) {
        var element = this[0].insertBefore(element, this[0].firstChild);
    };
    return jQuery(element);
}
jQuery.fn.tplAppend = function(json, tpl)
{
    if (json.constructor != Array) { json = [ json ]; };
    if (json.length == 0) { return false; };
    for (var i = 0; i < json.length; i++) {
        var results = tpl.apply(json[i]);
        for (var j = 0; j < results.length; j = j + 3) {
            jQuery(this).createAppend(results[j], results[j + 1], results[j + 2]);
        };
    };
    return self;
}
jQuery.fn.tplPrepend = function(json, tpl) {
    var self = this[0];
    if (json.constructor != Array) { json = [ json ]; };
    if (json.length == 0) { return false; };
    var div = document.createElement('div');
    for (var i = 0; i < json.length; i++) {
        var results = tpl.apply(json[i]);
        for (var j = 0; j < results.length; j = j + 3) {
            jQuery(div).createAppend(results[j], results[j + 1], results[j + 2]);
        };
    };
    for (i = div.childNodes.length - 1; i >= 0; i--) {
        if (jQuery.browser.msie && self.nodeName.toLowerCase() == 'table' && div.childNodes[i].nodeName.toLowerCase() == 'tr') {
            if (self.getElementsByTagName('tbody')[0]) {
                var tbodyElement = self.getElementsByTagName('tbody')[0];
                tbodyElement.insertBefore(div.childNodes[i], tbodyElement.firstChild);
            } else {
                var tbodyElement = self.insertBefore(document.createElement('tbody'), self.firstChild);
                tbodyElement.appendChild(tbodyElement.appendChild(div.childNodes[i]));
            };
        } else {
            self.insertBefore(div.childNodes[i], self.firstChild);
        };
    };
    return jQuery(self);
};
String.prototype.toCamelCase = function()
{
    var self = this;
    if (self.indexOf('-') > 0) {
        var parts = self.split('-');
        self = parts[0];
        for (i = 1; i < parts.length; i++) {
            self += parts[i].substr(0, 1).toUpperCase() + parts[i].substr(1).toLowerCase();
        };
    };
    return self;
};
String.prototype.trim = function()
{
    return this.replace(/^\s+|\s+$/g, '');
};
__FlyDOM_parseAttrs = function(element, attrs)
{
    for (attr in attrs) {
        var attrName    = attr;
        var attrValue   = attrs[attr];
        switch (attrName) {
            case 'style':
                if (typeof attrValue == 'string') {
                    var params = attrValue.split(';');
                    for (var i = 0; i < params.length; i++) {
                        if (params[i].trim() != '') {
                            var styleName   = params[i].split(':')[0].trim();
                            var styleValue  = params[i].split(':')[1].trim();
                            styleName = styleName.toCamelCase();
                            if (styleName != '') {
                                element.style[styleName] = styleValue;
                            };
                        };
                    };
                } else if (typeof attrValue == 'object') {
                    for (styleName in attrValue) {
                        var styleNameCamel = styleName.toCamelCase();
                        if (styleName.trim() != '') {
                            element.style[styleNameCamel] = attrValue[styleName];
                        };
                    };
                };
                break;
            default:
                if (attrName.substr(0, 2) == 'on') {
                    var event = attrName.substr(2);
                    attrValue = (typeof attrValue != 'function') ? eval('function() { ' + attrValue + '}') : attrValue;
                    jQuery(element).bind(event, attrValue);
                } else {
                    element[attrName.toCamelCase()] = attrValue;
                }
        };
    };
    return element;
};
__FlyDOM_setText = function(element, content)
{
    var isHtml = /(<\S[^><]*>)|(&.+;)/g;
    if (content.match(isHtml) != null && element.tagName.toUpperCase() != 'TEXTAREA') {
        element.innerHTML = content;
    } else {
        var textNode = document.createTextNode(content);
        element.appendChild(textNode);
    };
    return element;
};
