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));
+                });
+            }
+        }]
+    }]);
+}
