Element.prototype.getOuterXHTML = function()  {
    var mainstart = "<";
    mainstart += this.tagName.toLowerCase();
    var mainattrs = this.attributes;
    for (var z = 0; z < mainattrs.length; z++ ) {
        mainstart += " ";
        mainstart += mainattrs[z].nodeName.toLowerCase();
        mainstart += "=\"";
        mainstart += mainattrs[z].nodeValue.replace(/\"/g,"&quot;");
        mainstart += "\"";
    }
    var maintn = this.tagName.toLowerCase();
    if ( !this.hasChildNodes() ) {
        mainstart += " />";
        return mainstart;
    } else {
        mainstart += ">";
    }
    var markup = mainstart;
    function getMarkupFor( currentNode ) {
        var kids = currentNode.childNodes;
        for ( var i = 0; i < kids.length; i++ ) {
            if ( kids[i].nodeName == "#text" ) {
                markup += kids[i].nodeValue;
            } else if ( kids[i].nodeName == "#cdata-section" ) {
                markup += unescape("%3C!%5BCDATA%5B");
                markup += kids[i].nodeValue;
                markup += unescape("%5D%5D%3E");
            } else if ( kids[i].nodeName == "#comment" ) {
                markup += "<!-- ";
                markup += kids[i].nodeValue;
                markup += " -->";
            } else {
                markup += "<";
                markup += kids[i].tagName.toLowerCase();
                var attrs = kids[i].attributes;
                for ( var a = 0; a < attrs.length; a++ ) {
                    markup += " ";
                    markup += attrs[a].nodeName.toLowerCase();
                    markup += "=\"";
                    markup += attrs[a].nodeValue.replace(/\"/g,"&quot;");
                    markup += "\"";
                }
                if ( !kids[i].hasChildNodes() ) {
                    markup += "/>";
                } else {
                    markup += ">";
                    getMarkupFor( kids[i] );
                    markup += "<";
                    markup += "/";
                    markup += kids[i].tagName.toLowerCase();
                    markup += ">";
                }
            }
        }
    }
    getMarkupFor( this );
    markup += "</";
    markup += this.tagName.toLowerCase();
    markup += ">";
    return markup;
};

win.addEventListener("load", function() {
    var obj = doc.createElementNS(namespace, "object" );
    for ( var i in attributes ) {
        obj.setAttributeNS("", i, attributes[i] );
    }
    for ( var i in params ) {
        var p  = doc.createElementNS(namespace, "param");
        p.setAttributeNS("", "name", i );
        p.setAttributeNS("", "value", params[i] );
        p.setAttributeNS("", "class", plugin + "_" + i );
        obj.appendChild( p );
    }
    var alt = new DOMParser().parseFromString('<span xmlns="' + namespace + '" class="' + plugin + '_error">' + fallback + '</span>', "application/xhtml+xml");
    obj.appendChild( doc.importNode( alt.documentElement, true ) );
    var container = doc.createElementNS( namespace, "div" );
    container.setAttributeNS("", "class", plugin + "_container" );
    container.appendChild( obj );
    doc.body.appendChild( container );
    var pre = doc.createElementNS(namespace, "pre" );
    var unresolve_data_search =  'data="' + obj.getAttributeNS("", "codebase");
    var remove_namespace = ' xmlns="' + namespace + '"';
    pre.appendChild( doc.createTextNode( container.getOuterXHTML().replace(unresolve_data_search, 'data="' ).replace(remove_namespace,"").replace(/></g,">\n    <").replace(/<param/ig,"    <param").replace(/<span/i,"    <span").replace(/error\">\n    /,'error\">').replace(/    <\/div>/i,"</div>").replace(/ valuetype=\"data\"/ig,"") ) );
    pre.style.fontSize = "16px";
    pre.style.fontFamily = "monospace";
    doc.body.appendChild( pre );
}, false);