diff --git a/asterix-examples/src/main/resources/html/example.html b/asterix-examples/src/main/resources/html/example.html
index 0a3af38..01f6ed0 100644
--- a/asterix-examples/src/main/resources/html/example.html
+++ b/asterix-examples/src/main/resources/html/example.html
@@ -1,15 +1,56 @@
 <!DOCTYPE html>
 <html>
     <head>
-        <script src="http://localhost:19101/sdk/static/js/asterix-api-core.js"
-            type="text/javascript"></script>
+        <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
+        <script src="../js/easyXDM/easyXDM.debug.js" type="text/javascript"></script>
+        <script src="http://localhost:19101/sdk/static/js/asterix-api-core.js" type="text/javascript"></script>
         <script src="../js/example.js" type="text/javascript"></script> 
         <script>
-            var a = new AsterixAPI();
-            a.test();
+            $(function () {
+                var as = new AsterixSDK();
+                var c = new CreateExpression(tinySocialCreate.join("\n"));
+                as.send(c);
+
+                $('#ddl').html(tinySocialCreate.join("<br/>"));
+            });
         </script>
     </head>
     <body>
-         
+        <div>
+            Example: DDL
+            <div class="syntax-box" id="ddl">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+        
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
     </body>
 </html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt b/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt
new file mode 100644
index 0000000..4320fb1
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2009-2011 Øyvind Sean Kinsey, oyvind@kinsey.no
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/cors/index.html b/asterix-examples/src/main/resources/js/easyXDM/cors/index.html
new file mode 100644
index 0000000..9370e1d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/cors/index.html
@@ -0,0 +1,214 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM cross-domain XHMLHttpRequest provider</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // This should be changed so that it points to the minified version before use in production.
+        </script>
+        <script type="text/javascript">
+            // Update to point to your copy
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+        
+        /* 
+         * This is a CORS (Cross-Origin Resource Sharing) and AJAX enabled endpoint for easyXDM.
+         * The ACL code is adapted from pmxdr (http://github.com/eligrey/pmxdr/) by Eli Grey (http://eligrey.com/)
+         *
+         */
+        // From http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+        function isHostMethod(object, property){
+            var t = typeof object[property];
+            return t == 'function' ||
+            (!!(t == 'object' && object[property])) ||
+            t == 'unknown';
+        }
+        
+        /**
+         * Creates a cross-browser XMLHttpRequest object
+         * @return {XMLHttpRequest} A XMLHttpRequest object.
+         */
+        var getXhr = (function(){
+            if (isHostMethod(window, "XMLHttpRequest")) {
+                return function(){
+                    return new XMLHttpRequest();
+                };
+            }
+            else {
+                var item = (function(){
+                    var list = ["Microsoft", "Msxml2", "Msxml3"], i = list.length;
+                    while (i--) {
+                        try {
+                            item = list[i] + ".XMLHTTP";
+                            var obj = new ActiveXObject(item);
+                            return item;
+                        } 
+                        catch (e) {
+                        }
+                    }
+                }());
+                return function(){
+                    return new ActiveXObject(item);
+                };
+            }
+        }());
+        
+        // this file is by default set up to use Access Control - this means that it will use the headers set by the server to decide whether or not to allow the call to return
+        var useAccessControl = true;
+        // always trusted origins, can be exact strings or regular expressions
+        var alwaysTrustedOrigins = [(/\.?easyxdm\.net/), (/xdm1/)];
+        
+        // instantiate a new easyXDM object which will handle the request 
+        var remote = new easyXDM.Rpc({
+            local: "../name.html",
+            swf: "../easyxdm.swf"
+        }, {
+            local: {
+                // define the exposed method
+                request: function(config, success, error){
+                
+                    // apply default values if not set
+                    easyXDM.apply(config, {
+                        method: "POST",
+                        headers: {
+                            "Content-Type": "application/x-www-form-urlencoded",
+                            "X-Requested-With": "XMLHttpRequest"
+                        },
+                        success: Function.prototype,
+                        error: function(msg){
+                            throw new Error(msg);
+                        },
+                        data: {},
+                        timeout: 10 * 1000
+                    }, true);
+                    
+                    // set the CORS request header
+                    // only if there is no XHR2 features
+                    if (!window.XMLHttpRequest || !('withCredentials' in (new XMLHttpRequest))) {
+                        config.headers.Origin = remote.origin;
+                    }
+                    
+                    var isPOST = config.method == "POST";
+                    
+                    // convert the data into a format we can send to the server 
+                    var pairs = [];
+                    for (var key in config.data) {
+                        if (config.data.hasOwnProperty(key)) {
+                            pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(config.data[key]));
+                        }
+                    }
+                    var data = pairs.join("&");
+                    
+                    // create the XMLHttpRequest object
+                    var req = getXhr();
+                    var url = !isPOST && data
+                        ? config.url + (~config.url.indexOf('?') ? '&' : '?') + data
+                        : config.url;
+                    req.open(config.method, url, true);
+                    
+                    // apply the request headers
+                    for (var prop in config.headers) {
+                        if (config.headers.hasOwnProperty(prop) && config.headers[prop]) {
+                            req.setRequestHeader(prop, config.headers[prop]);
+                        }
+                    }
+                    
+                    // set a timeout
+                    var timeout;
+                    timeout = setTimeout(function(){
+                        // reset the handler
+                        req.onreadystatechange = Function.prototype;
+                        req.abort();
+                        req = null;
+                        error({
+                            message: "timeout after " + config.timeout + " second",
+                            status: 0,
+                            data: null,
+                            toString: function(){
+                                return this.message + " Status: " + this.status;
+                            }
+                        }, null);
+                    }, config.timeout);
+                    
+                    // check if this origin should always be trusted
+                    var alwaysTrusted = false, i = alwaysTrustedOrigins.length;
+                    while (i-- && !alwaysTrusted) {
+                        if (alwaysTrustedOrigins[i] instanceof RegExp) {
+                            alwaysTrusted = alwaysTrustedOrigins[i].test(remote.origin);
+                        }
+                        else if (typeof alwaysTrustedOrigins[i] == "string") {
+                            alwaysTrusted = (remote.origin === alwaysTrustedOrigins[i]);
+                        }
+                    }
+                    
+                    
+                    // define the onreadystate handler
+                    req.onreadystatechange = function(){
+                        if (req.readyState == 4) {
+                            clearTimeout(timeout);
+                            
+                            // parse the response headers
+                            var rawHeaders = req.getAllResponseHeaders(), headers = {}, headers_lowercase = {}, reHeader = /([\w-_]+):\s+(.*)$/gm, m;
+                            while ((m = reHeader.exec(rawHeaders))) {
+                                headers_lowercase[m[1].toLowerCase()] = headers[m[1]] = m[2];
+                            }
+                            
+                            if (req.status < 200 || req.status >= 300) {
+                                if (useAccessControl) {
+                                    error("INVALID_STATUS_CODE");
+                                }
+                                else {
+                                    error("INVALID_STATUS_CODE", {
+                                        status: req.status,
+                                        data: req.responseText
+                                    });
+                                }
+                            }
+                            else {
+                            
+                                var errorMessage;
+                                if (useAccessControl) {
+                                    // normalize the valuse access controls
+                                    var aclAllowedOrigin = (headers_lowercase["access-control-allow-origin"] || "").replace(/\s/g, "");
+                                    var aclAllowedMethods = (headers_lowercase["access-control-allow-methods"] || "").replace(/\s/g, "");
+                                    
+                                    // determine if origin is trusted
+                                    if (alwaysTrusted || aclAllowedOrigin == "*" || aclAllowedOrigin.indexOf(remote.origin) != -1) {
+                                        // determine if the request method was allowed
+                                        if (aclAllowedMethods && aclAllowedMethods != "*" && aclAllowedMethods.indexOf(config.method) == -1) {
+                                            errorMessage = "DISALLOWED_REQUEST_METHOD";
+                                        }
+                                    }
+                                    else {
+                                        errorMessage = "DISALLOWED_ORIGIN";
+                                    }
+                                    
+                                }
+                                
+                                if (errorMessage) {
+                                    error(errorMessage);
+                                }
+                                else {
+                                    success({
+                                        data: req.responseText,
+                                        status: req.status,
+                                        headers: headers
+                                    });
+                                }
+                            }
+                            // reset the handler
+                            req.onreadystatechange = Function.prototype;
+                            req = null;
+                        }
+                    };
+                    
+                    // issue the request
+                    req.send(isPOST ? data : "");
+                }
+            }
+        });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip b/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip
new file mode 100644
index 0000000..c44301f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js
new file mode 100644
index 0000000..7dcf4bd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js
@@ -0,0 +1,333 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*jslint browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window */
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/**
+ * @class easyXDM.WidgetManager
+ * A class for managing widgets.<br/>
+ * Handles initializing widgets, and does all of the message distribution.
+ <pre><code>
+ _widgetManager = new easyXDM.WidgetManager({
+ local: "../hash.html",
+ container: document.getElementById("defaultcontainer")
+ },function(){
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{});
+ });
+ </code></pre>
+ * Widgets can by dynamically added using the addWidget method
+ <pre><code>
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{
+ container document.getElementById("widgetcontainer")
+ });
+ </code></pre>
+ * @constructor
+ * @param {Object} config The WidgetManagers configuration
+ * @namespace easyXDM
+ */
+easyXDM.WidgetManager = function(config){
+    var WidgetManager = this, _hashUrl = config.local, _channelNr = 0;
+    var Events = {
+        WidgetInitialized: "widgetinitialized",
+        WidgetFailed: "widgetfailed"
+    };
+    var _widgets = {}, _subscribers = {};
+    var _widgetSettings = {
+        hosturl: location.href
+    };
+    easyXDM.apply(_widgetSettings, config.widgetSettings);
+    var _container = config.container || document.body;
+    
+    /**
+     * @private
+     * Raises the specified event
+     * @param {String} event The raised event
+     * @param {Object} arg
+     */
+    function _raiseEvent(event, arg){
+        if (config.listeners && config.listeners[event]) {
+            config.listeners[event](WidgetManager, arg);
+        }
+    }
+    
+    /**
+     * @private
+     * Adds the widghet to the list of subscribers for the given topic
+     * @param {String} url The widgets url
+     * @param {String} topic The topic to subscribe to
+     */
+    function _subscribe(url, topic){
+        if (!(topic in _subscribers)) {
+            _subscribers[topic] = [];
+        }
+        _subscribers[topic].push(url);
+    }
+    
+    /**
+     * @private
+     * Initialized the widget.<br/>
+     * This is called after the widget has notified that it is ready.
+     * @param {Object} widget The widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _initializeWidget(widget, url, widgetConfig){
+        widget.initialize(_widgetSettings, function(response){
+            if (response.isInitialized) {
+                _widgets[url] = widget;
+                var i = response.subscriptions.length;
+                while (i--) {
+                    _subscribe(url, response.subscriptions[i]);
+                }
+                _raiseEvent(Events.WidgetInitialized, {
+                    url: url
+                });
+            }
+            else {
+                widget.destroy();
+                _raiseEvent(Events.WidgetFailed, {
+                    url: url
+                });
+            }
+        });
+    }
+    
+    /**
+     * @private
+     * Publishes the data to the topics subscribers
+     * @param {String} url The senders url
+     * @param {String} topic The datas topic
+     * @param {Object} data The data to publish
+     */
+    function _publish(url, topic, data){
+        var subscribers = _subscribers[topic];
+        if (subscribers) {
+            var i = subscribers.length, widgetUrl;
+            while (i--) {
+                widgetUrl = subscribers[i];
+                if (widgetUrl !== url) {
+                    _widgets[widgetUrl].send(url, topic, data);
+                }
+            }
+        }
+    }
+    
+    /**
+     * @private
+     * Sets up a new widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _setUpWidget(url, widgetConfig){
+        var widget = new easyXDM.Rpc({
+            channel: "widget" + _channelNr++,
+            local: _hashUrl,
+            remote: url,
+            container: widgetConfig.container || _container,
+            swf: config.swf,
+            onReady: function(){
+                _initializeWidget(widget, url, widgetConfig);
+            }
+        }, {
+            local: {
+                subscribe: {
+                    isVoid: true,
+                    method: function(topic){
+                        _subscribe(url, topic);
+                    }
+                },
+                publish: {
+                    isVoid: true,
+                    method: function(topic, data){
+                        _publish(url, topic, data);
+                    }
+                }
+            },
+            remote: {
+                initialize: {},
+                send: {
+                    isVoid: true
+                }
+            }
+        });
+    }
+    
+    /**
+     * Adds a widget to the collection
+     * @param {String} url The url to load the widget from
+     * @param {Object} widgetConfig The widgets url
+     */
+    this.addWidget = function(url, widgetConfig){
+        if (url in _widgets) {
+            throw new Error("A widget with this url has already been initialized");
+        }
+        _setUpWidget(url, widgetConfig);
+    };
+    
+    /**
+     * Removes the widget
+     * @param {Object} url
+     */
+    this.removeWidget = function(url){
+        if (url in _widgets) {
+            for (var topic in _subscribers) {
+                if (_subscribers.hasOwnProperty(topic)) {
+                    var subscribers = _subscribers[topic], i = subscribers.length;
+                    while (i--) {
+                        if (subscribers[i] === url) {
+                            subscribers.splice(i, 1);
+                            break;
+                        }
+                    }
+                }
+            }
+            _widgets[url].destroy();
+            delete _widgets[url];
+        }
+    };
+    
+    /**
+     * Publish data to a topics subscribers
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _publish("", topic, data);
+    };
+    
+    /**
+     * Broadcasts data to all the widgets
+     * @param {Object} data The data to broadcast
+     */
+    this.broadcast = function(data){
+        for (var url in _widgets) {
+            if (_widgets.hasOwnPropert(url)) {
+                _widgets[url].send({
+                    url: "",
+                    topic: "broadcast",
+                    data: data
+                });
+            }
+        }
+    };
+};
+
+/**
+ * @class easyXDM.Widget
+ * The base framework for creating widgets
+ * @constructor
+ * @param {Object} config The widgets configuration
+ * @param {Function} onReady A method to run after the widget has been initialized.
+ * @namespace easyXDM
+ */
+easyXDM.Widget = function(config){
+    var _widget = this;
+    var _incomingMessageHandler;
+    var _widgetHost = new easyXDM.Rpc({
+        swf: config.swf
+    }, {
+        remote: {
+            subscribe: {
+                isVoid: true
+            },
+            publish: {
+                isVoid: true
+            }
+        },
+        local: {
+            initialize: {
+                method: function(settings){
+                    config.initialized(_widget, _widgetHost);
+                    return {
+                        isInitialized: true,
+                        subscriptions: config.subscriptions
+                    };
+                }
+            },
+            send: {
+                isVoid: true,
+                method: function(url, topic, data){
+                    _incomingMessageHandler(url, topic, data);
+                }
+            }
+        }
+    });
+    
+    /**
+     * @private
+     * Destroy the interface on unload
+     */
+    window.onunload = function(){
+        _widgetHost.destroy();
+    };
+    
+    /**
+     * Publish data to subscribers to a topic
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _widgetHost.publish(topic, data);
+    };
+    
+    /**
+     * Subscribe to a topic
+     * @param {String} topic The topic to subscribe to
+     */
+    this.subscribe = function(topic){
+        _widgetHost.subscribe(topic);
+    };
+    
+    /**
+     * Register the method that will handle incoming messages
+     * @param {Function} fn The handler
+     */
+    this.registerMessageHandler = function(fn){
+        _incomingMessageHandler = fn;
+    };
+    
+    config.initialize(this, _widgetHost);
+};
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js
new file mode 100644
index 0000000..7dcf4bd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js
@@ -0,0 +1,333 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*jslint browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window */
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/**
+ * @class easyXDM.WidgetManager
+ * A class for managing widgets.<br/>
+ * Handles initializing widgets, and does all of the message distribution.
+ <pre><code>
+ _widgetManager = new easyXDM.WidgetManager({
+ local: "../hash.html",
+ container: document.getElementById("defaultcontainer")
+ },function(){
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{});
+ });
+ </code></pre>
+ * Widgets can by dynamically added using the addWidget method
+ <pre><code>
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{
+ container document.getElementById("widgetcontainer")
+ });
+ </code></pre>
+ * @constructor
+ * @param {Object} config The WidgetManagers configuration
+ * @namespace easyXDM
+ */
+easyXDM.WidgetManager = function(config){
+    var WidgetManager = this, _hashUrl = config.local, _channelNr = 0;
+    var Events = {
+        WidgetInitialized: "widgetinitialized",
+        WidgetFailed: "widgetfailed"
+    };
+    var _widgets = {}, _subscribers = {};
+    var _widgetSettings = {
+        hosturl: location.href
+    };
+    easyXDM.apply(_widgetSettings, config.widgetSettings);
+    var _container = config.container || document.body;
+    
+    /**
+     * @private
+     * Raises the specified event
+     * @param {String} event The raised event
+     * @param {Object} arg
+     */
+    function _raiseEvent(event, arg){
+        if (config.listeners && config.listeners[event]) {
+            config.listeners[event](WidgetManager, arg);
+        }
+    }
+    
+    /**
+     * @private
+     * Adds the widghet to the list of subscribers for the given topic
+     * @param {String} url The widgets url
+     * @param {String} topic The topic to subscribe to
+     */
+    function _subscribe(url, topic){
+        if (!(topic in _subscribers)) {
+            _subscribers[topic] = [];
+        }
+        _subscribers[topic].push(url);
+    }
+    
+    /**
+     * @private
+     * Initialized the widget.<br/>
+     * This is called after the widget has notified that it is ready.
+     * @param {Object} widget The widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _initializeWidget(widget, url, widgetConfig){
+        widget.initialize(_widgetSettings, function(response){
+            if (response.isInitialized) {
+                _widgets[url] = widget;
+                var i = response.subscriptions.length;
+                while (i--) {
+                    _subscribe(url, response.subscriptions[i]);
+                }
+                _raiseEvent(Events.WidgetInitialized, {
+                    url: url
+                });
+            }
+            else {
+                widget.destroy();
+                _raiseEvent(Events.WidgetFailed, {
+                    url: url
+                });
+            }
+        });
+    }
+    
+    /**
+     * @private
+     * Publishes the data to the topics subscribers
+     * @param {String} url The senders url
+     * @param {String} topic The datas topic
+     * @param {Object} data The data to publish
+     */
+    function _publish(url, topic, data){
+        var subscribers = _subscribers[topic];
+        if (subscribers) {
+            var i = subscribers.length, widgetUrl;
+            while (i--) {
+                widgetUrl = subscribers[i];
+                if (widgetUrl !== url) {
+                    _widgets[widgetUrl].send(url, topic, data);
+                }
+            }
+        }
+    }
+    
+    /**
+     * @private
+     * Sets up a new widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _setUpWidget(url, widgetConfig){
+        var widget = new easyXDM.Rpc({
+            channel: "widget" + _channelNr++,
+            local: _hashUrl,
+            remote: url,
+            container: widgetConfig.container || _container,
+            swf: config.swf,
+            onReady: function(){
+                _initializeWidget(widget, url, widgetConfig);
+            }
+        }, {
+            local: {
+                subscribe: {
+                    isVoid: true,
+                    method: function(topic){
+                        _subscribe(url, topic);
+                    }
+                },
+                publish: {
+                    isVoid: true,
+                    method: function(topic, data){
+                        _publish(url, topic, data);
+                    }
+                }
+            },
+            remote: {
+                initialize: {},
+                send: {
+                    isVoid: true
+                }
+            }
+        });
+    }
+    
+    /**
+     * Adds a widget to the collection
+     * @param {String} url The url to load the widget from
+     * @param {Object} widgetConfig The widgets url
+     */
+    this.addWidget = function(url, widgetConfig){
+        if (url in _widgets) {
+            throw new Error("A widget with this url has already been initialized");
+        }
+        _setUpWidget(url, widgetConfig);
+    };
+    
+    /**
+     * Removes the widget
+     * @param {Object} url
+     */
+    this.removeWidget = function(url){
+        if (url in _widgets) {
+            for (var topic in _subscribers) {
+                if (_subscribers.hasOwnProperty(topic)) {
+                    var subscribers = _subscribers[topic], i = subscribers.length;
+                    while (i--) {
+                        if (subscribers[i] === url) {
+                            subscribers.splice(i, 1);
+                            break;
+                        }
+                    }
+                }
+            }
+            _widgets[url].destroy();
+            delete _widgets[url];
+        }
+    };
+    
+    /**
+     * Publish data to a topics subscribers
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _publish("", topic, data);
+    };
+    
+    /**
+     * Broadcasts data to all the widgets
+     * @param {Object} data The data to broadcast
+     */
+    this.broadcast = function(data){
+        for (var url in _widgets) {
+            if (_widgets.hasOwnPropert(url)) {
+                _widgets[url].send({
+                    url: "",
+                    topic: "broadcast",
+                    data: data
+                });
+            }
+        }
+    };
+};
+
+/**
+ * @class easyXDM.Widget
+ * The base framework for creating widgets
+ * @constructor
+ * @param {Object} config The widgets configuration
+ * @param {Function} onReady A method to run after the widget has been initialized.
+ * @namespace easyXDM
+ */
+easyXDM.Widget = function(config){
+    var _widget = this;
+    var _incomingMessageHandler;
+    var _widgetHost = new easyXDM.Rpc({
+        swf: config.swf
+    }, {
+        remote: {
+            subscribe: {
+                isVoid: true
+            },
+            publish: {
+                isVoid: true
+            }
+        },
+        local: {
+            initialize: {
+                method: function(settings){
+                    config.initialized(_widget, _widgetHost);
+                    return {
+                        isInitialized: true,
+                        subscriptions: config.subscriptions
+                    };
+                }
+            },
+            send: {
+                isVoid: true,
+                method: function(url, topic, data){
+                    _incomingMessageHandler(url, topic, data);
+                }
+            }
+        }
+    });
+    
+    /**
+     * @private
+     * Destroy the interface on unload
+     */
+    window.onunload = function(){
+        _widgetHost.destroy();
+    };
+    
+    /**
+     * Publish data to subscribers to a topic
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _widgetHost.publish(topic, data);
+    };
+    
+    /**
+     * Subscribe to a topic
+     * @param {String} topic The topic to subscribe to
+     */
+    this.subscribe = function(topic){
+        _widgetHost.subscribe(topic);
+    };
+    
+    /**
+     * Register the method that will handle incoming messages
+     * @param {Function} fn The handler
+     */
+    this.registerMessageHandler = function(fn){
+        _incomingMessageHandler = fn;
+    };
+    
+    config.initialize(this, _widgetHost);
+};
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js
new file mode 100644
index 0000000..8ed55cd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js
@@ -0,0 +1,24 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+easyXDM.WidgetManager=function(e){var h=this,b=e.local,k=0;var n={WidgetInitialized:"widgetinitialized",WidgetFailed:"widgetfailed"};var j={},d={};var i={hosturl:location.href};easyXDM.apply(i,e.widgetSettings);var g=e.container||document.body;function f(p,o){if(e.listeners&&e.listeners[p]){e.listeners[p](h,o)}}function c(p,o){if(!(o in d)){d[o]=[]}d[o].push(p)}function m(p,o,q){p.initialize(i,function(r){if(r.isInitialized){j[o]=p;var s=r.subscriptions.length;while(s--){c(o,r.subscriptions[s])}f(n.WidgetInitialized,{url:o})}else{p.destroy();f(n.WidgetFailed,{url:o})}})}function a(p,o,r){var s=d[o];if(s){var q=s.length,t;while(q--){t=s[q];if(t!==p){j[t].send(p,o,r)}}}}function l(o,q){var p=new easyXDM.Rpc({channel:"widget"+k++,local:b,remote:o,container:q.container||g,swf:e.swf,onReady:function(){m(p,o,q)}},{local:{subscribe:{isVoid:true,method:function(r){c(o,r)}},publish:{isVoid:true,method:function(r,s){a(o,r,s)}}},remote:{initialize:{},send:{isVoid:true}}})}this.addWidget=function(o,p){if(o in j){throw new Error("A widget with this url has already been initialized")}l(o,p)};this.removeWidget=function(p){if(p in j){for(var o in d){if(d.hasOwnProperty(o)){var r=d[o],q=r.length;while(q--){if(r[q]===p){r.splice(q,1);break}}}}j[p].destroy();delete j[p]}};this.publish=function(o,p){a("",o,p)};this.broadcast=function(p){for(var o in j){if(j.hasOwnPropert(o)){j[o].send({url:"",topic:"broadcast",data:p})}}}};easyXDM.Widget=function(c){var a=this;var b;var d=new easyXDM.Rpc({swf:c.swf},{remote:{subscribe:{isVoid:true},publish:{isVoid:true}},local:{initialize:{method:function(e){c.initialized(a,d);return{isInitialized:true,subscriptions:c.subscriptions}}},send:{isVoid:true,method:function(f,e,g){b(f,e,g)}}}});window.onunload=function(){d.destroy()};this.publish=function(e,f){d.publish(e,f)};this.subscribe=function(e){d.subscribe(e)};this.registerMessageHandler=function(e){b=e};c.initialize(this,d)};
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js
new file mode 100644
index 0000000..61b9738
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js
@@ -0,0 +1,2871 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+var _trace = emptyFn;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        _trace("adding listener " + type);
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        _trace("removing listener " + type);
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        _trace("adding listener " + sEvent);
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        _trace("removing listener " + sEvent);
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    _trace("firing dom_onReady");
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            if (!obj) {
+                throw new Error(ii.slice(0, i + 1).join('.') + ' is not an object');
+            }
+            obj = obj[ii[i]];
+        }
+    }
+    if (!obj || !obj.easyXDM) {
+        throw new Error('Could not find easyXDM in parent.' + namespace);
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    if (typeof ns != "string" || !ns) {
+        throw new Error('namespace must be a non-empty string');
+    }
+    _trace("Settings namespace to '" + ns + "'");
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    if (/^file/.test(url)) {
+        throw new Error("The file:// protocol is not supported");
+    }
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    _trace("resolved url '" + url + "'");
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    if (!parameters) {
+        throw new Error("parameters is undefined or null");
+    }
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+    _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    _trace("creating frame: " + config.props.src);
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    _trace("preparing transport stack");
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        _trace("using parameters from query");
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+            _trace("selecting protocol: " + protocol);
+        }
+        else {
+            _trace("using protocol: " + protocol);
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    _trace("looking for image to use as local");
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        _trace("no image found, defaulting to using the window");
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+// Expose helper functions so we can test them
+apply(easyXDM, {
+    checkAcl: checkAcl,
+    getDomainName: getDomainName,
+    getLocation: getLocation,
+    appendQueryParameters: appendQueryParameters
+});
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var debug = {
+    _deferred: [],
+    flush: function(){
+        this.trace("... deferred messages ...");
+        for (var i = 0, len = this._deferred.length; i < len; i++) {
+            this.trace(this._deferred[i]);
+        }
+        this._deferred.length = 0;
+        this.trace("... end of deferred messages ...");
+    },
+    getTime: function(){
+        var d = new Date(), h = d.getHours() + "", m = d.getMinutes() + "", s = d.getSeconds() + "", ms = d.getMilliseconds() + "", zeros = "000";
+        if (h.length == 1) {
+            h = "0" + h;
+        }
+        if (m.length == 1) {
+            m = "0" + m;
+        }
+        if (s.length == 1) {
+            s = "0" + s;
+        }
+        ms = zeros.substring(ms.length) + ms;
+        return h + ":" + m + ":" + s + "." + ms;
+    },
+    /**
+     * Logs the message to console.log if available
+     * @param {String} msg The message to log
+     */
+    log: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!isHostObject(window, "console") || undef(console.log)) {
+            /**
+             * Sets log to be an empty function since we have no output available
+             * @ignore
+             */
+            this.log = emptyFn;
+        }
+        else {
+            /**
+             * Sets log to be a wrapper around console.log
+             * @ignore
+             * @param {String} msg
+             */
+            this.log = function(msg){
+                console.log(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ": " + msg);
+            };
+        }
+        this.log(msg);
+    },
+    /**
+     * Will try to trace the given message either to a DOMElement with the id "log",
+     * or by using console.info.
+     * @param {String} msg The message to trace
+     */
+    trace: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!domIsReady) {
+            if (this._deferred.length === 0) {
+                easyXDM.whenReady(debug.flush, debug);
+            }
+            this._deferred.push(msg);
+            this.log(msg);
+        }
+        else {
+            var el = document.getElementById("log");
+            // is there a log element present?
+            if (el) {
+                /**
+                 * Sets trace to be a function that outputs the messages to the DOMElement with id "log"
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    try {
+                        el.appendChild(document.createElement("div")).appendChild(document.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                        el.scrollTop = el.scrollHeight;
+                    } 
+                    catch (e) {
+                        //In case we are unloading
+                    }
+                };
+            }
+            else if (isHostObject(window, "console") && !undef(console.info)) {
+                /**
+                 * Sets trace to be a wrapper around console.info
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    console.info(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg);
+                };
+            }
+            else {
+                /**
+                 * Create log window
+                 * @ignore
+                 */
+                var domain = location.host, windowname = domain.replace(/[\-.:]/g, "") + "easyxdm_log", logWin;
+                try {
+                    logWin = window.open("", windowname, "width=800,height=200,status=0,navigation=0,scrollbars=1");
+                } 
+                catch (e) {
+                }
+                if (logWin) {
+                    var doc = logWin.document;
+                    el = doc.getElementById("log");
+                    if (!el) {
+                        doc.write("<html><head><title>easyXDM log " + domain + "</title></head>");
+                        doc.write("<body><div id=\"log\"></div></body></html>");
+                        doc.close();
+                        el = doc.getElementById("log");
+                    }
+                    this.trace = function(msg){
+                        try {
+                            el.appendChild(doc.createElement("div")).appendChild(doc.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                            el.scrollTop = el.scrollHeight;
+                        } 
+                        catch (e) {
+                            //In case we are unloading
+                        }
+                    };
+                    this.trace("---- new logger at " + location.href);
+                }
+                
+                if (!el) {
+                    // We are unable to use any logging
+                    this.trace = emptyFn;
+                }
+            }
+            this.trace(msg);
+        }
+    },
+    /**
+     * Creates a method usable for tracing.
+     * @param {String} name The name the messages should be marked with
+     * @return {Function} A function that accepts a single string as argument.
+     */
+    getTracer: function(name){
+        return function(msg){
+            debug.trace(name + ": " + msg);
+        };
+    }
+};
+debug.log("easyXDM present on '" + location.href);
+easyXDM.Debug = debug;
+_trace = debug.getTracer("{Private}");
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            debug.log("loading external JSON");
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+        else {
+            debug.log("native JSON found");
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            this._trace("storing function " + name);
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            this._trace("retrieving function " + name);
+            var fn = _map[name];
+            if (!fn) {
+                this._trace(name + " not found");
+            }
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+    easyXDM.Fn._trace = debug.getTracer("easyXDM.Fn");
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    var trace = debug.getTracer("easyXDM.Socket");
+    trace("constructor");
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    var trace = debug.getTracer("easyXDM.Rpc");
+    trace("constructor");
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.SameOriginTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FlashTransport");
+    trace("constructor");
+    if (!config.swf) {
+        throw new Error("Path to easyxdm.swf is missing");
+    }
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            trace("received message");
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        trace("creating factory with SWF from " + domain);
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        flashVars += "&log=true";
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    trace("firing onReady");
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.PostMessageTransport");
+    trace("constructor");
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        trace("received message '" + event.data + "' from " + origin);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        trace("firing onReady");
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FrameElementTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.NameTransport");
+    trace("constructor");
+    if (config.isHost && undef(config.remoteHelper)) {
+        trace("missing remoteHelper");
+        throw new Error("missing remoteHelper");
+    }
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        trace("sending message " + message);
+        trace("navigating to  '" + url + "'");
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            trace("calling onReady");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        trace("received message " + message);
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            trace("destroy");
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    trace("received initial message " + message);
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.HashTransport");
+    trace("constructor");
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        trace("sending message '" + (_msgNr + 1) + " " + message + "' to " + _remoteOrigin);
+        if (!_callerWindow) {
+            trace("no caller window");
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            trace("poll: new message");
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        trace("starting polling");
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            trace("unable to get reference to _listenerWindow, giving up");
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            trace("got a reference to _listenerWindow");
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.ReliableBehavior");
+    trace("constructor");
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            trace("incoming: " + message);
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                trace("message delivered");
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                trace("sending ack, and passing on " + message);
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.QueueBehavior");
+    trace("constructor");
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            trace("removing myself from the stack");
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        trace("dispatching from queue");
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    trace("received the last fragment");
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+                else {
+                    trace("waiting for more fragments, seq=" + message);
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    trace("enqueuing");
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.VerifyBehavior");
+    trace("constructor");
+    if (undef(config.initiate)) {
+        throw new Error("settings.initiate is not set");
+    }
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        trace("requesting verification");
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    trace("verified, calling callback");
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    trace("returning secret");
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var trace = debug.getTracer("easyXDM.stack.RpcBehavior");
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        trace("creating method " + method);
+        return function(){
+            trace("executing method " + method);
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            trace("requested to execute non-existent procedure " + method);
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        trace("requested to execute procedure " + method);
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                trace("received request to execute method " + data.method + (data.id ? (" using callback id " + data.id) : ""));
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                trace("received return value destined to callback with id " + data.id);
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                    else {
+                        trace("unhandled error returned.");
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            trace("init");
+            if (config.remote) {
+                trace("creating stubs");
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            trace("destroy");
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js
new file mode 100644
index 0000000..c0dabbd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js
@@ -0,0 +1,2576 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            obj = obj[ii[i]];
+        }
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            var fn = _map[name];
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        if (!_callerWindow) {
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        return function(){
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            if (config.remote) {
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js
new file mode 100644
index 0000000..8660795
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js
@@ -0,0 +1,24 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function(N,d,p,K,k,H){var b=this;var n=Math.floor(Math.random()*10000);var q=Function.prototype;var Q=/^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/;var R=/[\-\w]+\/\.\.\//;var F=/([^:])\/\//g;var I="";var o={};var M=N.easyXDM;var U="easyXDM_";var E;var y=false;var i;var h;function C(X,Z){var Y=typeof X[Z];return Y=="function"||(!!(Y=="object"&&X[Z]))||Y=="unknown"}function u(X,Y){return !!(typeof(X[Y])=="object"&&X[Y])}function r(X){return Object.prototype.toString.call(X)==="[object Array]"}function c(){var Z="Shockwave Flash",ad="application/x-shockwave-flash";if(!t(navigator.plugins)&&typeof navigator.plugins[Z]=="object"){var ab=navigator.plugins[Z].description;if(ab&&!t(navigator.mimeTypes)&&navigator.mimeTypes[ad]&&navigator.mimeTypes[ad].enabledPlugin){i=ab.match(/\d+/g)}}if(!i){var Y;try{Y=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");i=Array.prototype.slice.call(Y.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/),1);Y=null}catch(ac){}}if(!i){return false}var X=parseInt(i[0],10),aa=parseInt(i[1],10);h=X>9&&aa>0;return true}var v,x;if(C(N,"addEventListener")){v=function(Z,X,Y){Z.addEventListener(X,Y,false)};x=function(Z,X,Y){Z.removeEventListener(X,Y,false)}}else{if(C(N,"attachEvent")){v=function(X,Z,Y){X.attachEvent("on"+Z,Y)};x=function(X,Z,Y){X.detachEvent("on"+Z,Y)}}else{throw new Error("Browser not supported")}}var W=false,J=[],L;if("readyState" in d){L=d.readyState;W=L=="complete"||(~navigator.userAgent.indexOf("AppleWebKit/")&&(L=="loaded"||L=="interactive"))}else{W=!!d.body}function s(){if(W){return}W=true;for(var X=0;X<J.length;X++){J[X]()}J.length=0}if(!W){if(C(N,"addEventListener")){v(d,"DOMContentLoaded",s)}else{v(d,"readystatechange",function(){if(d.readyState=="complete"){s()}});if(d.documentElement.doScroll&&N===top){var g=function(){if(W){return}try{d.documentElement.doScroll("left")}catch(X){K(g,1);return}s()};g()}}v(N,"load",s)}function G(Y,X){if(W){Y.call(X);return}J.push(function(){Y.call(X)})}function m(){var Z=parent;if(I!==""){for(var X=0,Y=I.split(".");X<Y.length;X++){Z=Z[Y[X]]}}return Z.easyXDM}function e(X){N.easyXDM=M;I=X;if(I){U="easyXDM_"+I.replace(".","_")+"_"}return o}function z(X){return X.match(Q)[3]}function f(X){return X.match(Q)[4]||""}function j(Z){var X=Z.toLowerCase().match(Q);var aa=X[2],ab=X[3],Y=X[4]||"";if((aa=="http:"&&Y==":80")||(aa=="https:"&&Y==":443")){Y=""}return aa+"//"+ab+Y}function B(X){X=X.replace(F,"$1/");if(!X.match(/^(http||https):\/\//)){var Y=(X.substring(0,1)==="/")?"":p.pathname;if(Y.substring(Y.length-1)!=="/"){Y=Y.substring(0,Y.lastIndexOf("/")+1)}X=p.protocol+"//"+p.host+Y+X}while(R.test(X)){X=X.replace(R,"")}return X}function P(X,aa){var ac="",Z=X.indexOf("#");if(Z!==-1){ac=X.substring(Z);X=X.substring(0,Z)}var ab=[];for(var Y in aa){if(aa.hasOwnProperty(Y)){ab.push(Y+"="+H(aa[Y]))}}return X+(y?"#":(X.indexOf("?")==-1?"?":"&"))+ab.join("&")+ac}var S=(function(X){X=X.substring(1).split("&");var Z={},aa,Y=X.length;while(Y--){aa=X[Y].split("=");Z[aa[0]]=k(aa[1])}return Z}(/xdm_e=/.test(p.search)?p.search:p.hash));function t(X){return typeof X==="undefined"}var O=function(){var Y={};var Z={a:[1,2,3]},X='{"a":[1,2,3]}';if(typeof JSON!="undefined"&&typeof JSON.stringify==="function"&&JSON.stringify(Z).replace((/\s/g),"")===X){return JSON}if(Object.toJSON){if(Object.toJSON(Z).replace((/\s/g),"")===X){Y.stringify=Object.toJSON}}if(typeof String.prototype.evalJSON==="function"){Z=X.evalJSON();if(Z.a&&Z.a.length===3&&Z.a[2]===3){Y.parse=function(aa){return aa.evalJSON()}}}if(Y.stringify&&Y.parse){O=function(){return Y};return Y}return null};function T(X,Y,Z){var ab;for(var aa in Y){if(Y.hasOwnProperty(aa)){if(aa in X){ab=Y[aa];if(typeof ab==="object"){T(X[aa],ab,Z)}else{if(!Z){X[aa]=Y[aa]}}}else{X[aa]=Y[aa]}}}return X}function a(){var Y=d.body.appendChild(d.createElement("form")),X=Y.appendChild(d.createElement("input"));X.name=U+"TEST"+n;E=X!==Y.elements[X.name];d.body.removeChild(Y)}function A(Y){if(t(E)){a()}var ac;if(E){ac=d.createElement('<iframe name="'+Y.props.name+'"/>')}else{ac=d.createElement("IFRAME");ac.name=Y.props.name}ac.id=ac.name=Y.props.name;delete Y.props.name;if(typeof Y.container=="string"){Y.container=d.getElementById(Y.container)}if(!Y.container){T(ac.style,{position:"absolute",top:"-2000px",left:"0px"});Y.container=d.body}var ab=Y.props.src;Y.props.src="javascript:false";T(ac,Y.props);ac.border=ac.frameBorder=0;ac.allowTransparency=true;Y.container.appendChild(ac);if(Y.onLoad){v(ac,"load",Y.onLoad)}if(Y.usePost){var aa=Y.container.appendChild(d.createElement("form")),X;aa.target=ac.name;aa.action=ab;aa.method="POST";if(typeof(Y.usePost)==="object"){for(var Z in Y.usePost){if(Y.usePost.hasOwnProperty(Z)){if(E){X=d.createElement('<input name="'+Z+'"/>')}else{X=d.createElement("INPUT");X.name=Z}X.value=Y.usePost[Z];aa.appendChild(X)}}}aa.submit();aa.parentNode.removeChild(aa)}else{ac.src=ab}Y.props.src=ab;return ac}function V(aa,Z){if(typeof aa=="string"){aa=[aa]}var Y,X=aa.length;while(X--){Y=aa[X];Y=new RegExp(Y.substr(0,1)=="^"?Y:("^"+Y.replace(/(\*)/g,".$1").replace(/\?/g,".")+"$"));if(Y.test(Z)){return true}}return false}function l(Z){var ae=Z.protocol,Y;Z.isHost=Z.isHost||t(S.xdm_p);y=Z.hash||false;if(!Z.props){Z.props={}}if(!Z.isHost){Z.channel=S.xdm_c.replace(/["'<>\\]/g,"");Z.secret=S.xdm_s;Z.remote=S.xdm_e.replace(/["'<>\\]/g,"");ae=S.xdm_p;if(Z.acl&&!V(Z.acl,Z.remote)){throw new Error("Access denied for "+Z.remote)}}else{Z.remote=B(Z.remote);Z.channel=Z.channel||"default"+n++;Z.secret=Math.random().toString(16).substring(2);if(t(ae)){if(j(p.href)==j(Z.remote)){ae="4"}else{if(C(N,"postMessage")||C(d,"postMessage")){ae="1"}else{if(Z.swf&&C(N,"ActiveXObject")&&c()){ae="6"}else{if(navigator.product==="Gecko"&&"frameElement" in N&&navigator.userAgent.indexOf("WebKit")==-1){ae="5"}else{if(Z.remoteHelper){ae="2"}else{ae="0"}}}}}}}Z.protocol=ae;switch(ae){case"0":T(Z,{interval:100,delay:2000,useResize:true,useParent:false,usePolling:false},true);if(Z.isHost){if(!Z.local){var ac=p.protocol+"//"+p.host,X=d.body.getElementsByTagName("img"),ad;var aa=X.length;while(aa--){ad=X[aa];if(ad.src.substring(0,ac.length)===ac){Z.local=ad.src;break}}if(!Z.local){Z.local=N}}var ab={xdm_c:Z.channel,xdm_p:0};if(Z.local===N){Z.usePolling=true;Z.useParent=true;Z.local=p.protocol+"//"+p.host+p.pathname+p.search;ab.xdm_e=Z.local;ab.xdm_pa=1}else{ab.xdm_e=B(Z.local)}if(Z.container){Z.useResize=false;ab.xdm_po=1}Z.remote=P(Z.remote,ab)}else{T(Z,{channel:S.xdm_c,remote:S.xdm_e,useParent:!t(S.xdm_pa),usePolling:!t(S.xdm_po),useResize:Z.useParent?false:Z.useResize})}Y=[new o.stack.HashTransport(Z),new o.stack.ReliableBehavior({}),new o.stack.QueueBehavior({encode:true,maxLength:4000-Z.remote.length}),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"1":Y=[new o.stack.PostMessageTransport(Z)];break;case"2":Z.remoteHelper=B(Z.remoteHelper);Y=[new o.stack.NameTransport(Z),new o.stack.QueueBehavior(),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"3":Y=[new o.stack.NixTransport(Z)];break;case"4":Y=[new o.stack.SameOriginTransport(Z)];break;case"5":Y=[new o.stack.FrameElementTransport(Z)];break;case"6":if(!i){c()}Y=[new o.stack.FlashTransport(Z)];break}Y.push(new o.stack.QueueBehavior({lazy:Z.lazy,remove:true}));return Y}function D(aa){var ab,Z={incoming:function(ad,ac){this.up.incoming(ad,ac)},outgoing:function(ac,ad){this.down.outgoing(ac,ad)},callback:function(ac){this.up.callback(ac)},init:function(){this.down.init()},destroy:function(){this.down.destroy()}};for(var Y=0,X=aa.length;Y<X;Y++){ab=aa[Y];T(ab,Z,true);if(Y!==0){ab.down=aa[Y-1]}if(Y!==X-1){ab.up=aa[Y+1]}}return ab}function w(X){X.up.down=X.down;X.down.up=X.up;X.up=X.down=null}T(o,{version:"2.4.17.1",query:S,stack:{},apply:T,getJSONObject:O,whenReady:G,noConflict:e});o.DomHelper={on:v,un:x,requiresJSON:function(X){if(!u(N,"JSON")){d.write('<script type="text/javascript" src="'+X+'"><\/script>')}}};(function(){var X={};o.Fn={set:function(Y,Z){X[Y]=Z},get:function(Z,Y){var aa=X[Z];if(Y){delete X[Z]}return aa}}}());o.Socket=function(Y){var X=D(l(Y).concat([{incoming:function(ab,aa){Y.onMessage(ab,aa)},callback:function(aa){if(Y.onReady){Y.onReady(aa)}}}])),Z=j(Y.remote);this.origin=j(Y.remote);this.destroy=function(){X.destroy()};this.postMessage=function(aa){X.outgoing(aa,Z)};X.init()};o.Rpc=function(Z,Y){if(Y.local){for(var ab in Y.local){if(Y.local.hasOwnProperty(ab)){var aa=Y.local[ab];if(typeof aa==="function"){Y.local[ab]={method:aa}}}}}var X=D(l(Z).concat([new o.stack.RpcBehavior(this,Y),{callback:function(ac){if(Z.onReady){Z.onReady(ac)}}}]));this.origin=j(Z.remote);this.destroy=function(){X.destroy()};X.init()};o.stack.SameOriginTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa(ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:p.protocol+"//"+p.host+p.pathname,xdm_c:Y.channel,xdm_p:4}),name:U+Y.channel+"_provider"});ab=A(Y);o.Fn.set(Y.channel,function(ac){aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}})}else{aa=m().Fn.get(Y.channel,true)(function(ac){Z.up.incoming(ac,X)});K(function(){Z.up.callback(true)},0)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.FlashTransport=function(aa){var ac,X,ab,ad,Y,ae;function af(ah,ag){K(function(){ac.up.incoming(ah,ad)},0)}function Z(ah){var ag=aa.swf+"?host="+aa.isHost;var aj="easyXDM_swf_"+Math.floor(Math.random()*10000);o.Fn.set("flash_loaded"+ah.replace(/[\-.]/g,"_"),function(){o.stack.FlashTransport[ah].swf=Y=ae.firstChild;var ak=o.stack.FlashTransport[ah].queue;for(var al=0;al<ak.length;al++){ak[al]()}ak.length=0});if(aa.swfContainer){ae=(typeof aa.swfContainer=="string")?d.getElementById(aa.swfContainer):aa.swfContainer}else{ae=d.createElement("div");T(ae.style,h&&aa.swfNoThrottle?{height:"20px",width:"20px",position:"fixed",right:0,top:0}:{height:"1px",width:"1px",position:"absolute",overflow:"hidden",right:0,top:0});d.body.appendChild(ae)}var ai="callback=flash_loaded"+ah.replace(/[\-.]/g,"_")+"&proto="+b.location.protocol+"&domain="+z(b.location.href)+"&port="+f(b.location.href)+"&ns="+I;ae.innerHTML="<object height='20' width='20' type='application/x-shockwave-flash' id='"+aj+"' data='"+ag+"'><param name='allowScriptAccess' value='always'></param><param name='wmode' value='transparent'><param name='movie' value='"+ag+"'></param><param name='flashvars' value='"+ai+"'></param><embed type='application/x-shockwave-flash' FlashVars='"+ai+"' allowScriptAccess='always' wmode='transparent' src='"+ag+"' height='1' width='1'></embed></object>"}return(ac={outgoing:function(ah,ai,ag){Y.postMessage(aa.channel,ah.toString());if(ag){ag()}},destroy:function(){try{Y.destroyChannel(aa.channel)}catch(ag){}Y=null;if(X){X.parentNode.removeChild(X);X=null}},onDOMReady:function(){ad=aa.remote;o.Fn.set("flash_"+aa.channel+"_init",function(){K(function(){ac.up.callback(true)})});o.Fn.set("flash_"+aa.channel+"_onMessage",af);aa.swf=B(aa.swf);var ah=z(aa.swf);var ag=function(){o.stack.FlashTransport[ah].init=true;Y=o.stack.FlashTransport[ah].swf;Y.createChannel(aa.channel,aa.secret,j(aa.remote),aa.isHost);if(aa.isHost){if(h&&aa.swfNoThrottle){T(aa.props,{position:"fixed",right:0,top:0,height:"20px",width:"20px"})}T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:6,xdm_s:aa.secret}),name:U+aa.channel+"_provider"});X=A(aa)}};if(o.stack.FlashTransport[ah]&&o.stack.FlashTransport[ah].init){ag()}else{if(!o.stack.FlashTransport[ah]){o.stack.FlashTransport[ah]={queue:[ag]};Z(ah)}else{o.stack.FlashTransport[ah].queue.push(ag)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.PostMessageTransport=function(aa){var ac,ad,Y,Z;function X(ae){if(ae.origin){return j(ae.origin)}if(ae.uri){return j(ae.uri)}if(ae.domain){return p.protocol+"//"+ae.domain}throw"Unable to retrieve the origin of the event"}function ab(af){var ae=X(af);if(ae==Z&&af.data.substring(0,aa.channel.length+1)==aa.channel+" "){ac.up.incoming(af.data.substring(aa.channel.length+1),ae)}}return(ac={outgoing:function(af,ag,ae){Y.postMessage(aa.channel+" "+af,ag||Z);if(ae){ae()}},destroy:function(){x(N,"message",ab);if(ad){Y=null;ad.parentNode.removeChild(ad);ad=null}},onDOMReady:function(){Z=j(aa.remote);if(aa.isHost){var ae=function(af){if(af.data==aa.channel+"-ready"){Y=("postMessage" in ad.contentWindow)?ad.contentWindow:ad.contentWindow.document;x(N,"message",ae);v(N,"message",ab);K(function(){ac.up.callback(true)},0)}};v(N,"message",ae);T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:1}),name:U+aa.channel+"_provider"});ad=A(aa)}else{v(N,"message",ab);Y=("postMessage" in N.parent)?N.parent:N.parent.document;Y.postMessage(aa.channel+"-ready",Z);K(function(){ac.up.callback(true)},0)}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.FrameElementTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa.call(this,ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:j(p.href),xdm_c:Y.channel,xdm_p:5}),name:U+Y.channel+"_provider"});ab=A(Y);ab.fn=function(ac){delete ab.fn;aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}}}else{if(d.referrer&&j(d.referrer)!=S.xdm_e){N.top.location=S.xdm_e}aa=N.frameElement.fn(function(ac){Z.up.incoming(ac,X)});Z.up.callback(true)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.NameTransport=function(ab){var ac;var ae,ai,aa,ag,ah,Y,X;function af(al){var ak=ab.remoteHelper+(ae?"#_3":"#_2")+ab.channel;ai.contentWindow.sendMessage(al,ak)}function ad(){if(ae){if(++ag===2||!ae){ac.up.callback(true)}}else{af("ready");ac.up.callback(true)}}function aj(ak){ac.up.incoming(ak,Y)}function Z(){if(ah){K(function(){ah(true)},0)}}return(ac={outgoing:function(al,am,ak){ah=ak;af(al)},destroy:function(){ai.parentNode.removeChild(ai);ai=null;if(ae){aa.parentNode.removeChild(aa);aa=null}},onDOMReady:function(){ae=ab.isHost;ag=0;Y=j(ab.remote);ab.local=B(ab.local);if(ae){o.Fn.set(ab.channel,function(al){if(ae&&al==="ready"){o.Fn.set(ab.channel,aj);ad()}});X=P(ab.remote,{xdm_e:ab.local,xdm_c:ab.channel,xdm_p:2});T(ab.props,{src:X+"#"+ab.channel,name:U+ab.channel+"_provider"});aa=A(ab)}else{ab.remoteHelper=ab.remote;o.Fn.set(ab.channel,aj)}var ak=function(){var al=ai||this;x(al,"load",ak);o.Fn.set(ab.channel+"_load",Z);(function am(){if(typeof al.contentWindow.sendMessage=="function"){ad()}else{K(am,50)}}())};ai=A({props:{src:ab.local+"#_4"+ab.channel},onLoad:ak})},init:function(){G(ac.onDOMReady,ac)}})};o.stack.HashTransport=function(Z){var ac;var ah=this,af,aa,X,ad,am,ab,al;var ag,Y;function ak(ao){if(!al){return}var an=Z.remote+"#"+(am++)+"_"+ao;((af||!ag)?al.contentWindow:al).location=an}function ae(an){ad=an;ac.up.incoming(ad.substring(ad.indexOf("_")+1),Y)}function aj(){if(!ab){return}var an=ab.location.href,ap="",ao=an.indexOf("#");if(ao!=-1){ap=an.substring(ao)}if(ap&&ap!=ad){ae(ap)}}function ai(){aa=setInterval(aj,X)}return(ac={outgoing:function(an,ao){ak(an)},destroy:function(){N.clearInterval(aa);if(af||!ag){al.parentNode.removeChild(al)}al=null},onDOMReady:function(){af=Z.isHost;X=Z.interval;ad="#"+Z.channel;am=0;ag=Z.useParent;Y=j(Z.remote);if(af){T(Z.props,{src:Z.remote,name:U+Z.channel+"_provider"});if(ag){Z.onLoad=function(){ab=N;ai();ac.up.callback(true)}}else{var ap=0,an=Z.delay/50;(function ao(){if(++ap>an){throw new Error("Unable to reference listenerwindow")}try{ab=al.contentWindow.frames[U+Z.channel+"_consumer"]}catch(aq){}if(ab){ai();ac.up.callback(true)}else{K(ao,50)}}())}al=A(Z)}else{ab=N;ai();if(ag){al=parent;ac.up.callback(true)}else{T(Z,{props:{src:Z.remote+"#"+Z.channel+new Date(),name:U+Z.channel+"_consumer"},onLoad:function(){ac.up.callback(true)}});al=A(Z)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.ReliableBehavior=function(Y){var aa,ac;var ab=0,X=0,Z="";return(aa={incoming:function(af,ad){var ae=af.indexOf("_"),ag=af.substring(0,ae).split(",");af=af.substring(ae+1);if(ag[0]==ab){Z="";if(ac){ac(true);ac=null}}if(af.length>0){aa.down.outgoing(ag[1]+","+ab+"_"+Z,ad);if(X!=ag[1]){X=ag[1];aa.up.incoming(af,ad)}}},outgoing:function(af,ad,ae){Z=af;ac=ae;aa.down.outgoing(X+","+(++ab)+"_"+af,ad)}})};o.stack.QueueBehavior=function(Z){var ac,ad=[],ag=true,aa="",af,X=0,Y=false,ab=false;function ae(){if(Z.remove&&ad.length===0){w(ac);return}if(ag||ad.length===0||af){return}ag=true;var ah=ad.shift();ac.down.outgoing(ah.data,ah.origin,function(ai){ag=false;if(ah.callback){K(function(){ah.callback(ai)},0)}ae()})}return(ac={init:function(){if(t(Z)){Z={}}if(Z.maxLength){X=Z.maxLength;ab=true}if(Z.lazy){Y=true}else{ac.down.init()}},callback:function(ai){ag=false;var ah=ac.up;ae();ah.callback(ai)},incoming:function(ak,ai){if(ab){var aj=ak.indexOf("_"),ah=parseInt(ak.substring(0,aj),10);aa+=ak.substring(aj+1);if(ah===0){if(Z.encode){aa=k(aa)}ac.up.incoming(aa,ai);aa=""}}else{ac.up.incoming(ak,ai)}},outgoing:function(al,ai,ak){if(Z.encode){al=H(al)}var ah=[],aj;if(ab){while(al.length!==0){aj=al.substring(0,X);al=al.substring(aj.length);ah.push(aj)}while((aj=ah.shift())){ad.push({data:ah.length+"_"+aj,origin:ai,callback:ah.length===0?ak:null})}}else{ad.push({data:al,origin:ai,callback:ak})}if(Y){ac.down.init()}else{ae()}},destroy:function(){af=true;ac.down.destroy()}})};o.stack.VerifyBehavior=function(ab){var ac,aa,Y,Z=false;function X(){aa=Math.random().toString(16).substring(2);ac.down.outgoing(aa)}return(ac={incoming:function(af,ad){var ae=af.indexOf("_");if(ae===-1){if(af===aa){ac.up.callback(true)}else{if(!Y){Y=af;if(!ab.initiate){X()}ac.down.outgoing(af)}}}else{if(af.substring(0,ae)===Y){ac.up.incoming(af.substring(ae+1),ad)}}},outgoing:function(af,ad,ae){ac.down.outgoing(aa+"_"+af,ad,ae)},callback:function(ad){if(ab.initiate){X()}}})};o.stack.RpcBehavior=function(ad,Y){var aa,af=Y.serializer||O();var ae=0,ac={};function X(ag){ag.jsonrpc="2.0";aa.down.outgoing(af.stringify(ag))}function ab(ag,ai){var ah=Array.prototype.slice;return function(){var aj=arguments.length,al,ak={method:ai};if(aj>0&&typeof arguments[aj-1]==="function"){if(aj>1&&typeof arguments[aj-2]==="function"){al={success:arguments[aj-2],error:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-2)}else{al={success:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-1)}ac[""+(++ae)]=al;ak.id=ae}else{ak.params=ah.call(arguments,0)}if(ag.namedParams&&ak.params.length===1){ak.params=ak.params[0]}X(ak)}}function Z(an,am,ai,al){if(!ai){if(am){X({id:am,error:{code:-32601,message:"Procedure not found."}})}return}var ak,ah;if(am){ak=function(ao){ak=q;X({id:am,result:ao})};ah=function(ao,ap){ah=q;var aq={id:am,error:{code:-32099,message:ao}};if(ap){aq.error.data=ap}X(aq)}}else{ak=ah=q}if(!r(al)){al=[al]}try{var ag=ai.method.apply(ai.scope,al.concat([ak,ah]));if(!t(ag)){ak(ag)}}catch(aj){ah(aj.message)}}return(aa={incoming:function(ah,ag){var ai=af.parse(ah);if(ai.method){if(Y.handle){Y.handle(ai,X)}else{Z(ai.method,ai.id,Y.local[ai.method],ai.params)}}else{var aj=ac[ai.id];if(ai.error){if(aj.error){aj.error(ai.error)}}else{if(aj.success){aj.success(ai.result)}}delete ac[ai.id]}},init:function(){if(Y.remote){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)){ad[ag]=ab(Y.remote[ag],ag)}}}aa.down.init()},destroy:function(){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)&&ad.hasOwnProperty(ag)){delete ad[ag]}}aa.down.destroy()}})};b.easyXDM=o})(window,document,location,window.setTimeout,decodeURIComponent,encodeURIComponent);
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf b/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf
new file mode 100644
index 0000000..0a82005
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/blank.html b/asterix-examples/src/main/resources/js/easyXDM/example/blank.html
new file mode 100644
index 0000000..33b64d6
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/blank.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+    <head>
+        <title>Blank page</title>
+		</head>
+		<body>
+        This page will be replaced with the actuall content in just a jiffy.. 
+		</body>
+</html>		
+		
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html
new file mode 100644
index 0000000..2da7a2c
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+        <title></title>
+    </head>
+    <body>
+        <img src="../tests/s.gif" />
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+                document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+            }
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+        <a id="bookmark" src="">Bookmark</a>
+        <script type="text/javascript">
+            var baseUrl = location.href.substring(0, location.href.lastIndexOf("/"));
+            
+            // to simplify development, we create the bookmarklet as a regular function
+            function bookmark(){
+                if (typeof myBookmark === "undefined") {
+                    var script = document.createElement("script");
+                    script.type = "text/javascript";
+                    script.src = baseUrl + "/bookmark.js";
+                    document.getElementsByTagName("head")[0].appendChild(script);
+                }
+                else {
+                    myBookmark.run();
+                }
+            }
+            
+            // and then we include it using .toString().
+            document.getElementById("bookmark").href = 'javascript:(' +
+            (bookmark.toString().replace('baseUrl + "', '"' + baseUrl)).replace(/\s+/g, " ") +
+            ')();';
+            // when finished, you just copy the url from the rendered page
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js
new file mode 100644
index 0000000..7f0d0ff
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js
@@ -0,0 +1,74 @@
+var myBookmark = (function(){
+    var s1, s2, isLoaded = false, xhr, head = document.getElementsByTagName('head')[0];
+    var scripts = document.getElementsByTagName("script");
+    var REMOTE = (function(){
+        var remote = location.href;
+        switch (location.host) {
+            case "provider.easyxdm.net":
+                location.href = remote.replace("provider", "consumer");
+                break;
+            case "xdm1":
+                remote = remote.replace("xdm1", "xdm2");
+                break;
+            default:
+                remote = "http://provider.easyxdm.net/current/example/";
+        }
+        return remote.substring(0, remote.lastIndexOf("/"));
+    }());
+    
+    function run(){
+        if (typeof xhr === "undefined") {
+            return;
+        }
+        xhr.post("example/glossary.php", {
+            param1: "a",
+            param2: "b"
+        }, function(json){
+            alert(json.glossary.title);
+        });
+    }
+    
+    function scriptOnLoad(){
+        if (isLoaded || typeof easyXDM === "undefined" || typeof JSON === "undefined") {
+            return;
+        }
+        isLoaded = true;
+        xhr = new easyXDM.Rpc({
+            remote: REMOTE + "/../xhr.html",
+            onReady: function(){
+                run();
+            }
+        }, {
+            remote: {
+                post: {}
+            }
+        });
+        
+    }
+    s1 = document.createElement("script");
+    s1.type = "text/javascript";
+    s1.src = REMOTE + "/../easyXDM.debug.js";
+    s1.onreadystatechange = function(){
+        if (this.readyState === "complete" || this.readyState === "loaded") {
+            scriptOnLoad();
+        }
+    };
+    s1.onload = scriptOnLoad;
+    head.appendChild(s1);
+    
+    if (typeof JSON === "undefined" || !JSON) {
+        s2 = document.createElement("script");
+        s2.type = "text/javascript";
+        s2.src = REMOTE + "/../json2.js";
+        s2.onreadystatechange = function(){
+            if (this.readyState === "complete" || this.readyState === "loaded") {
+                scriptOnLoad();
+            }
+        };
+        s2.onload = scriptOnLoad;
+        head.appendChild(s2);
+    }
+    return {
+        run: run
+    };
+})();
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html b/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html
new file mode 100644
index 0000000..af840e8
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            /* Here we demo how to have two visible web applications communicate together.
+             * This is done by having the remote interface open a visible window and loading
+             * the application in this.
+             * Since the remote interface has access to the entire DOM (including javascript)
+             * of the opened window, the remote interface is able to interface freely with the
+             * remote web application and can serve as a bridge between the two applications.
+             */
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            
+            
+            
+            var proxy, win;
+            function openPopup(){
+                if (win) {
+                    // this allows to open new windows if the popup was closed
+                    if (win.closed) {
+                        win = window.open(REMOTE + '/blank.html', 'mainapp', "width=400, height=400");
+                        proxy.open("mainapp");
+                    }
+                    return;
+                }
+                // open up the popup 
+                win = window.open(REMOTE + '/blank.html', 'mainapp', "width=400, height=400");
+                
+                document.getElementById("btn").disabled = "";
+                
+                proxy = new easyXDM.Rpc(/** The configuration */{
+                    /**
+                     * Register the url to name.html, this must be an absolute path
+                     * or a path relative to the root.
+                     * @field
+                     */
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    /**
+                     * Register the url to the remote interface
+                     * @field
+                     */
+                    remote: REMOTE + "/remote.html",
+                    remoteHelper: REMOTE + "/../name.html"
+                }, {
+                    remote: {
+                        open: {},
+                        postMessage: {}
+                    },
+                    local: {
+                        /**
+                         * Register the method that should handle incoming data
+                         * @param {Object} data
+                         * @param {String} origin
+                         */
+                        postMessage: function(data){
+                            var div = document.createElement("div");
+                            div.innerHTML = "data from '" + proxy.origin + "'";
+                            document.body.appendChild(div);
+                            for (var key in data) {
+                                if (data.hasOwnProperty(key)) {
+                                    div = document.createElement("div");
+                                    div.innerHTML = key + "=" + data[key];
+                                    document.body.appendChild(div);
+                                }
+                            }
+                        }
+                    }
+                });
+                
+                // lets tell the proxy to open up the window as soon as possible
+                proxy.open("mainapp");
+            }
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <input id="btnOpen" type="button" onclick="openPopup();" value="Open popup"/><!-- Send som data to the other side --><input id="btn" disabled="disabled" type="button" onclick="proxy.postMessage({a:'b',c:'d',e:'f'});" value="send data to remote"/>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/data.html b/asterix-examples/src/main/resources/js/easyXDM/example/data.html
new file mode 100644
index 0000000..47eaeed
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/data.html
@@ -0,0 +1,133 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var serializer = {
+                /**
+                 * Serializes a hashtable and returns it as a string
+                 * @param {Object} data The data to serialize
+                 * @returns The serialized string
+                 * @type {String}
+                 */
+                stringify: function(data){
+                    var message = "";
+                    for (var key in data) {
+                        if (data.hasOwnProperty(key)) {
+                            message += key + "=" + escape(data[key]) + "&";
+                        }
+                    }
+                    return message.substring(0, message.length - 1);
+                },
+                /**
+                 * Deserializes a string and returns a hashtable
+                 * @param {String} message The string to deserialize
+                 * @returns An hashtable populated with key-value pairs
+                 * @type {Object}
+                 */
+                parse: function(message){
+                    var data = {};
+                    var d = message.split("&");
+                    var pair, key, value;
+                    for (var i = 0, len = d.length; i < len; i++) {
+                        pair = d[i];
+                        key = pair.substring(0, pair.indexOf("="));
+                        value = pair.substring(key.length + 1);
+                        data[key] = unescape(value);
+                    }
+                    return data;
+                }
+            };
+            
+            var channel;
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            window.onload = function(){
+                /**
+                 * When the window is finished loading start setting up the channel
+                 */
+                channel = new easyXDM.Socket(/** The configuration */{
+                    /**
+                     * Register the url to hash.html, this must be an absolute path
+                     * or a path relative to the root.
+                     * @field
+                     */
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    /**
+                     * Register the url to the remote interface
+                     * @field
+                     */
+                    remote: REMOTE + "/remotedata.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    onReady: function(){
+                        /**
+                         * Send some data to the other side
+                         */
+                        channel.postMessage(serializer.stringify({
+                            propA: "abc",
+                            propB: "def",
+                            propC: 44
+                        }));
+                    }
+                });
+            };
+        </script>
+    </head>
+    <body>
+    <div style="border:1px solid black;padding:3px;margin:10px;">
+        <a href="index.html">Index of examples</a>
+        | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+        | 
+        | <a href="http://easyxdm.net/">easyXDM.net</a>
+        | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+        <br/>
+        The examples are executing slower than the production build due to the extensive tracing.
+        <br/>
+        If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+    </div>
+    <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+    <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+    </div>
+    </div>
+    <br/>
+    <br/>
+    <input type="text" id="code" size="100" value="channel.postMessage(serializer.stringify({propC:'c',procD:'d',propE:88}))"/>
+    <button onclick="eval(document.getElementById('code').value);">
+        eval code
+    </button>
+    <script type="text/javascript">
+        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script>
+    <script type="text/javascript">
+        if (location.host.indexOf("easyxdm.net") !== -1) {
+            try {
+                var pageTracker = _gat._getTracker("UA-9535591-3");
+                pageTracker._setDomainName(".easyxdm.net");
+                pageTracker._trackPageview();
+            } 
+            catch (err) {
+            }
+        }
+    </script>
+</body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx b/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx
new file mode 100644
index 0000000..c815101
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx
@@ -0,0 +1,29 @@
+﻿<%
+    Response.ContentType = "application/json"
+    Response.AddHeader("x-foo", "bar")
+    Response.AddHeader("Access-Control-Allow-Origin", "http://xdm4")
+    Response.AddHeader("Access-Control-Allow-Methods", "POST")
+
+%>
+{
+    "glossary": {
+        "title": "example glossary",
+        "GlossDiv": {
+            "title": "S",
+            "GlossList": {
+                "GlossEntry": {
+                    "ID": "SGML",
+                    "SortAs": "SGML",
+                    "GlossTerm": "Standard Generalized Markup Language",
+                    "Acronym": "SGML",
+                    "Abbrev": "ISO 8879:1986",
+                    "GlossDef": {
+                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
+                        "GlossSeeAlso": ["GML", "XML"]
+                    },
+                    "GlossSee": "markup"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/index.html b/asterix-examples/src/main/resources/js/easyXDM/example/index.html
new file mode 100644
index 0000000..3690577
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/index.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <ul>
+        	<li>
+                <a href="transport.html">Transport</a>
+                <br/>
+                Example of passing a string message from one domain to another using the Socket.
+            </li>
+            <li>
+                <a href="data.html">Data</a>
+                <br/>
+                Example of passing data using a Socket and a custom serializer/deserializer.
+            </li>
+            <li>
+                <a href="methods.html">Methods</a>
+                <br/>
+                Example of using the Rpc object for executing Remote Procedure Calls with arguments and having results returned.
+            </li>
+            <li>
+                <a href="resize_iframe.html">Resize iframe</a>
+                <br/>
+                Example on how to use easyXDM to automatically resize an iframe. This uses an intermediate frame to enable navigation of the contained document
+            </li>
+            <li>
+                <a href="upload.html">Upload</a>
+                <br/>
+                Example on how to facilitate 'cross domain AJAX upload'. 
+            </li>
+            <li>
+                <a href="widgets.html">Widgets</a>
+                <br/>
+                Example on how to use easyXDM to build a framework for widgets using a pub/sub schema.
+            </li>
+            <li>
+                <a href="xhr.html">XHR</a>
+                <br/>
+                Example of using the shipped /cors/ endpoint to retrieve resources across the domain boundary.
+            </li>
+            <li>
+                <a href="bridge.html">Bridge</a>
+                <br/>
+                Experimental example of how to 'bridge' two web apps together. 
+            </li>
+        </ul>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/methods.html b/asterix-examples/src/main/resources/js/easyXDM/example/methods.html
new file mode 100644
index 0000000..9bbd15a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/methods.html
@@ -0,0 +1,148 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            var remote = new easyXDM.Rpc(/** The channel configuration */{
+                /**
+                 * Register the url to hash.html, this must be an absolute path
+                 * or a path relative to the root.
+                 * @field
+                 */
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                /**
+                 * Register the url to the remote interface
+                 * @field
+                 */
+                remote: REMOTE + "/remotemethods.html",
+                remoteHelper: REMOTE + "/../name.html",
+                /**
+                 * Register the DOMElement that the generated IFrame should be inserted into
+                 */
+                container: "embedded",
+                props: {
+                    style: {
+                        border: "2px dotted red",
+                        height: "200px"
+                    }
+                },
+                onReady: function(){
+                    /**
+                     * Call a method on the other side
+                     */
+                    remote.noOp();
+                }
+            }, /** The interface configuration */ {
+                remote: {
+                    addNumbers: {},
+                    multiplyNumbers: {},
+                    noOp: {}
+                },
+                local: {
+                    alertMessage: function(msg){
+                        alert(msg);
+                    }
+                }
+            });
+            
+            function add(a, b){
+                remote.addNumbers(a, b, function(result){
+                    alert(a + " + " + b + " = " + result);
+                });
+            }
+            
+            function multiply(a, b){
+                remote.multiplyNumbers(a, b, function(result){
+                    alert(a + " x " + b + " = " + result);
+                });
+            }
+        </script>
+        <style type="text/css">
+            
+            #embedded iframe {
+                width: 100%;
+                height: 100%;
+            }
+        </style>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <div>
+            The remote implementation is synchronous and will return immediately
+            <br/>
+            <input type="button" onclick="add(3,5);" value="call addNumbers on remote domain"/>
+            <br/>
+            <br/>
+            The remote implementation of multiplyNumbers is asynchronous and will return after 5seconds
+            <br/>
+            This shows that you can use async calls in the remote method, eg. XHR calls
+            <br/>
+            <input type="button" onclick="multiply(3,5);" value="call multiplyNumbers on remote domain"/>
+            <br/>
+            <br/>
+            This calls a non-returning method on the remote side
+            <br/>
+            <input type="button" onclick="remote.noOp();" value="call noOp on the remote domain"/>
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remote.html b/asterix-examples/src/main/resources/js/easyXDM/example/remote.html
new file mode 100644
index 0000000..ad82e8a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remote.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var win, remoteapp; // reference to the popups window
+            var proxy = new easyXDM.Rpc(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, {
+                local: {
+                    /**
+                     * This is used to open up the popup. A popup with the given name should already be opened
+                     * in the user click handler.
+                     */
+                    open: function(name){
+                        remoteapp = null;
+                        // we now open the window, passing the name of this window (includes the channel name)
+                        // in case it has to look us up using the framename
+                        win = window.open('remoteapp.html' + '#easyXDM_' + easyXDM.query.xdm_c + '_provider', name, "width=400, height=400");
+                    },
+                    /**
+                     * This is where we receive the data
+                     * @param {Object} data The data
+                     */
+                    postMessage: function(data){
+                        if (win.closed) {
+                            alert("the popup has been closed - please open it again");
+                            return;
+                        }
+                        var div = remoteapp.document.createElement("div");
+                        div.innerHTML = "data from '" + proxy.origin + "'";
+                        if (remoteapp) {
+                            remoteapp.document.body.appendChild(div);
+                            for (var key in data) {
+                                if (data.hasOwnProperty(key)) {
+                                    div = remoteapp.document.createElement("div");
+                                    div.innerHTML = key + "=" + data[key];
+                                    remoteapp.document.body.appendChild(div);
+                                }
+                            }
+                            remoteapp.focus();
+                        }
+                    }
+                },
+                remote: {
+                    postMessage: {}
+                }
+            });
+            
+            
+            /**
+             * The popup must use this window to register itself
+             * @param {DOMWindow} app The window object of the popup
+             */
+            function setApp(app){
+                remoteapp = app;
+            }
+            
+            /**
+             * The popup must use this method to send data. This clones the object in order to
+             * work around a but in IE
+             * @param {Object} data The data to send
+             */
+            function sendData(data){
+                var copy = {};
+                // copy the object in order to avoid the JSON serialization bug
+                easyXDM.apply(copy, data);
+                proxy.postMessage(copy);
+            }
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html b/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html
new file mode 100644
index 0000000..e493b68
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript">
+            var target = location.hash.substring(1);
+            
+            var host = window.opener.frames[target];
+            
+            if (window.opener) {
+                try {
+                    // test if we have access to the document 
+                    if (window.opener.document.title) {
+                        host = window.opener;
+                    }
+                    
+                } 
+                catch (xDomainError) {
+                    // we have an opener, but it's not on our domain, 
+                    host = window.opener.frames[target];
+                }
+                
+                if (host) {
+                    try {
+                        host.setApp(window);
+                    } 
+                    catch (browserHostError) {
+                        alert("was unable to gain a reference to the iframe");
+                    }
+                }
+            }
+        </script>
+    </head>
+    <body>
+        <!-- Send some data to the other side using the proxy --><input type="button" onclick="host.sendData({a:'b',c:'d',e:'f'});" value="send data to local"/>
+    </body>
+</html>
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html
new file mode 100644
index 0000000..814355c
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var serializer = {
+                /**
+                 * Serializes a hashtable and returns it as a string
+                 * @param {Object} data The data to serialize
+                 * @returns The serialized string
+                 * @type {String}
+                 */
+                stringify: function(data){
+                    var message = "";
+                    for (var key in data) {
+                        if (data.hasOwnProperty(key)) {
+                            message += key + "=" + escape(data[key]) + "&";
+                        }
+                    }
+                    return message.substring(0, message.length - 1);
+                },
+                /**
+                 * Deserializes a string and returns a hashtable
+                 * @param {String} message The string to deserialize
+                 * @returns An hashtable populated with key-value pairs
+                 * @type {Object}
+                 */
+                parse: function(message){
+                    var data = {};
+                    var d = message.split("&");
+                    var pair, key, value;
+                    for (var i = 0, len = d.length; i < len; i++) {
+                        pair = d[i];
+                        key = pair.substring(0, pair.indexOf("="));
+                        value = pair.substring(key.length + 1);
+                        data[key] = unescape(value);
+                    }
+                    return data;
+                }
+            };
+            
+            var socket = new easyXDM.Socket(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf",
+                /**
+                 * Register the method that should handle incoming data
+                 * @param {Object} data
+                 * @param {String} origin
+                 */
+                onMessage: function(data, origin){
+                    data = serializer.parse(data);
+                    alert("Received data from '" + origin + "':");
+                    for (var key in data) {
+                        alert("Property '" + key + "'=" + data[key]);
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html
new file mode 100644
index 0000000..2ea8c1f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc(/** The channel configuration*/{
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, /** The configuration */ {
+                remote: {
+                    alertMessage: {}
+                },
+                local: {
+                    addNumbers: function(a, b){
+                        return a + b;
+                    },
+                    multiplyNumbers: function(a, b, fn){
+                        window.setTimeout(function(){
+                            fn(a * b);
+                        }, 5000);
+                    },
+                    noOp: function(){
+                        alert("Method not returning any data");
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <input type="button" onclick="remote.alertMessage('message from remote');" value="call alertMessage on local domain"/>
+    </body>
+</html>
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html b/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html
new file mode 100644
index 0000000..59a411a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc(/** The channel configuration*/{
+                local: "../name.html"
+            }, /** The configuration */ {
+                /**
+                 *
+                 * @param {Object} rpc A JSON-RPC 2.0 request object
+                 * @param {Function} reply The callback method. Takes a single JSON-RPC 2.0 response object.
+                 */
+                handle: function(rpc, reply){
+                    alert("requested to execute procedure '" + rpc.method + "'");
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html
new file mode 100644
index 0000000..64093a7
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var transport = new easyXDM.Socket(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf",
+                /**
+                 * Register the method that should handle incoming messages
+                 * @param {String} data
+                 * @param {String} origin
+                 */
+                onMessage: function(message, origin){
+                    alert("Received '" + message + "' from '" + origin + "'");
+                }
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html b/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html
new file mode 100644
index 0000000..e0b0adb
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            var transport = new easyXDM.Socket(/** The configuration */{
+                remote: REMOTE + "/resize_intermediate.html?url=resized_iframe_1.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                container: "embedded",
+                onMessage: function(message, origin){
+                    this.container.getElementsByTagName("iframe")[0].style.height = message + "px";
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html b/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html
new file mode 100644
index 0000000..8b5f03e
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js"></script>
+        <script type="text/javascript">
+            var iframe;
+            var socket = new easyXDM.Socket({
+                swf : "../easyxdm.swf",
+                onReady : function() {
+                    iframe = document.createElement("iframe");
+                    iframe.frameBorder = 0;
+                    document.body.appendChild(iframe);
+                    iframe.src = easyXDM.query.url;
+
+                    var timer;
+                    iframe.onload = function() {
+                        var d = iframe.contentWindow.document;
+                        var originalHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;
+
+                        // We want to monitor the document for resize events in case of the use of accordions and such,
+                        // but unfortunately only the window node emits the resize event, and we need the body's.
+                        // The only solution then is to use polling..
+
+                        // Lets start the polling if not all ready started
+                        if(!timer) {
+                            timer = setInterval(function() {
+                                try {
+                                    var d = iframe.contentWindow.document;
+                                    var newHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;
+                                    if(newHeight != originalHeight) {
+                                        // The height has changed since last we checked
+                                        originalHeight = newHeight;
+                                        socket.postMessage(originalHeight);
+                                    }
+                                } catch(e) {
+                                    // We tried to read the property at some point when it wasn't available
+                                }
+                            }, 300);
+                        }
+                        // Send the first message
+                        socket.postMessage(originalHeight);
+                    };
+                },
+                onMessage : function(url, origin) {
+                    iframe.src = url;
+                }
+            });
+
+        </script>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                width: 100%;
+                height: 100%;
+            }
+            iframe {
+                width: 100%;
+                height: 100%;
+                border: 0px;
+            }
+        </style>
+    </head>
+    <body></body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html
new file mode 100644
index 0000000..8b4b7ad
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                background-color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <a href="resized_iframe_2.html">resized_iframe_2.html</a>
+        <br/>
+        Nam nulla nibh, tempus ut dictum eget, euismod vitae metus. Donec vitae nulla nec quam sagittis gravida vel quis eros. Nullam vel est justo. Donec euismod interdum magna, et rutrum libero tincidunt vel. Praesent imperdiet, magna et suscipit facilisis, nulla justo consequat nisl, et mollis elit nunc a est. Sed felis quam, condimentum eget gravida non, semper non quam. Duis vestibulum sem id erat tristique eleifend. Phasellus ante nunc, pulvinar nec facilisis at, hendrerit sed leo. Morbi lacinia nisl id nunc faucibus lacinia. Curabitur adipiscing leo a odio aliquet hendrerit. Nullam laoreet pulvinar suscipit.
+        Cras ante tortor, rutrum non pharetra vel, tempor et velit. Mauris semper, libero sit amet interdum interdum, metus purus rutrum libero, eget suscipit lectus augue eu magna. Aliquam quis dui a nunc luctus faucibus. Sed viverra augue rutrum odio placerat laoreet. Nulla scelerisque augue nec enim condimentum sollicitudin. Proin accumsan, turpis in viverra lobortis, nulla mauris euismod turpis, sit amet auctor felis lacus sed leo. Nullam posuere bibendum urna, ut mattis eros varius ac. Mauris sed metus orci, ut lobortis eros. Sed imperdiet bibendum tincidunt. Donec adipiscing sapien vitae ligula faucibus quis auctor nisi pretium. Morbi at nulla quam, in aliquet quam. Suspendisse potenti. Fusce varius gravida egestas. Nulla lectus velit, posuere et auctor a, congue id massa. Quisque ut lectus eu metus malesuada sollicitudin ac a risus.
+        Nullam massa ipsum, pulvinar ut facilisis a, commodo ut orci. Mauris ac ipsum diam, sit amet laoreet tortor. In pretium, nulla vel ornare euismod, nibh augue pharetra magna, at semper felis diam in ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus blandit ornare dignissim. Fusce et nulla urna. Morbi nec ante erat. Nullam ut urna libero. Nulla non ipsum purus, et cursus lectus. Etiam vehicula, mauris in faucibus vehicula, dolor quam sodales neque, sed laoreet est augue at lacus. Nunc tincidunt lacinia elit eu dignissim. Mauris at enim mauris. Donec congue auctor dui, eget posuere ante accumsan in. Nulla non quam enim, eget tempor arcu. Suspendisse nec nibh diam, ut congue est. Fusce at urna eget velit posuere ornare nec eget mauris. Sed accumsan magna et enim mollis dignissim.
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html
new file mode 100644
index 0000000..7c4085d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                background-color: red;
+            }
+        </style>
+    </head>
+    <body>
+        <a href="resized_iframe_1.html">resized_iframe_1.html</a>
+        <br/>
+        (This page will resize its content after three seconds)
+        <br/>
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eu felis libero, non ultricies ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in lorem libero. Phasellus malesuada, mauris eget suscipit tristique, dolor dui blandit purus, ut mollis eros dolor et elit. Ut consequat ultrices metus, pretium mattis dui adipiscing vitae. Nunc cursus, sapien vehicula auctor faucibus, enim orci pretium risus, id congue ligula justo sed felis. Proin nec quam justo. Cras tempor odio eget orci lacinia sit amet malesuada leo feugiat. In accumsan tincidunt enim, vitae ultricies arcu egestas in. Nulla rhoncus eros vel ipsum venenatis porta. Suspendisse id erat nec mauris ultricies consectetur id feugiat odio. Vestibulum pretium tristique magna sed ultrices. Suspendisse tortor mauris, facilisis et lobortis quis, suscipit sed est. Sed vitae tortor at lacus pretium blandit. Donec vitae nibh quis orci mollis fringilla. Duis tempus augue nec ipsum euismod elementum.
+        Donec pharetra sem nec lacus posuere et lacinia ligula sollicitudin. Morbi semper commodo posuere. In adipiscing nulla ut urna fermentum vestibulum. Sed consectetur massa non neque facilisis interdum. Quisque semper massa et urna euismod nec fermentum metus feugiat. Morbi tempor commodo enim non lacinia. Aliquam elementum tortor mattis odio congue a egestas lacus bibendum. Integer nec leo massa, a ullamcorper mi. Morbi vitae massa arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
+        Nam nulla nibh, tempus ut dictum eget, euismod vitae metus. Donec vitae nulla nec quam sagittis gravida vel quis eros. Nullam vel est justo. Donec euismod interdum magna, et rutrum libero tincidunt vel. Praesent imperdiet, magna et suscipit facilisis, nulla justo consequat nisl, et mollis elit nunc a est. Sed felis quam, condimentum eget gravida non, semper non quam. Duis vestibulum sem id erat tristique eleifend. Phasellus ante nunc, pulvinar nec facilisis at, hendrerit sed leo. Morbi lacinia nisl id nunc faucibus lacinia. Curabitur adipiscing leo a odio aliquet hendrerit. Nullam laoreet pulvinar suscipit.
+        Cras ante tortor, rutrum non pharetra vel, tempor et velit. Mauris semper, libero sit amet interdum interdum, metus purus rutrum libero, eget suscipit lectus augue eu magna. Aliquam quis dui a nunc luctus faucibus. Sed viverra augue rutrum odio placerat laoreet. Nulla scelerisque augue nec enim condimentum sollicitudin. Proin accumsan, turpis in viverra lobortis, nulla mauris euismod turpis, sit amet auctor felis lacus sed leo. Nullam posuere bibendum urna, ut mattis eros varius ac. Mauris sed metus orci, ut lobortis eros. Sed imperdiet bibendum tincidunt. Donec adipiscing sapien vitae ligula faucibus quis auctor nisi pretium. Morbi at nulla quam, in aliquet quam. Suspendisse potenti. Fusce varius gravida egestas. Nulla lectus velit, posuere et auctor a, congue id massa. Quisque ut lectus eu metus malesuada sollicitudin ac a risus.
+        Nullam massa ipsum, pulvinar ut facilisis a, commodo ut orci. Mauris ac ipsum diam, sit amet laoreet tortor. In pretium, nulla vel ornare euismod, nibh augue pharetra magna, at semper felis diam in ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus blandit ornare dignissim. Fusce et nulla urna. Morbi nec ante erat. Nullam ut urna libero. Nulla non ipsum purus, et cursus lectus. Etiam vehicula, mauris in faucibus vehicula, dolor quam sodales neque, sed laoreet est augue at lacus. Nunc tincidunt lacinia elit eu dignissim. Mauris at enim mauris. Donec congue auctor dui, eget posuere ante accumsan in. Nulla non quam enim, eget tempor arcu. Suspendisse nec nibh diam, ut congue est. Fusce at urna eget velit posuere ornare nec eget mauris. Sed accumsan magna et enim mollis dignissim.
+        <script type="text/javascript">
+            // here we fake an action that would the casue the body's size to mutate.
+            setTimeout(function() {
+                var html = document.body.innerHTML;
+                document.body.innerHTML = html.substring(0, html.length / 2);
+            }, 3000);
+
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/transport.html b/asterix-examples/src/main/resources/js/easyXDM/example/transport.html
new file mode 100644
index 0000000..769feb0
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/transport.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            var transport = new easyXDM.Socket(/** The configuration */{
+                /**
+                 * Register the url to name.html, this must be an absolute path
+                 * or a path relative to the root.
+                 * @field
+                 */
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                /**
+                 * Register the url to the remote interface
+                 * @field
+                 */
+                remote: REMOTE + "/remotetransport.html",
+                remoteHelper: REMOTE + "/../name.html",
+                onReady: function(){
+                    /**
+                     * If we want to do something once the transport is ready then we can place it here
+                     */
+                }
+            });
+            // messages will be buffered until the transport is ready
+            transport.postMessage("This is a message sent from " + location);
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload.html b/asterix-examples/src/main/resources/js/easyXDM/example/upload.html
new file mode 100644
index 0000000..569feb4
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            
+            // this is just some bootstrapping code in order to provide
+            // the correct host name depending on where it is being run.
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            
+            
+            var btn;
+            var remote = new easyXDM.Rpc({
+                remote: REMOTE + "/upload_rpc.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                onReady: function(){
+                    //display the upload form
+                    var frm = document.getElementById("frmUpload");
+                    frm.action = REMOTE + "/upload_handler.aspx";
+                    frm.style.display = "block";
+                    btn = document.getElementById("btnSubmit");
+                    
+                    frm.onsubmit = function(){
+                        btn.disabled = "disabled";
+                    };
+                }
+            }, {
+                local: {
+                    returnUploadResponse: function(response){
+                        // here you should call back into your regular workflow
+                        btn.disabled = null;
+                        alert(response.msg);
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <form id="frmUpload" style="display:none" method="POST" target="upload_target" enctype="multipart/form-data">
+            <input type="file" name="upload_file"/><input type="submit" id="btnSubmit" value="Upload file"/>
+        </form><!--
+        tracking code
+        -->
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx b/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx
new file mode 100644
index 0000000..8c652ee
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+    </head>
+    <body>
+        <script type="text/javascript">
+            // this should be outputted by the server side code 
+            parent.rpc.returnUploadResponse({
+                status: "success",
+                msg: "The upload succeeded!"
+            });
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html b/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html
new file mode 100644
index 0000000..37123ec
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            // the `rpc` object will be referenced by the upload handler
+            var rpc = new easyXDM.Rpc({
+                swf: "../easyxdm.swf"
+            }, {
+                remote: {
+                    returnUploadResponse: {}
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <iframe name="upload_target" src="about:blank">
+        </iframe>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/widget.html b/asterix-examples/src/main/resources/js/easyXDM/example/widget.html
new file mode 100644
index 0000000..5093eeb
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/widget.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM.Widget</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript" src="../easyXDM.Widgets.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.whenReady(function(){
+                var widget = new easyXDM.Widget({
+                    subscriptions: ["testtopic"],
+                    swf: "../easyxdm.swf",
+                    initialize: function(widget, widgetManager){
+                        // Set up the widget
+                        var _container, _btnPublish;
+                        
+                        // Render the UI
+                        _container = document.body.appendChild(document.createElement("div"));
+                        _btnPublish = _container.appendChild(document.createElement("button"));
+                        _btnPublish.innerHTML = "Publish";
+                        easyXDM.DomHelper.on(_btnPublish, "click", function(){
+                            widget.publish("testtopic", {
+                                latitude: 1,
+                                longitude: 2
+                            });
+                        });
+                        
+                        // Register the handler for incoming messages
+                        widget.registerMessageHandler(function(url, topic, data){
+                            _container.appendChild(document.createElement("div")).innerHTML = "got data on topic " + topic + " from " + url;
+                        });
+                    },
+                    initialized: function(widget, widgetManager){
+                        widget.publish("testtopic", {
+                            latitude: 1,
+                            longitude: 2
+                        });
+                    }
+                });
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html b/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html
new file mode 100644
index 0000000..17bff03
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript" src="../easyXDM.Widgets.debug.js">
+        </script>
+        <script type="text/javascript">
+            var _widgetManager;
+            easyXDM.whenReady(function(){
+                _widgetManager = new easyXDM.WidgetManager({
+                    swf: "../easyxdm.swf",
+                    container: document.getElementById("widgets")
+                });
+                document.getElementById("widget1url").value = location.href.replace("consumer", "provider").replace("widgets.html", "widget.html");
+                document.getElementById("widget2url").value = location.href.replace("consumer.", "").replace("widgets.html", "widget.html");
+            });
+        </script>
+        <style type="text/css">
+            
+            #widgets {
+                height: 400px;
+            }
+            
+            #widgets iframe {
+                width: 200px;
+                height: 300px;
+                float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div>
+            <input type="text" id="widget1url" style="width:300px" value=""/><input type="button" onclick="_widgetManager.addWidget(document.getElementById('widget1url').value,{});" value="Add Widget"/><input type="button" onclick="_widgetManager.removeWidget(document.getElementById('widget1url').value);" value="Remove Widget"/>
+        </div>
+        <div>
+            <input type="text" id="widget2url" style="width:300px" value=""/><input type="button" onclick="_widgetManager.addWidget(document.getElementById('widget2url').value,{});" value="Add Widget"/><input type="button" onclick="_widgetManager.removeWidget(document.getElementById('widget2url').value);" value="Remove Widget"/>
+        </div><input type="button" onclick="_widgetManager.publish('testtopic','abc');" value="publish"/>
+        <div id="widgets">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html b/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html
new file mode 100644
index 0000000..a6d7f5d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            // this is only bootstrapping code
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            // this is really what you are after
+            var xhr = new easyXDM.Rpc({
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                remote: REMOTE + "/../cors/",
+                remoteHelper: REMOTE + "/../name.html"
+            }, {
+                remote: {
+                    request: {}
+                }
+            });
+            
+            function getGlossary(){
+                xhr.request({
+                    url: "../example/glossary.aspx",
+                    method: "POST",
+                    headers: {
+                        "x-auth-token": "abcde"
+                    },
+                    data: {
+                        param1: "a",
+                        param2: "b"
+                    }
+                }, function(rpcdata){
+                    var json = easyXDM.getJSONObject().parse(rpcdata.data);
+                    
+                    document.getElementById("response").innerHTML = json.glossary.title;
+                    document.getElementById("header").innerHTML = rpcdata.headers["x-foo"];
+                });
+                
+            }
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <div>
+            This example shows how to use easyXDM to call regular ajax/cors services (no JSONP) from remote domains.
+            <br/>
+            <input type="button" onclick="getGlossary()" value="Call getGlossary using the exposed method"/>
+            <br/>
+            Data from response:<span id="response"></span>
+            <br/>
+            Data from header:<span id="header"></span>
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/json2.js b/asterix-examples/src/main/resources/js/easyXDM/json2.js
new file mode 100644
index 0000000..a1a3b17
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/json2.js
@@ -0,0 +1,482 @@
+/*
+    http://www.JSON.org/json2.js
+    2010-03-20
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON) {
+    this.JSON = {};
+}
+
+(function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                   this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
diff --git a/asterix-examples/src/main/resources/js/easyXDM/name.html b/asterix-examples/src/main/resources/js/easyXDM/name.html
new file mode 100644
index 0000000..cc403b1
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/name.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<html>
+    <head>
+        <title></title>
+        <meta http-equiv="CACHE-CONTROL" content="PUBLIC"/>
+        <meta http-equiv="EXPIRES" content="Sat, 01 Jan 2050 00:00:00 GMT"/>
+    </head>
+    <body>
+        <script type="text/javascript">
+        
+        function sendMessage(message, url){
+            window.setTimeout(function(){
+                window.name = message;
+                location.href = url + "," + encodeURIComponent(location.protocol + "//" + location.host + location.pathname);
+            }, 0);
+        }
+        
+        if (location.hash) {
+            if (location.hash.substring(1, 2) === "_") {
+                var channel, url, hash = location.href.substring(location.href.indexOf("#") + 3), indexOf = hash.indexOf(",");
+                if (indexOf == -1) {
+                    channel = hash;
+                }
+                else {
+                    channel = hash.substring(0, indexOf);
+                    url = decodeURIComponent(hash.substring(indexOf + 1));
+                }
+                switch (location.hash.substring(2, 3)) {
+                    case "2":
+                        // NameTransport local
+                        window.parent.parent.easyXDM.Fn.get(channel)(window.name);
+                        location.href = url + "#_4" + channel + ",";
+                        break;
+                    case "3":
+                        // NameTransport remote
+                        var guest = window.parent.frames["easyXDM_" + channel + "_provider"];
+                        if (!guest) {
+                            throw new Error("unable to reference window");
+                        }
+                        guest.easyXDM.Fn.get(channel)(window.name);
+                        location.href = url + "#_4" + channel + ",";
+                        break;
+                    case "4":
+                        // NameTransport idle
+                        var fn = window.parent.easyXDM.Fn.get(channel + "_load");
+                        if (fn) {
+                            fn();
+                        }
+                        break;
+                }
+            }
+        }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css
new file mode 100644
index 0000000..0df87e3
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css
@@ -0,0 +1,14 @@
+.easyTest_messages {
+}
+
+.easyTest_error {
+    color: red;
+}
+
+.easyTest_success {
+    color: green;
+}
+
+.easyTest_msg {
+    color: black;
+}
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
new file mode 100644
index 0000000..1da4812
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
@@ -0,0 +1,262 @@
+var easyTest = (function(){
+    var _messages;
+    var _start;
+    var MessageType = {
+        Error: 1,
+        Success: 2,
+        Info: 3
+    };
+    
+    /**
+     * Logs the message to the body
+     * @param {String} msg The message to displey
+     * @param {MessageType} type The messagetype
+     */
+    function _log(msg, type){
+        var el = _messages.appendChild(document.createElement("div"));
+        el.innerHTML = msg;
+        _messages.scrollTop = _messages.scrollHeight;
+        switch (type) {
+            case MessageType.Error:
+                el.className = "easyTest_error";
+                break;
+            case MessageType.Success:
+                el.className = "easyTest_success";
+                break;
+            default:
+                el.className = "easyTest_msg";
+                break;
+        }
+    }
+    
+    var Assert = {
+        // Type checks
+        isTypeOf: function(type, obj){
+            return typeof obj === type;
+        },
+        isInstanceOf: function(type, obj){
+            return obj instanceof type;
+        },
+        isString: function(obj){
+            return this.isTypeOf("string", obj);
+        },
+        isNumber: function(obj){
+            return this.isTypeOf("number", obj);
+        },
+        isObject: function(obj){
+            return this.isTypeOf("object", obj);
+        },
+        isBoolean: function(obj){
+            return this.isTypeOf("boolean", obj);
+        },
+        isFunction: function(obj){
+            return this.isTypeOf("function", obj);
+        },
+        // Equality
+        areEqual: function(a, b){
+            return a == b;
+        },
+        areNotEqual: function(a, b){
+            return a != b;
+        },
+        // Identical
+        areSame: function(a, b){
+            return a === b;
+        },
+        areNotSame: function(a, b){
+            return a !== b;
+        }
+        
+    };
+    
+    function Test(test, fn){
+        var _scope, _steps = test.steps, _step, _stepIndex = 0;
+        var _timer, _runStep, _startedAt, _stepStartedAt;
+        
+        /**
+         * Clean up and tear down the test.<br/>
+         * Calls back to notify that the test is complete
+         */
+        function _endTest(){
+            // Tear down the test
+            if (test.tearDown) {
+                try {
+                    test.tearDown.call(_scope);
+                } 
+                catch (ex) {
+                    _log("Teardown '" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'", MessageType.Error);
+                }
+            }
+            for (var key in _scope) {
+                if (_scope.hasOwnProperty(key)) {
+                    delete _scope[key];
+                }
+            }
+            
+            // Call back
+            fn();
+        }
+        
+        /**
+         * Used to notify the framework of the result of the test
+         * @param {String} name The name of the test
+         * @param {Boolean} result The result of the test
+         * @param {String} reason An optional reason why the test returned the result
+         */
+        function _notifyResult(name, result, reason){
+            var now = new Date().getTime();
+            var testsetTime = now - _start.getTime();
+            var testTime = now - _startedAt.getTime();
+            var stepTime = now - _stepStartedAt.getTime();
+            
+            var times = testsetTime + "ms, " + testTime + "ms, " + stepTime + "ms - ";
+            if (result) {
+                _log(times + name + " succeeded! " + (reason || ""), MessageType.Success);
+            }
+            else {
+                _log(times + name + " failed! " + (reason || ""), MessageType.Error);
+                if (test.failedMessage) {
+                    _log(test.failedMessage, MessageType.Info);
+                }
+            }
+            // Go to next step
+            if (result) {
+                _stepIndex++;
+                window.setTimeout(function(){
+                    _runStep();
+                }, 0);
+            }
+            else {
+                _endTest();
+            }
+        }
+        
+        
+        /**
+         * Runs through the test step
+         */
+        _runStep = function(){
+            if (_stepIndex < _steps.length) {
+                // We still have steps to run
+                _step = _steps[_stepIndex];
+                _stepStartedAt = new Date();
+                if (_step.timeout) {
+                    // This an asynchronous test
+                    _timer = window.setTimeout(function(){
+                        _notifyResult(_step.name, false, "Failed due to timeout.");
+                    }, _step.timeout);
+                    try {
+                        _step.run.call(_scope);
+                    } 
+                    catch (ex) {
+                        //If it fails we cancel the timeout
+                        window.clearTimeout(_timer);
+                        _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+                    }
+                }
+                else {
+                    // This is a synchronous test
+                    try {
+                        var result = _step.run.call(_scope);
+                        _notifyResult(_step.name, result);
+                    } 
+                    catch (ex) {
+                        _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+                    }
+                }
+            }
+            else {
+                _endTest();
+            }
+        };
+        
+        return {
+            /**
+             * Runs the test.
+             * Will first try to execute the setup method before continuing the steps
+             */
+            run: function(){
+                var excuse;
+                if (test.runIf) {
+                    excuse = test.runIf();
+                }
+                if (excuse) {
+                    _log("Skipping test ' " + test.name + "'. " + excuse);
+                    fn();
+                }
+                else {
+                    _log("Running test '" + test.name + "'");
+                    _scope = {
+                        Assert: Assert,
+                        log: _log,
+                        notifyResult: function(result){
+                            window.clearTimeout(_timer);
+                            _notifyResult(_step.name, result);
+                        }
+                    };
+                    if (test.setUp) {
+                        // Setup the test
+                        try {
+                            test.setUp.call(_scope);
+                            _log("Setup succeeded", MessageType.Success);
+                        } 
+                        catch (ex) {
+                            _log("Setup failed", MessageType.Error);
+                        }
+                    }
+                    _startedAt = new Date();
+                    _runStep();
+                }
+            }
+        };
+    }
+    
+    return {
+        /**
+         * Runs through all the tests
+         * @param {Array} tests The tests to run
+         */
+        test: function(testset){
+            var tests = [], testConfig, i = testset.length, test;
+            
+            // Prepare the messaging facilities
+            if (!_messages) {
+                _messages = document.createElement("div");
+                _messages.className = "easyTest_messages";
+                (document.getElementById("messages") || document.body).appendChild(_messages);
+            }
+            else {
+                _messages.innerHTML = "";
+            }
+            
+            // Convert the testset
+            while (i--) {
+                testConfig = testset[i];
+                if (!testConfig.steps) {
+                    // Convert a single step test to a proper test
+                    testConfig = {
+                        steps: testConfig
+                    };
+                }
+                
+                tests.push(new Test(testConfig, function(){
+                    // Get the next test to run
+                    test = tests.pop();
+                    if (test) {
+                        // This is needed to avoid a strange bug in Opera,
+                        window.setTimeout(function(){
+                            test.run();
+                        }, 0);
+                    }
+                    else {
+                        // No more tests to run
+                        _log("Test run complete", MessageType.Info);
+                    }
+                }));
+            }
+            // Start the first test
+            _start = new Date();
+            tests.pop().run();
+        }
+    };
+}());
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js b/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js
new file mode 100644
index 0000000..c1c614a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js
@@ -0,0 +1,2848 @@
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+var _trace = emptyFn;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        _trace("adding listener " + type);
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        _trace("removing listener " + type);
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        _trace("adding listener " + sEvent);
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        _trace("removing listener " + sEvent);
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    _trace("firing dom_onReady");
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            if (!obj) {
+                throw new Error(ii.slice(0, i + 1).join('.') + ' is not an object');
+            }
+            obj = obj[ii[i]];
+        }
+    }
+    if (!obj || !obj.easyXDM) {
+        throw new Error('Could not find easyXDM in parent.' + namespace);
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    if (typeof ns != "string" || !ns) {
+        throw new Error('namespace must be a non-empty string');
+    }
+    _trace("Settings namespace to '" + ns + "'");
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    if (/^file/.test(url)) {
+        throw new Error("The file:// protocol is not supported");
+    }
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    _trace("resolved url '" + url + "'");
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    if (!parameters) {
+        throw new Error("parameters is undefined or null");
+    }
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+    _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    _trace("creating frame: " + config.props.src);
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    _trace("preparing transport stack");
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        _trace("using parameters from query");
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+            _trace("selecting protocol: " + protocol);
+        }
+        else {
+            _trace("using protocol: " + protocol);
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    _trace("looking for image to use as local");
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        _trace("no image found, defaulting to using the window");
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+// Expose helper functions so we can test them
+apply(easyXDM, {
+    checkAcl: checkAcl,
+    getDomainName: getDomainName,
+    getLocation: getLocation,
+    appendQueryParameters: appendQueryParameters
+});
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var debug = {
+    _deferred: [],
+    flush: function(){
+        this.trace("... deferred messages ...");
+        for (var i = 0, len = this._deferred.length; i < len; i++) {
+            this.trace(this._deferred[i]);
+        }
+        this._deferred.length = 0;
+        this.trace("... end of deferred messages ...");
+    },
+    getTime: function(){
+        var d = new Date(), h = d.getHours() + "", m = d.getMinutes() + "", s = d.getSeconds() + "", ms = d.getMilliseconds() + "", zeros = "000";
+        if (h.length == 1) {
+            h = "0" + h;
+        }
+        if (m.length == 1) {
+            m = "0" + m;
+        }
+        if (s.length == 1) {
+            s = "0" + s;
+        }
+        ms = zeros.substring(ms.length) + ms;
+        return h + ":" + m + ":" + s + "." + ms;
+    },
+    /**
+     * Logs the message to console.log if available
+     * @param {String} msg The message to log
+     */
+    log: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!isHostObject(window, "console") || undef(console.log)) {
+            /**
+             * Sets log to be an empty function since we have no output available
+             * @ignore
+             */
+            this.log = emptyFn;
+        }
+        else {
+            /**
+             * Sets log to be a wrapper around console.log
+             * @ignore
+             * @param {String} msg
+             */
+            this.log = function(msg){
+                console.log(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ": " + msg);
+            };
+        }
+        this.log(msg);
+    },
+    /**
+     * Will try to trace the given message either to a DOMElement with the id "log",
+     * or by using console.info.
+     * @param {String} msg The message to trace
+     */
+    trace: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!domIsReady) {
+            if (this._deferred.length === 0) {
+                easyXDM.whenReady(debug.flush, debug);
+            }
+            this._deferred.push(msg);
+            this.log(msg);
+        }
+        else {
+            var el = document.getElementById("log");
+            // is there a log element present?
+            if (el) {
+                /**
+                 * Sets trace to be a function that outputs the messages to the DOMElement with id "log"
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    try {
+                        el.appendChild(document.createElement("div")).appendChild(document.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                        el.scrollTop = el.scrollHeight;
+                    } 
+                    catch (e) {
+                        //In case we are unloading
+                    }
+                };
+            }
+            else if (isHostObject(window, "console") && !undef(console.info)) {
+                /**
+                 * Sets trace to be a wrapper around console.info
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    console.info(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg);
+                };
+            }
+            else {
+                /**
+                 * Create log window
+                 * @ignore
+                 */
+                var domain = location.host, windowname = domain.replace(/[\-.:]/g, "") + "easyxdm_log", logWin;
+                try {
+                    logWin = window.open("", windowname, "width=800,height=200,status=0,navigation=0,scrollbars=1");
+                } 
+                catch (e) {
+                }
+                if (logWin) {
+                    var doc = logWin.document;
+                    el = doc.getElementById("log");
+                    if (!el) {
+                        doc.write("<html><head><title>easyXDM log " + domain + "</title></head>");
+                        doc.write("<body><div id=\"log\"></div></body></html>");
+                        doc.close();
+                        el = doc.getElementById("log");
+                    }
+                    this.trace = function(msg){
+                        try {
+                            el.appendChild(doc.createElement("div")).appendChild(doc.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                            el.scrollTop = el.scrollHeight;
+                        } 
+                        catch (e) {
+                            //In case we are unloading
+                        }
+                    };
+                    this.trace("---- new logger at " + location.href);
+                }
+                
+                if (!el) {
+                    // We are unable to use any logging
+                    this.trace = emptyFn;
+                }
+            }
+            this.trace(msg);
+        }
+    },
+    /**
+     * Creates a method usable for tracing.
+     * @param {String} name The name the messages should be marked with
+     * @return {Function} A function that accepts a single string as argument.
+     */
+    getTracer: function(name){
+        return function(msg){
+            debug.trace(name + ": " + msg);
+        };
+    }
+};
+debug.log("easyXDM present on '" + location.href);
+easyXDM.Debug = debug;
+_trace = debug.getTracer("{Private}");
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            debug.log("loading external JSON");
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+        else {
+            debug.log("native JSON found");
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            this._trace("storing function " + name);
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            this._trace("retrieving function " + name);
+            var fn = _map[name];
+            if (!fn) {
+                this._trace(name + " not found");
+            }
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+    easyXDM.Fn._trace = debug.getTracer("easyXDM.Fn");
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    var trace = debug.getTracer("easyXDM.Socket");
+    trace("constructor");
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    var trace = debug.getTracer("easyXDM.Rpc");
+    trace("constructor");
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.SameOriginTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FlashTransport");
+    trace("constructor");
+    if (!config.swf) {
+        throw new Error("Path to easyxdm.swf is missing");
+    }
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            trace("received message");
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        trace("creating factory with SWF from " + domain);
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        flashVars += "&log=true";
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    trace("firing onReady");
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.PostMessageTransport");
+    trace("constructor");
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        trace("received message '" + event.data + "' from " + origin);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        trace("firing onReady");
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FrameElementTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.NameTransport");
+    trace("constructor");
+    if (config.isHost && undef(config.remoteHelper)) {
+        trace("missing remoteHelper");
+        throw new Error("missing remoteHelper");
+    }
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        trace("sending message " + message);
+        trace("navigating to  '" + url + "'");
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            trace("calling onReady");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        trace("received message " + message);
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            trace("destroy");
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    trace("received initial message " + message);
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.HashTransport");
+    trace("constructor");
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        trace("sending message '" + (_msgNr + 1) + " " + message + "' to " + _remoteOrigin);
+        if (!_callerWindow) {
+            trace("no caller window");
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            trace("poll: new message");
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        trace("starting polling");
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            trace("unable to get reference to _listenerWindow, giving up");
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            trace("got a reference to _listenerWindow");
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.ReliableBehavior");
+    trace("constructor");
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            trace("incoming: " + message);
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                trace("message delivered");
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                trace("sending ack, and passing on " + message);
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.QueueBehavior");
+    trace("constructor");
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            trace("removing myself from the stack");
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        trace("dispatching from queue");
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    trace("received the last fragment");
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+                else {
+                    trace("waiting for more fragments, seq=" + message);
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    trace("enqueuing");
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.VerifyBehavior");
+    trace("constructor");
+    if (undef(config.initiate)) {
+        throw new Error("settings.initiate is not set");
+    }
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        trace("requesting verification");
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    trace("verified, calling callback");
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    trace("returning secret");
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var trace = debug.getTracer("easyXDM.stack.RpcBehavior");
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        trace("creating method " + method);
+        return function(){
+            trace("executing method " + method);
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            trace("requested to execute non-existent procedure " + method);
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        trace("requested to execute procedure " + method);
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                trace("received request to execute method " + data.method + (data.id ? (" using callback id " + data.id) : ""));
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                trace("received return value destined to callback with id " + data.id);
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                    else {
+                        trace("unhandled error returned.");
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            trace("init");
+            if (config.remote) {
+                trace("creating stubs");
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            trace("destroy");
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/index.html b/asterix-examples/src/main/resources/js/easyXDM/tests/index.html
new file mode 100644
index 0000000..0232da9
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/index.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+        <meta http-equiv="X-UA-Compatible" content="IE=100">
+        <title>easyTest results</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // The first instance of easyXDM
+        </script>
+        <script type="text/javascript">
+            easyXDM._test_global = true;
+        </script>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // The second instance of easyXDM (to test noConflict)
+        </script>
+        <script type="text/javascript">
+            // Used in the noConflict test
+            var modules = {
+                easyXDM: easyXDM.noConflict("modules")
+            };
+        </script>
+        <script type="text/javascript">
+            if (location.href.indexOf("src") !== -1) {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../../tools/json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+            else {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+        </script>
+        <script type="text/javascript" src="easyTest.js">
+        </script>
+        <link type="text/css" rel="stylesheet" href="easyTest.css"/>
+        <script type="text/javascript" src="tests.js">
+        </script>
+        <style type="text/css">
+            
+            #embedded {
+                height: 100px;
+            }
+            
+            #embedded iframe {
+                height: 50px;
+            }
+            
+            #log {
+                height: 100px;
+                border: 1px dotted black;
+                overflow: auto
+            }
+            
+            .easyTest_messages {
+                height: 300px;
+                border: 1px dotted black;
+                overflow: auto;
+            }
+        </style>
+    </head>
+    <body onload="runTests();">
+        <h1>easyXDM test suite</h1>
+        <h4>easyTest messages</h4>
+        <div id="messages">
+        </div>
+        <h4>easyXDM tracelog</h4>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log">
+        </div>
+        <div id="embedded">
+        </div>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+                document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+            }
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif b/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html
new file mode 100644
index 0000000..63d7a3e
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var modules = {
+                easyXDM: easyXDM.noConflict("modules")
+            };
+            
+            var transport;
+            window.onload = function(){
+                transport = new modules.easyXDM.Socket({
+                    local: "../name.html",
+                    swf: "../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        // Echo back the message
+                        transport.postMessage(message);
+                    }
+                });
+            };
+            window.onunload = function(){
+                if (transport) {
+                    transport.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html
new file mode 100644
index 0000000..11a489f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            if (location.href.indexOf("src") !== -1) {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../../tools/json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+            else {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc({
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, {
+                remote: {
+                    voidCallback: {}
+                },
+                local: {
+                    voidMethod: function(msg){
+                        // Echo back the message
+                        remote.voidCallback(msg);
+                    },
+                    asyncMethod: function(msg, fn){
+                        window.setTimeout(function(){
+                            // Echo back the msg
+                            fn(msg);
+                        }, 100);
+                    },
+                    // use the shorthand notation
+                    method: function(msg){
+                        // Echo back the msg
+                        return msg;
+                    },
+                    error: function(){
+                        var a, b = a.c;
+                    },
+                    namedParamsMethod: {
+                        method: function(params){
+                            return params.msg;
+                        }
+                    }
+                }
+            });
+            window.onunload = function(){
+                if (remote) {
+                    remote.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html
new file mode 100644
index 0000000..eb405cf
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var transport;
+            window.onload = function(){
+                transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: "../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        // Echo back the message
+                        transport.postMessage(message);
+                    }
+                });
+            };
+            window.onunload = function(){
+                if (transport) {
+                    transport.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js b/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js
new file mode 100644
index 0000000..d0a940a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js
@@ -0,0 +1,855 @@
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyTest, easyXDM, window, modules*/
+var REMOTE = (function(){
+    var remote = location.href;
+    switch (location.host) {
+        case "provider.easyxdm.net":
+            location.href = remote.replace("provider", "consumer");
+            break;
+        case "easyxdm.net":
+            remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+            break;
+        case "consumer.easyxdm.net":
+            remote = remote.replace("consumer", "provider");
+            break;
+        case "xdm1":
+            remote = remote.replace("xdm1", "xdm2");
+            break;
+    }
+    return remote.substring(0, remote.lastIndexOf("/"));
+}());
+
+var LOCAL = location.protocol + "//" + location.host + location.pathname.substring(0, location.pathname.lastIndexOf("/"));
+
+function runTests(){
+    var i = 0;
+    easyTest.test([/**Tests for the presence of namespaces and classes*/{
+        name: "Check that the library is complete",
+        steps: [{
+            name: "check for the presence of easyXDM",
+            run: function(){
+                if (this.Assert.isObject(easyXDM) && this.Assert.isString(easyXDM.version)) {
+                    this.log("found easyXDM, version=" + easyXDM.version);
+                    return true;
+                }
+                return false;
+            }
+        }, {
+            name: "check for the presence of easyXDM.DomHelper",
+            run: function(){
+                return this.Assert.isObject(easyXDM.DomHelper);
+            }
+        }, {
+            name: "check for the presence of easyXDM.Socket",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.Socket);
+            }
+        }, {
+            name: "check for the presence of easyXDM.Rpc",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.Rpc);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack",
+            run: function(){
+                return this.Assert.isObject(easyXDM.stack);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.SameOriginTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.SameOriginTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.PostMessageTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.PostMessageTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.FlashTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.FlashTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.NameTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.NameTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.HashTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.HashTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.ReliableBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.ReliableBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.QueueBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.QueueBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.VerifyBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.VerifyBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.RpcBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.RpcBehavior);
+            }
+        }]
+    }, {
+        name: "Check helper functions",
+        runIf: function(){
+            if (location.href.indexOf("/src/") == -1) {
+                return "This can only be run in development.";
+            }
+        },
+        setUp: function(){
+            this.url1 = "http://foo.bar/a/b/c?d=e#f";
+            this.url2 = "http://foo.bar:80/a/b/c?d=e#f";
+            this.url3 = "http://foo.bar:88/a/b/c?d=e#f";
+            this.url4 = "hTtp://Foo.Bar:88/a/b/c?d=e#f";
+            
+        },
+        steps: [{
+            name: "getDomainName",
+            run: function(){
+                return easyXDM.getDomainName(this.url1) === "foo.bar";
+            }
+        }, {
+            name: "getLocation",
+            run: function(){
+                return easyXDM.getLocation(this.url1) === "http://foo.bar";
+            }
+        }, {
+            name: "getLocation with standard port",
+            run: function(){
+                return easyXDM.getLocation(this.url2) === "http://foo.bar";
+            }
+        }, {
+            name: "getLocation with non-standard port",
+            run: function(){
+                return easyXDM.getLocation(this.url3) === "http://foo.bar:88";
+            }
+        }, {
+            name: "getLocation with capitals",
+            run: function(){
+                return easyXDM.getLocation(this.url4) === "http://foo.bar:88";
+            }
+        }, {
+            name: "appendQueryParameters",
+            run: function(){
+                return easyXDM.appendQueryParameters(this.url2, {
+                    g: "h"
+                }) ===
+                "http://foo.bar:80/a/b/c?d=e&g=h#f";
+            }
+        }]
+    }, {
+        name: "Check the ACL feature",
+        runIf: function(){
+            if (location.href.indexOf("/src/") == -1) {
+                return "This can only be run in development.";
+            }
+        },
+        setUp: function(){
+            this.acl = ["http://www.domain.invalid", "*.domaina.com", "http://dom?inb.com", "^http://domc{3}ain\\.com$"];
+        },
+        steps: [{
+            name: "Match complete string",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://www.domain.invalid");
+            }
+        }, {
+            name: "Match *",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://www.domaina.com");
+            }
+        }, {
+            name: "Match ?",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://domainb.com");
+            }
+        }, {
+            name: "Match RegExp",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://domcccain.com");
+            }
+        }, {
+            name: "No match",
+            run: function(){
+                return !easyXDM.checkAcl(this.acl, "http://foo.com");
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{SameOriginTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "4",
+                    remote: LOCAL + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{PostMessageTransport}",
+        runIf: function(){
+            if (!("postMessage" in window || "postMessage" in document)) {
+                return "This test requires the HTML5 postMessage interface.";
+            }
+        },
+        
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "1",
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{FlashTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "6",
+                    remote: REMOTE + "/test_transport.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: "embedded",
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{FrameElementTransport}",
+        runIf: function(){
+            if (!(navigator.product === "Gecko" && "frameElement" in window && !("postMessage" in window) && navigator.userAgent.indexOf('WebKit') == -1)) {
+                return "This test requires an older Gecko browser and the presence of the frameElement object";
+            }
+        },
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "5",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{NameTransport}",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "2", // This is just to override the automatic selection
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} using window",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: window,
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with no blank local, available image and resize",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+            this.img = document.createElement("img");
+            this.img.src = "s.gif";
+            document.body.appendChild(this.img);
+        },
+        tearDown: function(){
+            document.body.removeChild(this.img);
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (++messages === 2) {
+                            scope.notifyResult(true);
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with s.gif and polling",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: "s.gif",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (++messages === 2) {
+                            scope.notifyResult(true);
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with fragmentation (8192)",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            var i = 11;
+            this.expectedMessage = "aaaa";
+            while (i--) {
+                this.expectedMessage += this.expectedMessage;
+            }
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult(scope.expectedMessage === message);
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.noConflict {SameOriginTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "window.easyXDM is released {namespace}",
+            timeout: 5000,
+            run: function(){
+                this.notifyResult(window.easyXDM._test_global && !modules.easyXDM._test_global);
+            }
+        }, {
+            name: "onReady is fired {namespace}",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new modules.easyXDM.Socket({
+                    protocol: "4",
+                    remote: LOCAL + "/test_namespace.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back {namespace}",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy {namespace}",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} using hash for passing data",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html?foo=bar",
+                    hash: true,
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} with buffering",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "Buffered messages are sent",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    }
+                });
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} with query parameters",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html?a=b&c=d#foo,faa",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Rpc",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.remote.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote = new easyXDM.Rpc({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_rpc.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                }, {
+                    remote: {
+                        voidMethod: {},
+                        asyncMethod: {},
+                        method: {},
+                        error: {},
+                        nonexistent: {},
+                        namedParamsMethod: {
+                            namedParams: true
+                        }
+                    },
+                    local: {
+                        voidCallback: {
+                            method: function(message){
+                                scope.notifyResult((scope.expectedMessage === message));
+                            }
+                        }
+                    }
+                });
+            }
+        }, {
+            name: "void method",
+            timeout: 5000,
+            run: function(){
+                this.remote.voidMethod(this.expectedMessage);
+            }
+        }, {
+            name: "async method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.asyncMethod(this.expectedMessage, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }, {
+            name: "regular method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.method(this.expectedMessage, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }, {
+            name: "with error",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.error(this.expectedMessage, function(){
+                    this.notifyResult(false, "success handler called");
+                }, function(message){
+                    scope.notifyResult(true);
+                });
+            }
+        }, {
+            name: "calling nonexistent method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.nonexistent(this.expectedMessage, function(){
+                    this.notifyResult(false, "success handler called");
+                }, function(message){
+                    scope.notifyResult(true);
+                });
+            }
+        }, {
+            name: "using named parameters",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.namedParamsMethod({
+                    msg: this.expectedMessage
+                }, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }]
+    }]);
+}
diff --git a/asterix-examples/src/main/resources/js/example.js b/asterix-examples/src/main/resources/js/example.js
index e69de29..cf5d02b 100644
--- a/asterix-examples/src/main/resources/js/example.js
+++ b/asterix-examples/src/main/resources/js/example.js
@@ -0,0 +1,39 @@
+var tinySocialCreate = ["drop dataverse TinySocial if exists;",
+"create dataverse TinySocial;",
+"use dataverse TinySocial;",
+"create type TwitterUserType as open {",
+"screen-name: string,",
+"lang: string,",
+"friends_count: int32,",
+"statuses_count: int32,",
+"name: string,",
+"followers_count: int32",
+"}",
+"create type TweetMessageType as closed {",
+"tweetid: string,",
+"user: TwitterUserType,",
+"sender-location: point?,",
+"send-time: datetime,",
+"referred-topics: {{ string }},",
+"message-text: string",
+"}",
+"create type EmploymentType as open {",
+"organization-name: string,",
+"start-date: date,",
+"end-date: date?",
+"}",
+"create type FacebookUserType as closed {",
+"id: int32,",
+"alias: string,",
+"name: string,",
+"user-since: datetime,",
+"friend-ids: {{ int32 }},",
+"employment: [EmploymentType]",
+"}",
+"create type FacebookMessageType as closed {",
+"message-id: int32,",
+"author-id: int32,",
+"in-response-to: int32?,",
+"sender-location: point?,",
+"message: string",
+"}"];
