diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/AsterixSDKServlet.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/AsterixSDKServlet.java
index 598090d..3ae36df 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/AsterixSDKServlet.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/AsterixSDKServlet.java
@@ -9,11 +9,16 @@
 
     @Override
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        response.setContentType("application/json");
+        
+        String requestURI = request.getRequestURI();
+        String contentType = "application/javascript";
+        if (requestURI.endsWith("html")) {
+            contentType = "text/html";
+        }
+        response.setContentType(contentType);
         response.setCharacterEncoding("utf-8");
 
         PrintWriter out = response.getWriter();
-        String requestURI = request.getRequestURI();
 
         if (requestURI.startsWith("/sdk/static/")) {
             InputStream is = APIServlet.class.getResourceAsStream(requestURI);
@@ -21,6 +26,7 @@
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 return;
             }
+
             InputStreamReader isr = new InputStreamReader(is);
             StringBuilder sb = new StringBuilder();
             BufferedReader br = new BufferedReader(isr);
@@ -28,6 +34,7 @@
 
             while (line != null) {
                 sb.append(line);
+                sb.append("\n");
                 line = br.readLine();
             }
 
diff --git a/asterix-app/src/main/resources/sdk/static/client.html b/asterix-app/src/main/resources/sdk/static/client.html
new file mode 100644
index 0000000..d421a7a1
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/client.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
+        <script src="js/easyXDM.debug.js" type="text/javascript"></script>
+        <script src="js/asterix-api-core.js" type="text/javascript"></script>
+        <script>
+            var a = new AsterixSDK();
+            a.requestHandler();
+        </script>
+    </head>
+    <body>
+        'ello
+    </body>
+</html>
diff --git a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js b/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
index 5821198..0d67c9b 100644
--- a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
+++ b/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
@@ -1,14 +1,203 @@
+function AsterixSDK() {
+    
+    // Local RPC Handler for REST API
+    this.xhr = new easyXDM.Rpc({
+        remote: "http://localhost:19101/sdk/static/client.html"
+    }, {
+        remote: {
+            post: {}
+        }
+    });
+}
+
+
+AsterixSDK.prototype.send = function(handler) {
+    var api = handler.onSend();
+    this.xhr.post(
+        api.endpoint,
+        api.apiData,
+        function(data) {
+            alert("Sending Asterix SDK \n" + JSON.stringify(data));
+        }// handler.callback
+   );
+}
+
+
+AsterixSDK.prototype.client = function() {
+    this.xhr.post("http://www.localhost:19101/query",
+        {
+            "param" : "test"
+        },
+        function(data) {
+           // alert("hello world");
+        }
+    );
+}
+
+
+AsterixSDK.prototype.requestHandler = function() {
+    var rpc = new easyXDM.Rpc({}, {
+        local: {
+            post: {
+                method: function(url, data, fn, fnError){
+                    alert(url + "\ndata\n" + JSON.stringify(data));
+                }
+            }
+        }
+    });
+}
+
+
+// Asterix REST Controller
+// Handles interactions with remote database using a request handler
+function AsterixRESTController() {
+    
+    // REST DDL API
+    this.DDL = function(data, callback) {
+        this.endpoint = "http://localhost:19101/ddl";
+        this.apiData = data;
+        this.callback = callback;
+    };
+
+}
+
+AsterixRESTController.prototype.Update = function(json, data, callback) {
+    var endpoint = "http://localhost:19101/update";
+}
+
+
+AsterixRESTController.prototype.Query = function(json, data, callback) {
+    var endpoint = "http://localhost:19101/query";
+}
+
+
+AsterixRESTController.prototype.QueryStatus = function(json, data, callback) {
+    var endpoint = "http://localhost:19101/query/status";
+}
+
+
+AsterixRESTController.prototype.QueryResult = function(json, data, callback) {
+    var endpoint = "http://localhost:19101/query/result";
+}
+
+
+
+
+function AsterixSDKJQueryHandler(json, endpoint, callback) {
+    $.ajax({
+        type : 'GET',
+        url : endpoint,
+        data : json,
+        dataType : "json",
+        success : function(data) {
+            alert(JSON.stringify(data));
+        }
+    });
+}
+
+
+function AsterixExpression() {}
+
+
+// Create expressions
+// Create types, dataverses, indexes
+CreateExpression.prototype = new AsterixExpression();
+CreateExpression.prototype.constructor = CreateExpression;
+function CreateExpression(statement) {
+    this.value = statement;
+    this.send = this.onSend;
+}
+CreateExpression.prototype.onSend = function () {
+    var arc = new AsterixRESTController();
+    myThis = this;
+    arc.DDL( 
+        { "ddl" : myThis.value },
+        function () {}
+    );
+    return arc;
+};
+
+
+// For expressions
+// TODO Is this correct name?
+// TODO Probably query API
+ForExpression.prototype = new AsterixExpression();
+ForExpression.prototype.constructor = ForExpression;
+function ForExpression() {}
+ForExpression.prototype.onSend = function () {
+
+}
+
+// 
+
+/*
+// ************************
+// Asterix Query Manager
+// ************************
+
+// FOR REVIEW: This is not a good name, but I have no idea what to name it.
+function AsterixCoreJS() {
+    this.Expression = AQLExpression;
+    this.FLWOGR = AQLFLWOGR;
+    this.IfThenElse = AQLIfThenElse;
+}
+
+// ********************************
+// Asterix REST API Communication
+// ********************************
+function AsterixAPIRequest() {
+   var xmlhttp = new XMLHttpRequest();
+   xmlhttp.open("GET", "http://localhost:19101/query", true);
+   xmlhttp.setRequestHeader('Content-Type', 'application/json');
+   xmlhttp.send(JSON.stringify({"query" : "use dataverse dne;"}));
+   var serverResponse = xmlhttp.responseText;
+   alert(serverResponse);
+}
+
+// ********************
+// Asterix Expressions
+// ********************
+
 function AsterixExpression() {
 
+    // PRIVATE MEMBERS
+    
+    // PROTECTED METHODS
+    // * May be overridden with prototypes
+    // * May access private members
+    // * May not be changed
+   
+    // PUBLIC
 }
 
-function AsterixBindable() {
+// PUBLIC EXPRESSION PROPERTIES
+AsterixExpression.prototype.bindTo = function() {
 
 }
 
-function AsterixAPI() {
-    this.test = function() {
-        alert("testing");
-    };
-    return this;
+// For some AsterixExpression extension foo:
+// foo.prototype = new AsterixExpression();
+// foo.prototype.constructor = foo;
+// function foo() { // Set properties here }
+// foo.prototype.anotherMethod = function() { // Another example function }
+
+// AsterixFLWOGR
+// Inherits From: AsterixExpression
+//
+// FLWOGR   ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
+AQLFLWOGR.prototype = new AsterixExpression();
+AQLFLWOGR.prototype.constructor = AQLFLWOGR;
+function AQLFLWOGR() {
+
 }
+
+// AsterixIfThenElse
+// Inherits From: AsterixExpression
+//
+// IfThenElse   ::= "if" <LEFTPAREN> Expression <RIGHTPAREN> "then" 
+// Expression "else" Expression
+AQLIfThenElse.prototype = new AsterixExpression();
+AQLIfThenElse.prototype.constructor = AQLIfThenElse;
+function AQLIfThenElse() {
+
+}*/
diff --git a/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js b/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js
new file mode 100644
index 0000000..61b9738
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/js/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/html/example.html b/asterix-examples/src/main/resources/html/example.html
index 0a3af38..01f6ed0 100644
--- a/asterix-examples/src/main/resources/html/example.html
+++ b/asterix-examples/src/main/resources/html/example.html
@@ -1,15 +1,56 @@
 <!DOCTYPE html>
 <html>
     <head>
-        <script src="http://localhost:19101/sdk/static/js/asterix-api-core.js"
-            type="text/javascript"></script>
+        <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
+        <script src="../js/easyXDM/easyXDM.debug.js" type="text/javascript"></script>
+        <script src="http://localhost:19101/sdk/static/js/asterix-api-core.js" type="text/javascript"></script>
         <script src="../js/example.js" type="text/javascript"></script> 
         <script>
-            var a = new AsterixAPI();
-            a.test();
+            $(function () {
+                var as = new AsterixSDK();
+                var c = new CreateExpression(tinySocialCreate.join("\n"));
+                as.send(c);
+
+                $('#ddl').html(tinySocialCreate.join("<br/>"));
+            });
         </script>
     </head>
     <body>
-         
+        <div>
+            Example: DDL
+            <div class="syntax-box" id="ddl">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+        
+        <div>
+            Example: 
+            <div class="syntax-box">
+                Query:
+            </div>
+            <button>Run</button>
+            <hr>
+        </div>
+
     </body>
 </html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt b/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt
new file mode 100644
index 0000000..4320fb1
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/MIT-license.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2009-2011 Øyvind Sean Kinsey, oyvind@kinsey.no
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/cors/index.html b/asterix-examples/src/main/resources/js/easyXDM/cors/index.html
new file mode 100644
index 0000000..9370e1d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/cors/index.html
@@ -0,0 +1,214 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM cross-domain XHMLHttpRequest provider</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // This should be changed so that it points to the minified version before use in production.
+        </script>
+        <script type="text/javascript">
+            // Update to point to your copy
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+        
+        /* 
+         * This is a CORS (Cross-Origin Resource Sharing) and AJAX enabled endpoint for easyXDM.
+         * The ACL code is adapted from pmxdr (http://github.com/eligrey/pmxdr/) by Eli Grey (http://eligrey.com/)
+         *
+         */
+        // From http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+        function isHostMethod(object, property){
+            var t = typeof object[property];
+            return t == 'function' ||
+            (!!(t == 'object' && object[property])) ||
+            t == 'unknown';
+        }
+        
+        /**
+         * Creates a cross-browser XMLHttpRequest object
+         * @return {XMLHttpRequest} A XMLHttpRequest object.
+         */
+        var getXhr = (function(){
+            if (isHostMethod(window, "XMLHttpRequest")) {
+                return function(){
+                    return new XMLHttpRequest();
+                };
+            }
+            else {
+                var item = (function(){
+                    var list = ["Microsoft", "Msxml2", "Msxml3"], i = list.length;
+                    while (i--) {
+                        try {
+                            item = list[i] + ".XMLHTTP";
+                            var obj = new ActiveXObject(item);
+                            return item;
+                        } 
+                        catch (e) {
+                        }
+                    }
+                }());
+                return function(){
+                    return new ActiveXObject(item);
+                };
+            }
+        }());
+        
+        // this file is by default set up to use Access Control - this means that it will use the headers set by the server to decide whether or not to allow the call to return
+        var useAccessControl = true;
+        // always trusted origins, can be exact strings or regular expressions
+        var alwaysTrustedOrigins = [(/\.?easyxdm\.net/), (/xdm1/)];
+        
+        // instantiate a new easyXDM object which will handle the request 
+        var remote = new easyXDM.Rpc({
+            local: "../name.html",
+            swf: "../easyxdm.swf"
+        }, {
+            local: {
+                // define the exposed method
+                request: function(config, success, error){
+                
+                    // apply default values if not set
+                    easyXDM.apply(config, {
+                        method: "POST",
+                        headers: {
+                            "Content-Type": "application/x-www-form-urlencoded",
+                            "X-Requested-With": "XMLHttpRequest"
+                        },
+                        success: Function.prototype,
+                        error: function(msg){
+                            throw new Error(msg);
+                        },
+                        data: {},
+                        timeout: 10 * 1000
+                    }, true);
+                    
+                    // set the CORS request header
+                    // only if there is no XHR2 features
+                    if (!window.XMLHttpRequest || !('withCredentials' in (new XMLHttpRequest))) {
+                        config.headers.Origin = remote.origin;
+                    }
+                    
+                    var isPOST = config.method == "POST";
+                    
+                    // convert the data into a format we can send to the server 
+                    var pairs = [];
+                    for (var key in config.data) {
+                        if (config.data.hasOwnProperty(key)) {
+                            pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(config.data[key]));
+                        }
+                    }
+                    var data = pairs.join("&");
+                    
+                    // create the XMLHttpRequest object
+                    var req = getXhr();
+                    var url = !isPOST && data
+                        ? config.url + (~config.url.indexOf('?') ? '&' : '?') + data
+                        : config.url;
+                    req.open(config.method, url, true);
+                    
+                    // apply the request headers
+                    for (var prop in config.headers) {
+                        if (config.headers.hasOwnProperty(prop) && config.headers[prop]) {
+                            req.setRequestHeader(prop, config.headers[prop]);
+                        }
+                    }
+                    
+                    // set a timeout
+                    var timeout;
+                    timeout = setTimeout(function(){
+                        // reset the handler
+                        req.onreadystatechange = Function.prototype;
+                        req.abort();
+                        req = null;
+                        error({
+                            message: "timeout after " + config.timeout + " second",
+                            status: 0,
+                            data: null,
+                            toString: function(){
+                                return this.message + " Status: " + this.status;
+                            }
+                        }, null);
+                    }, config.timeout);
+                    
+                    // check if this origin should always be trusted
+                    var alwaysTrusted = false, i = alwaysTrustedOrigins.length;
+                    while (i-- && !alwaysTrusted) {
+                        if (alwaysTrustedOrigins[i] instanceof RegExp) {
+                            alwaysTrusted = alwaysTrustedOrigins[i].test(remote.origin);
+                        }
+                        else if (typeof alwaysTrustedOrigins[i] == "string") {
+                            alwaysTrusted = (remote.origin === alwaysTrustedOrigins[i]);
+                        }
+                    }
+                    
+                    
+                    // define the onreadystate handler
+                    req.onreadystatechange = function(){
+                        if (req.readyState == 4) {
+                            clearTimeout(timeout);
+                            
+                            // parse the response headers
+                            var rawHeaders = req.getAllResponseHeaders(), headers = {}, headers_lowercase = {}, reHeader = /([\w-_]+):\s+(.*)$/gm, m;
+                            while ((m = reHeader.exec(rawHeaders))) {
+                                headers_lowercase[m[1].toLowerCase()] = headers[m[1]] = m[2];
+                            }
+                            
+                            if (req.status < 200 || req.status >= 300) {
+                                if (useAccessControl) {
+                                    error("INVALID_STATUS_CODE");
+                                }
+                                else {
+                                    error("INVALID_STATUS_CODE", {
+                                        status: req.status,
+                                        data: req.responseText
+                                    });
+                                }
+                            }
+                            else {
+                            
+                                var errorMessage;
+                                if (useAccessControl) {
+                                    // normalize the valuse access controls
+                                    var aclAllowedOrigin = (headers_lowercase["access-control-allow-origin"] || "").replace(/\s/g, "");
+                                    var aclAllowedMethods = (headers_lowercase["access-control-allow-methods"] || "").replace(/\s/g, "");
+                                    
+                                    // determine if origin is trusted
+                                    if (alwaysTrusted || aclAllowedOrigin == "*" || aclAllowedOrigin.indexOf(remote.origin) != -1) {
+                                        // determine if the request method was allowed
+                                        if (aclAllowedMethods && aclAllowedMethods != "*" && aclAllowedMethods.indexOf(config.method) == -1) {
+                                            errorMessage = "DISALLOWED_REQUEST_METHOD";
+                                        }
+                                    }
+                                    else {
+                                        errorMessage = "DISALLOWED_ORIGIN";
+                                    }
+                                    
+                                }
+                                
+                                if (errorMessage) {
+                                    error(errorMessage);
+                                }
+                                else {
+                                    success({
+                                        data: req.responseText,
+                                        status: req.status,
+                                        headers: headers
+                                    });
+                                }
+                            }
+                            // reset the handler
+                            req.onreadystatechange = Function.prototype;
+                            req = null;
+                        }
+                    };
+                    
+                    // issue the request
+                    req.send(isPOST ? data : "");
+                }
+            }
+        });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip b/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip
new file mode 100644
index 0000000..c44301f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM-2.4.17.1.zip
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js
new file mode 100644
index 0000000..7dcf4bd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.debug.js
@@ -0,0 +1,333 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*jslint browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window */
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/**
+ * @class easyXDM.WidgetManager
+ * A class for managing widgets.<br/>
+ * Handles initializing widgets, and does all of the message distribution.
+ <pre><code>
+ _widgetManager = new easyXDM.WidgetManager({
+ local: "../hash.html",
+ container: document.getElementById("defaultcontainer")
+ },function(){
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{});
+ });
+ </code></pre>
+ * Widgets can by dynamically added using the addWidget method
+ <pre><code>
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{
+ container document.getElementById("widgetcontainer")
+ });
+ </code></pre>
+ * @constructor
+ * @param {Object} config The WidgetManagers configuration
+ * @namespace easyXDM
+ */
+easyXDM.WidgetManager = function(config){
+    var WidgetManager = this, _hashUrl = config.local, _channelNr = 0;
+    var Events = {
+        WidgetInitialized: "widgetinitialized",
+        WidgetFailed: "widgetfailed"
+    };
+    var _widgets = {}, _subscribers = {};
+    var _widgetSettings = {
+        hosturl: location.href
+    };
+    easyXDM.apply(_widgetSettings, config.widgetSettings);
+    var _container = config.container || document.body;
+    
+    /**
+     * @private
+     * Raises the specified event
+     * @param {String} event The raised event
+     * @param {Object} arg
+     */
+    function _raiseEvent(event, arg){
+        if (config.listeners && config.listeners[event]) {
+            config.listeners[event](WidgetManager, arg);
+        }
+    }
+    
+    /**
+     * @private
+     * Adds the widghet to the list of subscribers for the given topic
+     * @param {String} url The widgets url
+     * @param {String} topic The topic to subscribe to
+     */
+    function _subscribe(url, topic){
+        if (!(topic in _subscribers)) {
+            _subscribers[topic] = [];
+        }
+        _subscribers[topic].push(url);
+    }
+    
+    /**
+     * @private
+     * Initialized the widget.<br/>
+     * This is called after the widget has notified that it is ready.
+     * @param {Object} widget The widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _initializeWidget(widget, url, widgetConfig){
+        widget.initialize(_widgetSettings, function(response){
+            if (response.isInitialized) {
+                _widgets[url] = widget;
+                var i = response.subscriptions.length;
+                while (i--) {
+                    _subscribe(url, response.subscriptions[i]);
+                }
+                _raiseEvent(Events.WidgetInitialized, {
+                    url: url
+                });
+            }
+            else {
+                widget.destroy();
+                _raiseEvent(Events.WidgetFailed, {
+                    url: url
+                });
+            }
+        });
+    }
+    
+    /**
+     * @private
+     * Publishes the data to the topics subscribers
+     * @param {String} url The senders url
+     * @param {String} topic The datas topic
+     * @param {Object} data The data to publish
+     */
+    function _publish(url, topic, data){
+        var subscribers = _subscribers[topic];
+        if (subscribers) {
+            var i = subscribers.length, widgetUrl;
+            while (i--) {
+                widgetUrl = subscribers[i];
+                if (widgetUrl !== url) {
+                    _widgets[widgetUrl].send(url, topic, data);
+                }
+            }
+        }
+    }
+    
+    /**
+     * @private
+     * Sets up a new widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _setUpWidget(url, widgetConfig){
+        var widget = new easyXDM.Rpc({
+            channel: "widget" + _channelNr++,
+            local: _hashUrl,
+            remote: url,
+            container: widgetConfig.container || _container,
+            swf: config.swf,
+            onReady: function(){
+                _initializeWidget(widget, url, widgetConfig);
+            }
+        }, {
+            local: {
+                subscribe: {
+                    isVoid: true,
+                    method: function(topic){
+                        _subscribe(url, topic);
+                    }
+                },
+                publish: {
+                    isVoid: true,
+                    method: function(topic, data){
+                        _publish(url, topic, data);
+                    }
+                }
+            },
+            remote: {
+                initialize: {},
+                send: {
+                    isVoid: true
+                }
+            }
+        });
+    }
+    
+    /**
+     * Adds a widget to the collection
+     * @param {String} url The url to load the widget from
+     * @param {Object} widgetConfig The widgets url
+     */
+    this.addWidget = function(url, widgetConfig){
+        if (url in _widgets) {
+            throw new Error("A widget with this url has already been initialized");
+        }
+        _setUpWidget(url, widgetConfig);
+    };
+    
+    /**
+     * Removes the widget
+     * @param {Object} url
+     */
+    this.removeWidget = function(url){
+        if (url in _widgets) {
+            for (var topic in _subscribers) {
+                if (_subscribers.hasOwnProperty(topic)) {
+                    var subscribers = _subscribers[topic], i = subscribers.length;
+                    while (i--) {
+                        if (subscribers[i] === url) {
+                            subscribers.splice(i, 1);
+                            break;
+                        }
+                    }
+                }
+            }
+            _widgets[url].destroy();
+            delete _widgets[url];
+        }
+    };
+    
+    /**
+     * Publish data to a topics subscribers
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _publish("", topic, data);
+    };
+    
+    /**
+     * Broadcasts data to all the widgets
+     * @param {Object} data The data to broadcast
+     */
+    this.broadcast = function(data){
+        for (var url in _widgets) {
+            if (_widgets.hasOwnPropert(url)) {
+                _widgets[url].send({
+                    url: "",
+                    topic: "broadcast",
+                    data: data
+                });
+            }
+        }
+    };
+};
+
+/**
+ * @class easyXDM.Widget
+ * The base framework for creating widgets
+ * @constructor
+ * @param {Object} config The widgets configuration
+ * @param {Function} onReady A method to run after the widget has been initialized.
+ * @namespace easyXDM
+ */
+easyXDM.Widget = function(config){
+    var _widget = this;
+    var _incomingMessageHandler;
+    var _widgetHost = new easyXDM.Rpc({
+        swf: config.swf
+    }, {
+        remote: {
+            subscribe: {
+                isVoid: true
+            },
+            publish: {
+                isVoid: true
+            }
+        },
+        local: {
+            initialize: {
+                method: function(settings){
+                    config.initialized(_widget, _widgetHost);
+                    return {
+                        isInitialized: true,
+                        subscriptions: config.subscriptions
+                    };
+                }
+            },
+            send: {
+                isVoid: true,
+                method: function(url, topic, data){
+                    _incomingMessageHandler(url, topic, data);
+                }
+            }
+        }
+    });
+    
+    /**
+     * @private
+     * Destroy the interface on unload
+     */
+    window.onunload = function(){
+        _widgetHost.destroy();
+    };
+    
+    /**
+     * Publish data to subscribers to a topic
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _widgetHost.publish(topic, data);
+    };
+    
+    /**
+     * Subscribe to a topic
+     * @param {String} topic The topic to subscribe to
+     */
+    this.subscribe = function(topic){
+        _widgetHost.subscribe(topic);
+    };
+    
+    /**
+     * Register the method that will handle incoming messages
+     * @param {Function} fn The handler
+     */
+    this.registerMessageHandler = function(fn){
+        _incomingMessageHandler = fn;
+    };
+    
+    config.initialize(this, _widgetHost);
+};
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js
new file mode 100644
index 0000000..7dcf4bd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.js
@@ -0,0 +1,333 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*jslint browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window */
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/**
+ * @class easyXDM.WidgetManager
+ * A class for managing widgets.<br/>
+ * Handles initializing widgets, and does all of the message distribution.
+ <pre><code>
+ _widgetManager = new easyXDM.WidgetManager({
+ local: "../hash.html",
+ container: document.getElementById("defaultcontainer")
+ },function(){
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{});
+ });
+ </code></pre>
+ * Widgets can by dynamically added using the addWidget method
+ <pre><code>
+ _widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{
+ container document.getElementById("widgetcontainer")
+ });
+ </code></pre>
+ * @constructor
+ * @param {Object} config The WidgetManagers configuration
+ * @namespace easyXDM
+ */
+easyXDM.WidgetManager = function(config){
+    var WidgetManager = this, _hashUrl = config.local, _channelNr = 0;
+    var Events = {
+        WidgetInitialized: "widgetinitialized",
+        WidgetFailed: "widgetfailed"
+    };
+    var _widgets = {}, _subscribers = {};
+    var _widgetSettings = {
+        hosturl: location.href
+    };
+    easyXDM.apply(_widgetSettings, config.widgetSettings);
+    var _container = config.container || document.body;
+    
+    /**
+     * @private
+     * Raises the specified event
+     * @param {String} event The raised event
+     * @param {Object} arg
+     */
+    function _raiseEvent(event, arg){
+        if (config.listeners && config.listeners[event]) {
+            config.listeners[event](WidgetManager, arg);
+        }
+    }
+    
+    /**
+     * @private
+     * Adds the widghet to the list of subscribers for the given topic
+     * @param {String} url The widgets url
+     * @param {String} topic The topic to subscribe to
+     */
+    function _subscribe(url, topic){
+        if (!(topic in _subscribers)) {
+            _subscribers[topic] = [];
+        }
+        _subscribers[topic].push(url);
+    }
+    
+    /**
+     * @private
+     * Initialized the widget.<br/>
+     * This is called after the widget has notified that it is ready.
+     * @param {Object} widget The widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _initializeWidget(widget, url, widgetConfig){
+        widget.initialize(_widgetSettings, function(response){
+            if (response.isInitialized) {
+                _widgets[url] = widget;
+                var i = response.subscriptions.length;
+                while (i--) {
+                    _subscribe(url, response.subscriptions[i]);
+                }
+                _raiseEvent(Events.WidgetInitialized, {
+                    url: url
+                });
+            }
+            else {
+                widget.destroy();
+                _raiseEvent(Events.WidgetFailed, {
+                    url: url
+                });
+            }
+        });
+    }
+    
+    /**
+     * @private
+     * Publishes the data to the topics subscribers
+     * @param {String} url The senders url
+     * @param {String} topic The datas topic
+     * @param {Object} data The data to publish
+     */
+    function _publish(url, topic, data){
+        var subscribers = _subscribers[topic];
+        if (subscribers) {
+            var i = subscribers.length, widgetUrl;
+            while (i--) {
+                widgetUrl = subscribers[i];
+                if (widgetUrl !== url) {
+                    _widgets[widgetUrl].send(url, topic, data);
+                }
+            }
+        }
+    }
+    
+    /**
+     * @private
+     * Sets up a new widget
+     * @param {String} url The widgets url
+     * @param {Object} widgetConfig The widgets configuration
+     */
+    function _setUpWidget(url, widgetConfig){
+        var widget = new easyXDM.Rpc({
+            channel: "widget" + _channelNr++,
+            local: _hashUrl,
+            remote: url,
+            container: widgetConfig.container || _container,
+            swf: config.swf,
+            onReady: function(){
+                _initializeWidget(widget, url, widgetConfig);
+            }
+        }, {
+            local: {
+                subscribe: {
+                    isVoid: true,
+                    method: function(topic){
+                        _subscribe(url, topic);
+                    }
+                },
+                publish: {
+                    isVoid: true,
+                    method: function(topic, data){
+                        _publish(url, topic, data);
+                    }
+                }
+            },
+            remote: {
+                initialize: {},
+                send: {
+                    isVoid: true
+                }
+            }
+        });
+    }
+    
+    /**
+     * Adds a widget to the collection
+     * @param {String} url The url to load the widget from
+     * @param {Object} widgetConfig The widgets url
+     */
+    this.addWidget = function(url, widgetConfig){
+        if (url in _widgets) {
+            throw new Error("A widget with this url has already been initialized");
+        }
+        _setUpWidget(url, widgetConfig);
+    };
+    
+    /**
+     * Removes the widget
+     * @param {Object} url
+     */
+    this.removeWidget = function(url){
+        if (url in _widgets) {
+            for (var topic in _subscribers) {
+                if (_subscribers.hasOwnProperty(topic)) {
+                    var subscribers = _subscribers[topic], i = subscribers.length;
+                    while (i--) {
+                        if (subscribers[i] === url) {
+                            subscribers.splice(i, 1);
+                            break;
+                        }
+                    }
+                }
+            }
+            _widgets[url].destroy();
+            delete _widgets[url];
+        }
+    };
+    
+    /**
+     * Publish data to a topics subscribers
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _publish("", topic, data);
+    };
+    
+    /**
+     * Broadcasts data to all the widgets
+     * @param {Object} data The data to broadcast
+     */
+    this.broadcast = function(data){
+        for (var url in _widgets) {
+            if (_widgets.hasOwnPropert(url)) {
+                _widgets[url].send({
+                    url: "",
+                    topic: "broadcast",
+                    data: data
+                });
+            }
+        }
+    };
+};
+
+/**
+ * @class easyXDM.Widget
+ * The base framework for creating widgets
+ * @constructor
+ * @param {Object} config The widgets configuration
+ * @param {Function} onReady A method to run after the widget has been initialized.
+ * @namespace easyXDM
+ */
+easyXDM.Widget = function(config){
+    var _widget = this;
+    var _incomingMessageHandler;
+    var _widgetHost = new easyXDM.Rpc({
+        swf: config.swf
+    }, {
+        remote: {
+            subscribe: {
+                isVoid: true
+            },
+            publish: {
+                isVoid: true
+            }
+        },
+        local: {
+            initialize: {
+                method: function(settings){
+                    config.initialized(_widget, _widgetHost);
+                    return {
+                        isInitialized: true,
+                        subscriptions: config.subscriptions
+                    };
+                }
+            },
+            send: {
+                isVoid: true,
+                method: function(url, topic, data){
+                    _incomingMessageHandler(url, topic, data);
+                }
+            }
+        }
+    });
+    
+    /**
+     * @private
+     * Destroy the interface on unload
+     */
+    window.onunload = function(){
+        _widgetHost.destroy();
+    };
+    
+    /**
+     * Publish data to subscribers to a topic
+     * @param {String} topic The topic to publish to
+     * @param {Object} data The data to publish
+     */
+    this.publish = function(topic, data){
+        _widgetHost.publish(topic, data);
+    };
+    
+    /**
+     * Subscribe to a topic
+     * @param {String} topic The topic to subscribe to
+     */
+    this.subscribe = function(topic){
+        _widgetHost.subscribe(topic);
+    };
+    
+    /**
+     * Register the method that will handle incoming messages
+     * @param {Function} fn The handler
+     */
+    this.registerMessageHandler = function(fn){
+        _incomingMessageHandler = fn;
+    };
+    
+    config.initialize(this, _widgetHost);
+};
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js
new file mode 100644
index 0000000..8ed55cd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.Widgets.min.js
@@ -0,0 +1,24 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+easyXDM.WidgetManager=function(e){var h=this,b=e.local,k=0;var n={WidgetInitialized:"widgetinitialized",WidgetFailed:"widgetfailed"};var j={},d={};var i={hosturl:location.href};easyXDM.apply(i,e.widgetSettings);var g=e.container||document.body;function f(p,o){if(e.listeners&&e.listeners[p]){e.listeners[p](h,o)}}function c(p,o){if(!(o in d)){d[o]=[]}d[o].push(p)}function m(p,o,q){p.initialize(i,function(r){if(r.isInitialized){j[o]=p;var s=r.subscriptions.length;while(s--){c(o,r.subscriptions[s])}f(n.WidgetInitialized,{url:o})}else{p.destroy();f(n.WidgetFailed,{url:o})}})}function a(p,o,r){var s=d[o];if(s){var q=s.length,t;while(q--){t=s[q];if(t!==p){j[t].send(p,o,r)}}}}function l(o,q){var p=new easyXDM.Rpc({channel:"widget"+k++,local:b,remote:o,container:q.container||g,swf:e.swf,onReady:function(){m(p,o,q)}},{local:{subscribe:{isVoid:true,method:function(r){c(o,r)}},publish:{isVoid:true,method:function(r,s){a(o,r,s)}}},remote:{initialize:{},send:{isVoid:true}}})}this.addWidget=function(o,p){if(o in j){throw new Error("A widget with this url has already been initialized")}l(o,p)};this.removeWidget=function(p){if(p in j){for(var o in d){if(d.hasOwnProperty(o)){var r=d[o],q=r.length;while(q--){if(r[q]===p){r.splice(q,1);break}}}}j[p].destroy();delete j[p]}};this.publish=function(o,p){a("",o,p)};this.broadcast=function(p){for(var o in j){if(j.hasOwnPropert(o)){j[o].send({url:"",topic:"broadcast",data:p})}}}};easyXDM.Widget=function(c){var a=this;var b;var d=new easyXDM.Rpc({swf:c.swf},{remote:{subscribe:{isVoid:true},publish:{isVoid:true}},local:{initialize:{method:function(e){c.initialized(a,d);return{isInitialized:true,subscriptions:c.subscriptions}}},send:{isVoid:true,method:function(f,e,g){b(f,e,g)}}}});window.onunload=function(){d.destroy()};this.publish=function(e,f){d.publish(e,f)};this.subscribe=function(e){d.subscribe(e)};this.registerMessageHandler=function(e){b=e};c.initialize(this,d)};
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js
new file mode 100644
index 0000000..61b9738
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.debug.js
@@ -0,0 +1,2871 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+var _trace = emptyFn;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        _trace("adding listener " + type);
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        _trace("removing listener " + type);
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        _trace("adding listener " + sEvent);
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        _trace("removing listener " + sEvent);
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    _trace("firing dom_onReady");
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            if (!obj) {
+                throw new Error(ii.slice(0, i + 1).join('.') + ' is not an object');
+            }
+            obj = obj[ii[i]];
+        }
+    }
+    if (!obj || !obj.easyXDM) {
+        throw new Error('Could not find easyXDM in parent.' + namespace);
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    if (typeof ns != "string" || !ns) {
+        throw new Error('namespace must be a non-empty string');
+    }
+    _trace("Settings namespace to '" + ns + "'");
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    if (/^file/.test(url)) {
+        throw new Error("The file:// protocol is not supported");
+    }
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    _trace("resolved url '" + url + "'");
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    if (!parameters) {
+        throw new Error("parameters is undefined or null");
+    }
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+    _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    _trace("creating frame: " + config.props.src);
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    _trace("preparing transport stack");
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        _trace("using parameters from query");
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+            _trace("selecting protocol: " + protocol);
+        }
+        else {
+            _trace("using protocol: " + protocol);
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    _trace("looking for image to use as local");
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        _trace("no image found, defaulting to using the window");
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+// Expose helper functions so we can test them
+apply(easyXDM, {
+    checkAcl: checkAcl,
+    getDomainName: getDomainName,
+    getLocation: getLocation,
+    appendQueryParameters: appendQueryParameters
+});
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var debug = {
+    _deferred: [],
+    flush: function(){
+        this.trace("... deferred messages ...");
+        for (var i = 0, len = this._deferred.length; i < len; i++) {
+            this.trace(this._deferred[i]);
+        }
+        this._deferred.length = 0;
+        this.trace("... end of deferred messages ...");
+    },
+    getTime: function(){
+        var d = new Date(), h = d.getHours() + "", m = d.getMinutes() + "", s = d.getSeconds() + "", ms = d.getMilliseconds() + "", zeros = "000";
+        if (h.length == 1) {
+            h = "0" + h;
+        }
+        if (m.length == 1) {
+            m = "0" + m;
+        }
+        if (s.length == 1) {
+            s = "0" + s;
+        }
+        ms = zeros.substring(ms.length) + ms;
+        return h + ":" + m + ":" + s + "." + ms;
+    },
+    /**
+     * Logs the message to console.log if available
+     * @param {String} msg The message to log
+     */
+    log: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!isHostObject(window, "console") || undef(console.log)) {
+            /**
+             * Sets log to be an empty function since we have no output available
+             * @ignore
+             */
+            this.log = emptyFn;
+        }
+        else {
+            /**
+             * Sets log to be a wrapper around console.log
+             * @ignore
+             * @param {String} msg
+             */
+            this.log = function(msg){
+                console.log(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ": " + msg);
+            };
+        }
+        this.log(msg);
+    },
+    /**
+     * Will try to trace the given message either to a DOMElement with the id "log",
+     * or by using console.info.
+     * @param {String} msg The message to trace
+     */
+    trace: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!domIsReady) {
+            if (this._deferred.length === 0) {
+                easyXDM.whenReady(debug.flush, debug);
+            }
+            this._deferred.push(msg);
+            this.log(msg);
+        }
+        else {
+            var el = document.getElementById("log");
+            // is there a log element present?
+            if (el) {
+                /**
+                 * Sets trace to be a function that outputs the messages to the DOMElement with id "log"
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    try {
+                        el.appendChild(document.createElement("div")).appendChild(document.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                        el.scrollTop = el.scrollHeight;
+                    } 
+                    catch (e) {
+                        //In case we are unloading
+                    }
+                };
+            }
+            else if (isHostObject(window, "console") && !undef(console.info)) {
+                /**
+                 * Sets trace to be a wrapper around console.info
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    console.info(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg);
+                };
+            }
+            else {
+                /**
+                 * Create log window
+                 * @ignore
+                 */
+                var domain = location.host, windowname = domain.replace(/[\-.:]/g, "") + "easyxdm_log", logWin;
+                try {
+                    logWin = window.open("", windowname, "width=800,height=200,status=0,navigation=0,scrollbars=1");
+                } 
+                catch (e) {
+                }
+                if (logWin) {
+                    var doc = logWin.document;
+                    el = doc.getElementById("log");
+                    if (!el) {
+                        doc.write("<html><head><title>easyXDM log " + domain + "</title></head>");
+                        doc.write("<body><div id=\"log\"></div></body></html>");
+                        doc.close();
+                        el = doc.getElementById("log");
+                    }
+                    this.trace = function(msg){
+                        try {
+                            el.appendChild(doc.createElement("div")).appendChild(doc.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                            el.scrollTop = el.scrollHeight;
+                        } 
+                        catch (e) {
+                            //In case we are unloading
+                        }
+                    };
+                    this.trace("---- new logger at " + location.href);
+                }
+                
+                if (!el) {
+                    // We are unable to use any logging
+                    this.trace = emptyFn;
+                }
+            }
+            this.trace(msg);
+        }
+    },
+    /**
+     * Creates a method usable for tracing.
+     * @param {String} name The name the messages should be marked with
+     * @return {Function} A function that accepts a single string as argument.
+     */
+    getTracer: function(name){
+        return function(msg){
+            debug.trace(name + ": " + msg);
+        };
+    }
+};
+debug.log("easyXDM present on '" + location.href);
+easyXDM.Debug = debug;
+_trace = debug.getTracer("{Private}");
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            debug.log("loading external JSON");
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+        else {
+            debug.log("native JSON found");
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            this._trace("storing function " + name);
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            this._trace("retrieving function " + name);
+            var fn = _map[name];
+            if (!fn) {
+                this._trace(name + " not found");
+            }
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+    easyXDM.Fn._trace = debug.getTracer("easyXDM.Fn");
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    var trace = debug.getTracer("easyXDM.Socket");
+    trace("constructor");
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    var trace = debug.getTracer("easyXDM.Rpc");
+    trace("constructor");
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.SameOriginTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FlashTransport");
+    trace("constructor");
+    if (!config.swf) {
+        throw new Error("Path to easyxdm.swf is missing");
+    }
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            trace("received message");
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        trace("creating factory with SWF from " + domain);
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        flashVars += "&log=true";
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    trace("firing onReady");
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.PostMessageTransport");
+    trace("constructor");
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        trace("received message '" + event.data + "' from " + origin);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        trace("firing onReady");
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FrameElementTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.NameTransport");
+    trace("constructor");
+    if (config.isHost && undef(config.remoteHelper)) {
+        trace("missing remoteHelper");
+        throw new Error("missing remoteHelper");
+    }
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        trace("sending message " + message);
+        trace("navigating to  '" + url + "'");
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            trace("calling onReady");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        trace("received message " + message);
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            trace("destroy");
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    trace("received initial message " + message);
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.HashTransport");
+    trace("constructor");
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        trace("sending message '" + (_msgNr + 1) + " " + message + "' to " + _remoteOrigin);
+        if (!_callerWindow) {
+            trace("no caller window");
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            trace("poll: new message");
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        trace("starting polling");
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            trace("unable to get reference to _listenerWindow, giving up");
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            trace("got a reference to _listenerWindow");
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.ReliableBehavior");
+    trace("constructor");
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            trace("incoming: " + message);
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                trace("message delivered");
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                trace("sending ack, and passing on " + message);
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.QueueBehavior");
+    trace("constructor");
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            trace("removing myself from the stack");
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        trace("dispatching from queue");
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    trace("received the last fragment");
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+                else {
+                    trace("waiting for more fragments, seq=" + message);
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    trace("enqueuing");
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.VerifyBehavior");
+    trace("constructor");
+    if (undef(config.initiate)) {
+        throw new Error("settings.initiate is not set");
+    }
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        trace("requesting verification");
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    trace("verified, calling callback");
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    trace("returning secret");
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var trace = debug.getTracer("easyXDM.stack.RpcBehavior");
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        trace("creating method " + method);
+        return function(){
+            trace("executing method " + method);
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            trace("requested to execute non-existent procedure " + method);
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        trace("requested to execute procedure " + method);
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                trace("received request to execute method " + data.method + (data.id ? (" using callback id " + data.id) : ""));
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                trace("received return value destined to callback with id " + data.id);
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                    else {
+                        trace("unhandled error returned.");
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            trace("init");
+            if (config.remote) {
+                trace("creating stubs");
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            trace("destroy");
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js
new file mode 100644
index 0000000..c0dabbd
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.js
@@ -0,0 +1,2576 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            obj = obj[ii[i]];
+        }
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            var fn = _map[name];
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        if (!_callerWindow) {
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        return function(){
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            if (config.remote) {
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js
new file mode 100644
index 0000000..8660795
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyXDM.min.js
@@ -0,0 +1,24 @@
+/**
+ * easyXDM
+ * http://easyxdm.net/
+ * Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function(N,d,p,K,k,H){var b=this;var n=Math.floor(Math.random()*10000);var q=Function.prototype;var Q=/^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/;var R=/[\-\w]+\/\.\.\//;var F=/([^:])\/\//g;var I="";var o={};var M=N.easyXDM;var U="easyXDM_";var E;var y=false;var i;var h;function C(X,Z){var Y=typeof X[Z];return Y=="function"||(!!(Y=="object"&&X[Z]))||Y=="unknown"}function u(X,Y){return !!(typeof(X[Y])=="object"&&X[Y])}function r(X){return Object.prototype.toString.call(X)==="[object Array]"}function c(){var Z="Shockwave Flash",ad="application/x-shockwave-flash";if(!t(navigator.plugins)&&typeof navigator.plugins[Z]=="object"){var ab=navigator.plugins[Z].description;if(ab&&!t(navigator.mimeTypes)&&navigator.mimeTypes[ad]&&navigator.mimeTypes[ad].enabledPlugin){i=ab.match(/\d+/g)}}if(!i){var Y;try{Y=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");i=Array.prototype.slice.call(Y.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/),1);Y=null}catch(ac){}}if(!i){return false}var X=parseInt(i[0],10),aa=parseInt(i[1],10);h=X>9&&aa>0;return true}var v,x;if(C(N,"addEventListener")){v=function(Z,X,Y){Z.addEventListener(X,Y,false)};x=function(Z,X,Y){Z.removeEventListener(X,Y,false)}}else{if(C(N,"attachEvent")){v=function(X,Z,Y){X.attachEvent("on"+Z,Y)};x=function(X,Z,Y){X.detachEvent("on"+Z,Y)}}else{throw new Error("Browser not supported")}}var W=false,J=[],L;if("readyState" in d){L=d.readyState;W=L=="complete"||(~navigator.userAgent.indexOf("AppleWebKit/")&&(L=="loaded"||L=="interactive"))}else{W=!!d.body}function s(){if(W){return}W=true;for(var X=0;X<J.length;X++){J[X]()}J.length=0}if(!W){if(C(N,"addEventListener")){v(d,"DOMContentLoaded",s)}else{v(d,"readystatechange",function(){if(d.readyState=="complete"){s()}});if(d.documentElement.doScroll&&N===top){var g=function(){if(W){return}try{d.documentElement.doScroll("left")}catch(X){K(g,1);return}s()};g()}}v(N,"load",s)}function G(Y,X){if(W){Y.call(X);return}J.push(function(){Y.call(X)})}function m(){var Z=parent;if(I!==""){for(var X=0,Y=I.split(".");X<Y.length;X++){Z=Z[Y[X]]}}return Z.easyXDM}function e(X){N.easyXDM=M;I=X;if(I){U="easyXDM_"+I.replace(".","_")+"_"}return o}function z(X){return X.match(Q)[3]}function f(X){return X.match(Q)[4]||""}function j(Z){var X=Z.toLowerCase().match(Q);var aa=X[2],ab=X[3],Y=X[4]||"";if((aa=="http:"&&Y==":80")||(aa=="https:"&&Y==":443")){Y=""}return aa+"//"+ab+Y}function B(X){X=X.replace(F,"$1/");if(!X.match(/^(http||https):\/\//)){var Y=(X.substring(0,1)==="/")?"":p.pathname;if(Y.substring(Y.length-1)!=="/"){Y=Y.substring(0,Y.lastIndexOf("/")+1)}X=p.protocol+"//"+p.host+Y+X}while(R.test(X)){X=X.replace(R,"")}return X}function P(X,aa){var ac="",Z=X.indexOf("#");if(Z!==-1){ac=X.substring(Z);X=X.substring(0,Z)}var ab=[];for(var Y in aa){if(aa.hasOwnProperty(Y)){ab.push(Y+"="+H(aa[Y]))}}return X+(y?"#":(X.indexOf("?")==-1?"?":"&"))+ab.join("&")+ac}var S=(function(X){X=X.substring(1).split("&");var Z={},aa,Y=X.length;while(Y--){aa=X[Y].split("=");Z[aa[0]]=k(aa[1])}return Z}(/xdm_e=/.test(p.search)?p.search:p.hash));function t(X){return typeof X==="undefined"}var O=function(){var Y={};var Z={a:[1,2,3]},X='{"a":[1,2,3]}';if(typeof JSON!="undefined"&&typeof JSON.stringify==="function"&&JSON.stringify(Z).replace((/\s/g),"")===X){return JSON}if(Object.toJSON){if(Object.toJSON(Z).replace((/\s/g),"")===X){Y.stringify=Object.toJSON}}if(typeof String.prototype.evalJSON==="function"){Z=X.evalJSON();if(Z.a&&Z.a.length===3&&Z.a[2]===3){Y.parse=function(aa){return aa.evalJSON()}}}if(Y.stringify&&Y.parse){O=function(){return Y};return Y}return null};function T(X,Y,Z){var ab;for(var aa in Y){if(Y.hasOwnProperty(aa)){if(aa in X){ab=Y[aa];if(typeof ab==="object"){T(X[aa],ab,Z)}else{if(!Z){X[aa]=Y[aa]}}}else{X[aa]=Y[aa]}}}return X}function a(){var Y=d.body.appendChild(d.createElement("form")),X=Y.appendChild(d.createElement("input"));X.name=U+"TEST"+n;E=X!==Y.elements[X.name];d.body.removeChild(Y)}function A(Y){if(t(E)){a()}var ac;if(E){ac=d.createElement('<iframe name="'+Y.props.name+'"/>')}else{ac=d.createElement("IFRAME");ac.name=Y.props.name}ac.id=ac.name=Y.props.name;delete Y.props.name;if(typeof Y.container=="string"){Y.container=d.getElementById(Y.container)}if(!Y.container){T(ac.style,{position:"absolute",top:"-2000px",left:"0px"});Y.container=d.body}var ab=Y.props.src;Y.props.src="javascript:false";T(ac,Y.props);ac.border=ac.frameBorder=0;ac.allowTransparency=true;Y.container.appendChild(ac);if(Y.onLoad){v(ac,"load",Y.onLoad)}if(Y.usePost){var aa=Y.container.appendChild(d.createElement("form")),X;aa.target=ac.name;aa.action=ab;aa.method="POST";if(typeof(Y.usePost)==="object"){for(var Z in Y.usePost){if(Y.usePost.hasOwnProperty(Z)){if(E){X=d.createElement('<input name="'+Z+'"/>')}else{X=d.createElement("INPUT");X.name=Z}X.value=Y.usePost[Z];aa.appendChild(X)}}}aa.submit();aa.parentNode.removeChild(aa)}else{ac.src=ab}Y.props.src=ab;return ac}function V(aa,Z){if(typeof aa=="string"){aa=[aa]}var Y,X=aa.length;while(X--){Y=aa[X];Y=new RegExp(Y.substr(0,1)=="^"?Y:("^"+Y.replace(/(\*)/g,".$1").replace(/\?/g,".")+"$"));if(Y.test(Z)){return true}}return false}function l(Z){var ae=Z.protocol,Y;Z.isHost=Z.isHost||t(S.xdm_p);y=Z.hash||false;if(!Z.props){Z.props={}}if(!Z.isHost){Z.channel=S.xdm_c.replace(/["'<>\\]/g,"");Z.secret=S.xdm_s;Z.remote=S.xdm_e.replace(/["'<>\\]/g,"");ae=S.xdm_p;if(Z.acl&&!V(Z.acl,Z.remote)){throw new Error("Access denied for "+Z.remote)}}else{Z.remote=B(Z.remote);Z.channel=Z.channel||"default"+n++;Z.secret=Math.random().toString(16).substring(2);if(t(ae)){if(j(p.href)==j(Z.remote)){ae="4"}else{if(C(N,"postMessage")||C(d,"postMessage")){ae="1"}else{if(Z.swf&&C(N,"ActiveXObject")&&c()){ae="6"}else{if(navigator.product==="Gecko"&&"frameElement" in N&&navigator.userAgent.indexOf("WebKit")==-1){ae="5"}else{if(Z.remoteHelper){ae="2"}else{ae="0"}}}}}}}Z.protocol=ae;switch(ae){case"0":T(Z,{interval:100,delay:2000,useResize:true,useParent:false,usePolling:false},true);if(Z.isHost){if(!Z.local){var ac=p.protocol+"//"+p.host,X=d.body.getElementsByTagName("img"),ad;var aa=X.length;while(aa--){ad=X[aa];if(ad.src.substring(0,ac.length)===ac){Z.local=ad.src;break}}if(!Z.local){Z.local=N}}var ab={xdm_c:Z.channel,xdm_p:0};if(Z.local===N){Z.usePolling=true;Z.useParent=true;Z.local=p.protocol+"//"+p.host+p.pathname+p.search;ab.xdm_e=Z.local;ab.xdm_pa=1}else{ab.xdm_e=B(Z.local)}if(Z.container){Z.useResize=false;ab.xdm_po=1}Z.remote=P(Z.remote,ab)}else{T(Z,{channel:S.xdm_c,remote:S.xdm_e,useParent:!t(S.xdm_pa),usePolling:!t(S.xdm_po),useResize:Z.useParent?false:Z.useResize})}Y=[new o.stack.HashTransport(Z),new o.stack.ReliableBehavior({}),new o.stack.QueueBehavior({encode:true,maxLength:4000-Z.remote.length}),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"1":Y=[new o.stack.PostMessageTransport(Z)];break;case"2":Z.remoteHelper=B(Z.remoteHelper);Y=[new o.stack.NameTransport(Z),new o.stack.QueueBehavior(),new o.stack.VerifyBehavior({initiate:Z.isHost})];break;case"3":Y=[new o.stack.NixTransport(Z)];break;case"4":Y=[new o.stack.SameOriginTransport(Z)];break;case"5":Y=[new o.stack.FrameElementTransport(Z)];break;case"6":if(!i){c()}Y=[new o.stack.FlashTransport(Z)];break}Y.push(new o.stack.QueueBehavior({lazy:Z.lazy,remove:true}));return Y}function D(aa){var ab,Z={incoming:function(ad,ac){this.up.incoming(ad,ac)},outgoing:function(ac,ad){this.down.outgoing(ac,ad)},callback:function(ac){this.up.callback(ac)},init:function(){this.down.init()},destroy:function(){this.down.destroy()}};for(var Y=0,X=aa.length;Y<X;Y++){ab=aa[Y];T(ab,Z,true);if(Y!==0){ab.down=aa[Y-1]}if(Y!==X-1){ab.up=aa[Y+1]}}return ab}function w(X){X.up.down=X.down;X.down.up=X.up;X.up=X.down=null}T(o,{version:"2.4.17.1",query:S,stack:{},apply:T,getJSONObject:O,whenReady:G,noConflict:e});o.DomHelper={on:v,un:x,requiresJSON:function(X){if(!u(N,"JSON")){d.write('<script type="text/javascript" src="'+X+'"><\/script>')}}};(function(){var X={};o.Fn={set:function(Y,Z){X[Y]=Z},get:function(Z,Y){var aa=X[Z];if(Y){delete X[Z]}return aa}}}());o.Socket=function(Y){var X=D(l(Y).concat([{incoming:function(ab,aa){Y.onMessage(ab,aa)},callback:function(aa){if(Y.onReady){Y.onReady(aa)}}}])),Z=j(Y.remote);this.origin=j(Y.remote);this.destroy=function(){X.destroy()};this.postMessage=function(aa){X.outgoing(aa,Z)};X.init()};o.Rpc=function(Z,Y){if(Y.local){for(var ab in Y.local){if(Y.local.hasOwnProperty(ab)){var aa=Y.local[ab];if(typeof aa==="function"){Y.local[ab]={method:aa}}}}}var X=D(l(Z).concat([new o.stack.RpcBehavior(this,Y),{callback:function(ac){if(Z.onReady){Z.onReady(ac)}}}]));this.origin=j(Z.remote);this.destroy=function(){X.destroy()};X.init()};o.stack.SameOriginTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa(ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:p.protocol+"//"+p.host+p.pathname,xdm_c:Y.channel,xdm_p:4}),name:U+Y.channel+"_provider"});ab=A(Y);o.Fn.set(Y.channel,function(ac){aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}})}else{aa=m().Fn.get(Y.channel,true)(function(ac){Z.up.incoming(ac,X)});K(function(){Z.up.callback(true)},0)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.FlashTransport=function(aa){var ac,X,ab,ad,Y,ae;function af(ah,ag){K(function(){ac.up.incoming(ah,ad)},0)}function Z(ah){var ag=aa.swf+"?host="+aa.isHost;var aj="easyXDM_swf_"+Math.floor(Math.random()*10000);o.Fn.set("flash_loaded"+ah.replace(/[\-.]/g,"_"),function(){o.stack.FlashTransport[ah].swf=Y=ae.firstChild;var ak=o.stack.FlashTransport[ah].queue;for(var al=0;al<ak.length;al++){ak[al]()}ak.length=0});if(aa.swfContainer){ae=(typeof aa.swfContainer=="string")?d.getElementById(aa.swfContainer):aa.swfContainer}else{ae=d.createElement("div");T(ae.style,h&&aa.swfNoThrottle?{height:"20px",width:"20px",position:"fixed",right:0,top:0}:{height:"1px",width:"1px",position:"absolute",overflow:"hidden",right:0,top:0});d.body.appendChild(ae)}var ai="callback=flash_loaded"+ah.replace(/[\-.]/g,"_")+"&proto="+b.location.protocol+"&domain="+z(b.location.href)+"&port="+f(b.location.href)+"&ns="+I;ae.innerHTML="<object height='20' width='20' type='application/x-shockwave-flash' id='"+aj+"' data='"+ag+"'><param name='allowScriptAccess' value='always'></param><param name='wmode' value='transparent'><param name='movie' value='"+ag+"'></param><param name='flashvars' value='"+ai+"'></param><embed type='application/x-shockwave-flash' FlashVars='"+ai+"' allowScriptAccess='always' wmode='transparent' src='"+ag+"' height='1' width='1'></embed></object>"}return(ac={outgoing:function(ah,ai,ag){Y.postMessage(aa.channel,ah.toString());if(ag){ag()}},destroy:function(){try{Y.destroyChannel(aa.channel)}catch(ag){}Y=null;if(X){X.parentNode.removeChild(X);X=null}},onDOMReady:function(){ad=aa.remote;o.Fn.set("flash_"+aa.channel+"_init",function(){K(function(){ac.up.callback(true)})});o.Fn.set("flash_"+aa.channel+"_onMessage",af);aa.swf=B(aa.swf);var ah=z(aa.swf);var ag=function(){o.stack.FlashTransport[ah].init=true;Y=o.stack.FlashTransport[ah].swf;Y.createChannel(aa.channel,aa.secret,j(aa.remote),aa.isHost);if(aa.isHost){if(h&&aa.swfNoThrottle){T(aa.props,{position:"fixed",right:0,top:0,height:"20px",width:"20px"})}T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:6,xdm_s:aa.secret}),name:U+aa.channel+"_provider"});X=A(aa)}};if(o.stack.FlashTransport[ah]&&o.stack.FlashTransport[ah].init){ag()}else{if(!o.stack.FlashTransport[ah]){o.stack.FlashTransport[ah]={queue:[ag]};Z(ah)}else{o.stack.FlashTransport[ah].queue.push(ag)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.PostMessageTransport=function(aa){var ac,ad,Y,Z;function X(ae){if(ae.origin){return j(ae.origin)}if(ae.uri){return j(ae.uri)}if(ae.domain){return p.protocol+"//"+ae.domain}throw"Unable to retrieve the origin of the event"}function ab(af){var ae=X(af);if(ae==Z&&af.data.substring(0,aa.channel.length+1)==aa.channel+" "){ac.up.incoming(af.data.substring(aa.channel.length+1),ae)}}return(ac={outgoing:function(af,ag,ae){Y.postMessage(aa.channel+" "+af,ag||Z);if(ae){ae()}},destroy:function(){x(N,"message",ab);if(ad){Y=null;ad.parentNode.removeChild(ad);ad=null}},onDOMReady:function(){Z=j(aa.remote);if(aa.isHost){var ae=function(af){if(af.data==aa.channel+"-ready"){Y=("postMessage" in ad.contentWindow)?ad.contentWindow:ad.contentWindow.document;x(N,"message",ae);v(N,"message",ab);K(function(){ac.up.callback(true)},0)}};v(N,"message",ae);T(aa.props,{src:P(aa.remote,{xdm_e:j(p.href),xdm_c:aa.channel,xdm_p:1}),name:U+aa.channel+"_provider"});ad=A(aa)}else{v(N,"message",ab);Y=("postMessage" in N.parent)?N.parent:N.parent.document;Y.postMessage(aa.channel+"-ready",Z);K(function(){ac.up.callback(true)},0)}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.FrameElementTransport=function(Y){var Z,ab,aa,X;return(Z={outgoing:function(ad,ae,ac){aa.call(this,ad);if(ac){ac()}},destroy:function(){if(ab){ab.parentNode.removeChild(ab);ab=null}},onDOMReady:function(){X=j(Y.remote);if(Y.isHost){T(Y.props,{src:P(Y.remote,{xdm_e:j(p.href),xdm_c:Y.channel,xdm_p:5}),name:U+Y.channel+"_provider"});ab=A(Y);ab.fn=function(ac){delete ab.fn;aa=ac;K(function(){Z.up.callback(true)},0);return function(ad){Z.up.incoming(ad,X)}}}else{if(d.referrer&&j(d.referrer)!=S.xdm_e){N.top.location=S.xdm_e}aa=N.frameElement.fn(function(ac){Z.up.incoming(ac,X)});Z.up.callback(true)}},init:function(){G(Z.onDOMReady,Z)}})};o.stack.NameTransport=function(ab){var ac;var ae,ai,aa,ag,ah,Y,X;function af(al){var ak=ab.remoteHelper+(ae?"#_3":"#_2")+ab.channel;ai.contentWindow.sendMessage(al,ak)}function ad(){if(ae){if(++ag===2||!ae){ac.up.callback(true)}}else{af("ready");ac.up.callback(true)}}function aj(ak){ac.up.incoming(ak,Y)}function Z(){if(ah){K(function(){ah(true)},0)}}return(ac={outgoing:function(al,am,ak){ah=ak;af(al)},destroy:function(){ai.parentNode.removeChild(ai);ai=null;if(ae){aa.parentNode.removeChild(aa);aa=null}},onDOMReady:function(){ae=ab.isHost;ag=0;Y=j(ab.remote);ab.local=B(ab.local);if(ae){o.Fn.set(ab.channel,function(al){if(ae&&al==="ready"){o.Fn.set(ab.channel,aj);ad()}});X=P(ab.remote,{xdm_e:ab.local,xdm_c:ab.channel,xdm_p:2});T(ab.props,{src:X+"#"+ab.channel,name:U+ab.channel+"_provider"});aa=A(ab)}else{ab.remoteHelper=ab.remote;o.Fn.set(ab.channel,aj)}var ak=function(){var al=ai||this;x(al,"load",ak);o.Fn.set(ab.channel+"_load",Z);(function am(){if(typeof al.contentWindow.sendMessage=="function"){ad()}else{K(am,50)}}())};ai=A({props:{src:ab.local+"#_4"+ab.channel},onLoad:ak})},init:function(){G(ac.onDOMReady,ac)}})};o.stack.HashTransport=function(Z){var ac;var ah=this,af,aa,X,ad,am,ab,al;var ag,Y;function ak(ao){if(!al){return}var an=Z.remote+"#"+(am++)+"_"+ao;((af||!ag)?al.contentWindow:al).location=an}function ae(an){ad=an;ac.up.incoming(ad.substring(ad.indexOf("_")+1),Y)}function aj(){if(!ab){return}var an=ab.location.href,ap="",ao=an.indexOf("#");if(ao!=-1){ap=an.substring(ao)}if(ap&&ap!=ad){ae(ap)}}function ai(){aa=setInterval(aj,X)}return(ac={outgoing:function(an,ao){ak(an)},destroy:function(){N.clearInterval(aa);if(af||!ag){al.parentNode.removeChild(al)}al=null},onDOMReady:function(){af=Z.isHost;X=Z.interval;ad="#"+Z.channel;am=0;ag=Z.useParent;Y=j(Z.remote);if(af){T(Z.props,{src:Z.remote,name:U+Z.channel+"_provider"});if(ag){Z.onLoad=function(){ab=N;ai();ac.up.callback(true)}}else{var ap=0,an=Z.delay/50;(function ao(){if(++ap>an){throw new Error("Unable to reference listenerwindow")}try{ab=al.contentWindow.frames[U+Z.channel+"_consumer"]}catch(aq){}if(ab){ai();ac.up.callback(true)}else{K(ao,50)}}())}al=A(Z)}else{ab=N;ai();if(ag){al=parent;ac.up.callback(true)}else{T(Z,{props:{src:Z.remote+"#"+Z.channel+new Date(),name:U+Z.channel+"_consumer"},onLoad:function(){ac.up.callback(true)}});al=A(Z)}}},init:function(){G(ac.onDOMReady,ac)}})};o.stack.ReliableBehavior=function(Y){var aa,ac;var ab=0,X=0,Z="";return(aa={incoming:function(af,ad){var ae=af.indexOf("_"),ag=af.substring(0,ae).split(",");af=af.substring(ae+1);if(ag[0]==ab){Z="";if(ac){ac(true);ac=null}}if(af.length>0){aa.down.outgoing(ag[1]+","+ab+"_"+Z,ad);if(X!=ag[1]){X=ag[1];aa.up.incoming(af,ad)}}},outgoing:function(af,ad,ae){Z=af;ac=ae;aa.down.outgoing(X+","+(++ab)+"_"+af,ad)}})};o.stack.QueueBehavior=function(Z){var ac,ad=[],ag=true,aa="",af,X=0,Y=false,ab=false;function ae(){if(Z.remove&&ad.length===0){w(ac);return}if(ag||ad.length===0||af){return}ag=true;var ah=ad.shift();ac.down.outgoing(ah.data,ah.origin,function(ai){ag=false;if(ah.callback){K(function(){ah.callback(ai)},0)}ae()})}return(ac={init:function(){if(t(Z)){Z={}}if(Z.maxLength){X=Z.maxLength;ab=true}if(Z.lazy){Y=true}else{ac.down.init()}},callback:function(ai){ag=false;var ah=ac.up;ae();ah.callback(ai)},incoming:function(ak,ai){if(ab){var aj=ak.indexOf("_"),ah=parseInt(ak.substring(0,aj),10);aa+=ak.substring(aj+1);if(ah===0){if(Z.encode){aa=k(aa)}ac.up.incoming(aa,ai);aa=""}}else{ac.up.incoming(ak,ai)}},outgoing:function(al,ai,ak){if(Z.encode){al=H(al)}var ah=[],aj;if(ab){while(al.length!==0){aj=al.substring(0,X);al=al.substring(aj.length);ah.push(aj)}while((aj=ah.shift())){ad.push({data:ah.length+"_"+aj,origin:ai,callback:ah.length===0?ak:null})}}else{ad.push({data:al,origin:ai,callback:ak})}if(Y){ac.down.init()}else{ae()}},destroy:function(){af=true;ac.down.destroy()}})};o.stack.VerifyBehavior=function(ab){var ac,aa,Y,Z=false;function X(){aa=Math.random().toString(16).substring(2);ac.down.outgoing(aa)}return(ac={incoming:function(af,ad){var ae=af.indexOf("_");if(ae===-1){if(af===aa){ac.up.callback(true)}else{if(!Y){Y=af;if(!ab.initiate){X()}ac.down.outgoing(af)}}}else{if(af.substring(0,ae)===Y){ac.up.incoming(af.substring(ae+1),ad)}}},outgoing:function(af,ad,ae){ac.down.outgoing(aa+"_"+af,ad,ae)},callback:function(ad){if(ab.initiate){X()}}})};o.stack.RpcBehavior=function(ad,Y){var aa,af=Y.serializer||O();var ae=0,ac={};function X(ag){ag.jsonrpc="2.0";aa.down.outgoing(af.stringify(ag))}function ab(ag,ai){var ah=Array.prototype.slice;return function(){var aj=arguments.length,al,ak={method:ai};if(aj>0&&typeof arguments[aj-1]==="function"){if(aj>1&&typeof arguments[aj-2]==="function"){al={success:arguments[aj-2],error:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-2)}else{al={success:arguments[aj-1]};ak.params=ah.call(arguments,0,aj-1)}ac[""+(++ae)]=al;ak.id=ae}else{ak.params=ah.call(arguments,0)}if(ag.namedParams&&ak.params.length===1){ak.params=ak.params[0]}X(ak)}}function Z(an,am,ai,al){if(!ai){if(am){X({id:am,error:{code:-32601,message:"Procedure not found."}})}return}var ak,ah;if(am){ak=function(ao){ak=q;X({id:am,result:ao})};ah=function(ao,ap){ah=q;var aq={id:am,error:{code:-32099,message:ao}};if(ap){aq.error.data=ap}X(aq)}}else{ak=ah=q}if(!r(al)){al=[al]}try{var ag=ai.method.apply(ai.scope,al.concat([ak,ah]));if(!t(ag)){ak(ag)}}catch(aj){ah(aj.message)}}return(aa={incoming:function(ah,ag){var ai=af.parse(ah);if(ai.method){if(Y.handle){Y.handle(ai,X)}else{Z(ai.method,ai.id,Y.local[ai.method],ai.params)}}else{var aj=ac[ai.id];if(ai.error){if(aj.error){aj.error(ai.error)}}else{if(aj.success){aj.success(ai.result)}}delete ac[ai.id]}},init:function(){if(Y.remote){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)){ad[ag]=ab(Y.remote[ag],ag)}}}aa.down.init()},destroy:function(){for(var ag in Y.remote){if(Y.remote.hasOwnProperty(ag)&&ad.hasOwnProperty(ag)){delete ad[ag]}}aa.down.destroy()}})};b.easyXDM=o})(window,document,location,window.setTimeout,decodeURIComponent,encodeURIComponent);
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf b/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf
new file mode 100644
index 0000000..0a82005
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/easyxdm.swf
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/blank.html b/asterix-examples/src/main/resources/js/easyXDM/example/blank.html
new file mode 100644
index 0000000..33b64d6
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/blank.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+    <head>
+        <title>Blank page</title>
+		</head>
+		<body>
+        This page will be replaced with the actuall content in just a jiffy.. 
+		</body>
+</html>		
+		
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html
new file mode 100644
index 0000000..2da7a2c
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+        <title></title>
+    </head>
+    <body>
+        <img src="../tests/s.gif" />
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+                document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+            }
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+        <a id="bookmark" src="">Bookmark</a>
+        <script type="text/javascript">
+            var baseUrl = location.href.substring(0, location.href.lastIndexOf("/"));
+            
+            // to simplify development, we create the bookmarklet as a regular function
+            function bookmark(){
+                if (typeof myBookmark === "undefined") {
+                    var script = document.createElement("script");
+                    script.type = "text/javascript";
+                    script.src = baseUrl + "/bookmark.js";
+                    document.getElementsByTagName("head")[0].appendChild(script);
+                }
+                else {
+                    myBookmark.run();
+                }
+            }
+            
+            // and then we include it using .toString().
+            document.getElementById("bookmark").href = 'javascript:(' +
+            (bookmark.toString().replace('baseUrl + "', '"' + baseUrl)).replace(/\s+/g, " ") +
+            ')();';
+            // when finished, you just copy the url from the rendered page
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js
new file mode 100644
index 0000000..7f0d0ff
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bookmark.js
@@ -0,0 +1,74 @@
+var myBookmark = (function(){
+    var s1, s2, isLoaded = false, xhr, head = document.getElementsByTagName('head')[0];
+    var scripts = document.getElementsByTagName("script");
+    var REMOTE = (function(){
+        var remote = location.href;
+        switch (location.host) {
+            case "provider.easyxdm.net":
+                location.href = remote.replace("provider", "consumer");
+                break;
+            case "xdm1":
+                remote = remote.replace("xdm1", "xdm2");
+                break;
+            default:
+                remote = "http://provider.easyxdm.net/current/example/";
+        }
+        return remote.substring(0, remote.lastIndexOf("/"));
+    }());
+    
+    function run(){
+        if (typeof xhr === "undefined") {
+            return;
+        }
+        xhr.post("example/glossary.php", {
+            param1: "a",
+            param2: "b"
+        }, function(json){
+            alert(json.glossary.title);
+        });
+    }
+    
+    function scriptOnLoad(){
+        if (isLoaded || typeof easyXDM === "undefined" || typeof JSON === "undefined") {
+            return;
+        }
+        isLoaded = true;
+        xhr = new easyXDM.Rpc({
+            remote: REMOTE + "/../xhr.html",
+            onReady: function(){
+                run();
+            }
+        }, {
+            remote: {
+                post: {}
+            }
+        });
+        
+    }
+    s1 = document.createElement("script");
+    s1.type = "text/javascript";
+    s1.src = REMOTE + "/../easyXDM.debug.js";
+    s1.onreadystatechange = function(){
+        if (this.readyState === "complete" || this.readyState === "loaded") {
+            scriptOnLoad();
+        }
+    };
+    s1.onload = scriptOnLoad;
+    head.appendChild(s1);
+    
+    if (typeof JSON === "undefined" || !JSON) {
+        s2 = document.createElement("script");
+        s2.type = "text/javascript";
+        s2.src = REMOTE + "/../json2.js";
+        s2.onreadystatechange = function(){
+            if (this.readyState === "complete" || this.readyState === "loaded") {
+                scriptOnLoad();
+            }
+        };
+        s2.onload = scriptOnLoad;
+        head.appendChild(s2);
+    }
+    return {
+        run: run
+    };
+})();
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html b/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html
new file mode 100644
index 0000000..af840e8
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/bridge.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            /* Here we demo how to have two visible web applications communicate together.
+             * This is done by having the remote interface open a visible window and loading
+             * the application in this.
+             * Since the remote interface has access to the entire DOM (including javascript)
+             * of the opened window, the remote interface is able to interface freely with the
+             * remote web application and can serve as a bridge between the two applications.
+             */
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            
+            
+            
+            var proxy, win;
+            function openPopup(){
+                if (win) {
+                    // this allows to open new windows if the popup was closed
+                    if (win.closed) {
+                        win = window.open(REMOTE + '/blank.html', 'mainapp', "width=400, height=400");
+                        proxy.open("mainapp");
+                    }
+                    return;
+                }
+                // open up the popup 
+                win = window.open(REMOTE + '/blank.html', 'mainapp', "width=400, height=400");
+                
+                document.getElementById("btn").disabled = "";
+                
+                proxy = new easyXDM.Rpc(/** The configuration */{
+                    /**
+                     * Register the url to name.html, this must be an absolute path
+                     * or a path relative to the root.
+                     * @field
+                     */
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    /**
+                     * Register the url to the remote interface
+                     * @field
+                     */
+                    remote: REMOTE + "/remote.html",
+                    remoteHelper: REMOTE + "/../name.html"
+                }, {
+                    remote: {
+                        open: {},
+                        postMessage: {}
+                    },
+                    local: {
+                        /**
+                         * Register the method that should handle incoming data
+                         * @param {Object} data
+                         * @param {String} origin
+                         */
+                        postMessage: function(data){
+                            var div = document.createElement("div");
+                            div.innerHTML = "data from '" + proxy.origin + "'";
+                            document.body.appendChild(div);
+                            for (var key in data) {
+                                if (data.hasOwnProperty(key)) {
+                                    div = document.createElement("div");
+                                    div.innerHTML = key + "=" + data[key];
+                                    document.body.appendChild(div);
+                                }
+                            }
+                        }
+                    }
+                });
+                
+                // lets tell the proxy to open up the window as soon as possible
+                proxy.open("mainapp");
+            }
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <input id="btnOpen" type="button" onclick="openPopup();" value="Open popup"/><!-- Send som data to the other side --><input id="btn" disabled="disabled" type="button" onclick="proxy.postMessage({a:'b',c:'d',e:'f'});" value="send data to remote"/>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/data.html b/asterix-examples/src/main/resources/js/easyXDM/example/data.html
new file mode 100644
index 0000000..47eaeed
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/data.html
@@ -0,0 +1,133 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var serializer = {
+                /**
+                 * Serializes a hashtable and returns it as a string
+                 * @param {Object} data The data to serialize
+                 * @returns The serialized string
+                 * @type {String}
+                 */
+                stringify: function(data){
+                    var message = "";
+                    for (var key in data) {
+                        if (data.hasOwnProperty(key)) {
+                            message += key + "=" + escape(data[key]) + "&";
+                        }
+                    }
+                    return message.substring(0, message.length - 1);
+                },
+                /**
+                 * Deserializes a string and returns a hashtable
+                 * @param {String} message The string to deserialize
+                 * @returns An hashtable populated with key-value pairs
+                 * @type {Object}
+                 */
+                parse: function(message){
+                    var data = {};
+                    var d = message.split("&");
+                    var pair, key, value;
+                    for (var i = 0, len = d.length; i < len; i++) {
+                        pair = d[i];
+                        key = pair.substring(0, pair.indexOf("="));
+                        value = pair.substring(key.length + 1);
+                        data[key] = unescape(value);
+                    }
+                    return data;
+                }
+            };
+            
+            var channel;
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            window.onload = function(){
+                /**
+                 * When the window is finished loading start setting up the channel
+                 */
+                channel = new easyXDM.Socket(/** The configuration */{
+                    /**
+                     * Register the url to hash.html, this must be an absolute path
+                     * or a path relative to the root.
+                     * @field
+                     */
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    /**
+                     * Register the url to the remote interface
+                     * @field
+                     */
+                    remote: REMOTE + "/remotedata.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    onReady: function(){
+                        /**
+                         * Send some data to the other side
+                         */
+                        channel.postMessage(serializer.stringify({
+                            propA: "abc",
+                            propB: "def",
+                            propC: 44
+                        }));
+                    }
+                });
+            };
+        </script>
+    </head>
+    <body>
+    <div style="border:1px solid black;padding:3px;margin:10px;">
+        <a href="index.html">Index of examples</a>
+        | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+        | 
+        | <a href="http://easyxdm.net/">easyXDM.net</a>
+        | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+        <br/>
+        The examples are executing slower than the production build due to the extensive tracing.
+        <br/>
+        If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+    </div>
+    <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+    <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+    </div>
+    </div>
+    <br/>
+    <br/>
+    <input type="text" id="code" size="100" value="channel.postMessage(serializer.stringify({propC:'c',procD:'d',propE:88}))"/>
+    <button onclick="eval(document.getElementById('code').value);">
+        eval code
+    </button>
+    <script type="text/javascript">
+        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script>
+    <script type="text/javascript">
+        if (location.host.indexOf("easyxdm.net") !== -1) {
+            try {
+                var pageTracker = _gat._getTracker("UA-9535591-3");
+                pageTracker._setDomainName(".easyxdm.net");
+                pageTracker._trackPageview();
+            } 
+            catch (err) {
+            }
+        }
+    </script>
+</body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx b/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx
new file mode 100644
index 0000000..c815101
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/glossary.aspx
@@ -0,0 +1,29 @@
+﻿<%
+    Response.ContentType = "application/json"
+    Response.AddHeader("x-foo", "bar")
+    Response.AddHeader("Access-Control-Allow-Origin", "http://xdm4")
+    Response.AddHeader("Access-Control-Allow-Methods", "POST")
+
+%>
+{
+    "glossary": {
+        "title": "example glossary",
+        "GlossDiv": {
+            "title": "S",
+            "GlossList": {
+                "GlossEntry": {
+                    "ID": "SGML",
+                    "SortAs": "SGML",
+                    "GlossTerm": "Standard Generalized Markup Language",
+                    "Acronym": "SGML",
+                    "Abbrev": "ISO 8879:1986",
+                    "GlossDef": {
+                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
+                        "GlossSeeAlso": ["GML", "XML"]
+                    },
+                    "GlossSee": "markup"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/index.html b/asterix-examples/src/main/resources/js/easyXDM/example/index.html
new file mode 100644
index 0000000..3690577
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/index.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <ul>
+        	<li>
+                <a href="transport.html">Transport</a>
+                <br/>
+                Example of passing a string message from one domain to another using the Socket.
+            </li>
+            <li>
+                <a href="data.html">Data</a>
+                <br/>
+                Example of passing data using a Socket and a custom serializer/deserializer.
+            </li>
+            <li>
+                <a href="methods.html">Methods</a>
+                <br/>
+                Example of using the Rpc object for executing Remote Procedure Calls with arguments and having results returned.
+            </li>
+            <li>
+                <a href="resize_iframe.html">Resize iframe</a>
+                <br/>
+                Example on how to use easyXDM to automatically resize an iframe. This uses an intermediate frame to enable navigation of the contained document
+            </li>
+            <li>
+                <a href="upload.html">Upload</a>
+                <br/>
+                Example on how to facilitate 'cross domain AJAX upload'. 
+            </li>
+            <li>
+                <a href="widgets.html">Widgets</a>
+                <br/>
+                Example on how to use easyXDM to build a framework for widgets using a pub/sub schema.
+            </li>
+            <li>
+                <a href="xhr.html">XHR</a>
+                <br/>
+                Example of using the shipped /cors/ endpoint to retrieve resources across the domain boundary.
+            </li>
+            <li>
+                <a href="bridge.html">Bridge</a>
+                <br/>
+                Experimental example of how to 'bridge' two web apps together. 
+            </li>
+        </ul>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/methods.html b/asterix-examples/src/main/resources/js/easyXDM/example/methods.html
new file mode 100644
index 0000000..9bbd15a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/methods.html
@@ -0,0 +1,148 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            var remote = new easyXDM.Rpc(/** The channel configuration */{
+                /**
+                 * Register the url to hash.html, this must be an absolute path
+                 * or a path relative to the root.
+                 * @field
+                 */
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                /**
+                 * Register the url to the remote interface
+                 * @field
+                 */
+                remote: REMOTE + "/remotemethods.html",
+                remoteHelper: REMOTE + "/../name.html",
+                /**
+                 * Register the DOMElement that the generated IFrame should be inserted into
+                 */
+                container: "embedded",
+                props: {
+                    style: {
+                        border: "2px dotted red",
+                        height: "200px"
+                    }
+                },
+                onReady: function(){
+                    /**
+                     * Call a method on the other side
+                     */
+                    remote.noOp();
+                }
+            }, /** The interface configuration */ {
+                remote: {
+                    addNumbers: {},
+                    multiplyNumbers: {},
+                    noOp: {}
+                },
+                local: {
+                    alertMessage: function(msg){
+                        alert(msg);
+                    }
+                }
+            });
+            
+            function add(a, b){
+                remote.addNumbers(a, b, function(result){
+                    alert(a + " + " + b + " = " + result);
+                });
+            }
+            
+            function multiply(a, b){
+                remote.multiplyNumbers(a, b, function(result){
+                    alert(a + " x " + b + " = " + result);
+                });
+            }
+        </script>
+        <style type="text/css">
+            
+            #embedded iframe {
+                width: 100%;
+                height: 100%;
+            }
+        </style>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <div>
+            The remote implementation is synchronous and will return immediately
+            <br/>
+            <input type="button" onclick="add(3,5);" value="call addNumbers on remote domain"/>
+            <br/>
+            <br/>
+            The remote implementation of multiplyNumbers is asynchronous and will return after 5seconds
+            <br/>
+            This shows that you can use async calls in the remote method, eg. XHR calls
+            <br/>
+            <input type="button" onclick="multiply(3,5);" value="call multiplyNumbers on remote domain"/>
+            <br/>
+            <br/>
+            This calls a non-returning method on the remote side
+            <br/>
+            <input type="button" onclick="remote.noOp();" value="call noOp on the remote domain"/>
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remote.html b/asterix-examples/src/main/resources/js/easyXDM/example/remote.html
new file mode 100644
index 0000000..ad82e8a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remote.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var win, remoteapp; // reference to the popups window
+            var proxy = new easyXDM.Rpc(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, {
+                local: {
+                    /**
+                     * This is used to open up the popup. A popup with the given name should already be opened
+                     * in the user click handler.
+                     */
+                    open: function(name){
+                        remoteapp = null;
+                        // we now open the window, passing the name of this window (includes the channel name)
+                        // in case it has to look us up using the framename
+                        win = window.open('remoteapp.html' + '#easyXDM_' + easyXDM.query.xdm_c + '_provider', name, "width=400, height=400");
+                    },
+                    /**
+                     * This is where we receive the data
+                     * @param {Object} data The data
+                     */
+                    postMessage: function(data){
+                        if (win.closed) {
+                            alert("the popup has been closed - please open it again");
+                            return;
+                        }
+                        var div = remoteapp.document.createElement("div");
+                        div.innerHTML = "data from '" + proxy.origin + "'";
+                        if (remoteapp) {
+                            remoteapp.document.body.appendChild(div);
+                            for (var key in data) {
+                                if (data.hasOwnProperty(key)) {
+                                    div = remoteapp.document.createElement("div");
+                                    div.innerHTML = key + "=" + data[key];
+                                    remoteapp.document.body.appendChild(div);
+                                }
+                            }
+                            remoteapp.focus();
+                        }
+                    }
+                },
+                remote: {
+                    postMessage: {}
+                }
+            });
+            
+            
+            /**
+             * The popup must use this window to register itself
+             * @param {DOMWindow} app The window object of the popup
+             */
+            function setApp(app){
+                remoteapp = app;
+            }
+            
+            /**
+             * The popup must use this method to send data. This clones the object in order to
+             * work around a but in IE
+             * @param {Object} data The data to send
+             */
+            function sendData(data){
+                var copy = {};
+                // copy the object in order to avoid the JSON serialization bug
+                easyXDM.apply(copy, data);
+                proxy.postMessage(copy);
+            }
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html b/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html
new file mode 100644
index 0000000..e493b68
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remoteapp.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript">
+            var target = location.hash.substring(1);
+            
+            var host = window.opener.frames[target];
+            
+            if (window.opener) {
+                try {
+                    // test if we have access to the document 
+                    if (window.opener.document.title) {
+                        host = window.opener;
+                    }
+                    
+                } 
+                catch (xDomainError) {
+                    // we have an opener, but it's not on our domain, 
+                    host = window.opener.frames[target];
+                }
+                
+                if (host) {
+                    try {
+                        host.setApp(window);
+                    } 
+                    catch (browserHostError) {
+                        alert("was unable to gain a reference to the iframe");
+                    }
+                }
+            }
+        </script>
+    </head>
+    <body>
+        <!-- Send some data to the other side using the proxy --><input type="button" onclick="host.sendData({a:'b',c:'d',e:'f'});" value="send data to local"/>
+    </body>
+</html>
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html
new file mode 100644
index 0000000..814355c
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotedata.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var serializer = {
+                /**
+                 * Serializes a hashtable and returns it as a string
+                 * @param {Object} data The data to serialize
+                 * @returns The serialized string
+                 * @type {String}
+                 */
+                stringify: function(data){
+                    var message = "";
+                    for (var key in data) {
+                        if (data.hasOwnProperty(key)) {
+                            message += key + "=" + escape(data[key]) + "&";
+                        }
+                    }
+                    return message.substring(0, message.length - 1);
+                },
+                /**
+                 * Deserializes a string and returns a hashtable
+                 * @param {String} message The string to deserialize
+                 * @returns An hashtable populated with key-value pairs
+                 * @type {Object}
+                 */
+                parse: function(message){
+                    var data = {};
+                    var d = message.split("&");
+                    var pair, key, value;
+                    for (var i = 0, len = d.length; i < len; i++) {
+                        pair = d[i];
+                        key = pair.substring(0, pair.indexOf("="));
+                        value = pair.substring(key.length + 1);
+                        data[key] = unescape(value);
+                    }
+                    return data;
+                }
+            };
+            
+            var socket = new easyXDM.Socket(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf",
+                /**
+                 * Register the method that should handle incoming data
+                 * @param {Object} data
+                 * @param {String} origin
+                 */
+                onMessage: function(data, origin){
+                    data = serializer.parse(data);
+                    alert("Received data from '" + origin + "':");
+                    for (var key in data) {
+                        alert("Property '" + key + "'=" + data[key]);
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html
new file mode 100644
index 0000000..2ea8c1f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotemethods.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc(/** The channel configuration*/{
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, /** The configuration */ {
+                remote: {
+                    alertMessage: {}
+                },
+                local: {
+                    addNumbers: function(a, b){
+                        return a + b;
+                    },
+                    multiplyNumbers: function(a, b, fn){
+                        window.setTimeout(function(){
+                            fn(a * b);
+                        }, 5000);
+                    },
+                    noOp: function(){
+                        alert("Method not returning any data");
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <input type="button" onclick="remote.alertMessage('message from remote');" value="call alertMessage on local domain"/>
+    </body>
+</html>
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html b/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html
new file mode 100644
index 0000000..59a411a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remoterpcbackend.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc(/** The channel configuration*/{
+                local: "../name.html"
+            }, /** The configuration */ {
+                /**
+                 *
+                 * @param {Object} rpc A JSON-RPC 2.0 request object
+                 * @param {Function} reply The callback method. Takes a single JSON-RPC 2.0 response object.
+                 */
+                handle: function(rpc, reply){
+                    alert("requested to execute procedure '" + rpc.method + "'");
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html b/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html
new file mode 100644
index 0000000..64093a7
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/remotetransport.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var transport = new easyXDM.Socket(/** The configuration */{
+                local: "../name.html",
+                swf: "../easyxdm.swf",
+                /**
+                 * Register the method that should handle incoming messages
+                 * @param {String} data
+                 * @param {String} origin
+                 */
+                onMessage: function(message, origin){
+                    alert("Received '" + message + "' from '" + origin + "'");
+                }
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html b/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html
new file mode 100644
index 0000000..e0b0adb
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resize_iframe.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            var transport = new easyXDM.Socket(/** The configuration */{
+                remote: REMOTE + "/resize_intermediate.html?url=resized_iframe_1.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                container: "embedded",
+                onMessage: function(message, origin){
+                    this.container.getElementsByTagName("iframe")[0].style.height = message + "px";
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html b/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html
new file mode 100644
index 0000000..8b5f03e
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resize_intermediate.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js"></script>
+        <script type="text/javascript">
+            var iframe;
+            var socket = new easyXDM.Socket({
+                swf : "../easyxdm.swf",
+                onReady : function() {
+                    iframe = document.createElement("iframe");
+                    iframe.frameBorder = 0;
+                    document.body.appendChild(iframe);
+                    iframe.src = easyXDM.query.url;
+
+                    var timer;
+                    iframe.onload = function() {
+                        var d = iframe.contentWindow.document;
+                        var originalHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;
+
+                        // We want to monitor the document for resize events in case of the use of accordions and such,
+                        // but unfortunately only the window node emits the resize event, and we need the body's.
+                        // The only solution then is to use polling..
+
+                        // Lets start the polling if not all ready started
+                        if(!timer) {
+                            timer = setInterval(function() {
+                                try {
+                                    var d = iframe.contentWindow.document;
+                                    var newHeight = d.body.clientHeight || d.body.offsetHeight || d.body.scrollHeight;
+                                    if(newHeight != originalHeight) {
+                                        // The height has changed since last we checked
+                                        originalHeight = newHeight;
+                                        socket.postMessage(originalHeight);
+                                    }
+                                } catch(e) {
+                                    // We tried to read the property at some point when it wasn't available
+                                }
+                            }, 300);
+                        }
+                        // Send the first message
+                        socket.postMessage(originalHeight);
+                    };
+                },
+                onMessage : function(url, origin) {
+                    iframe.src = url;
+                }
+            });
+
+        </script>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                width: 100%;
+                height: 100%;
+            }
+            iframe {
+                width: 100%;
+                height: 100%;
+                border: 0px;
+            }
+        </style>
+    </head>
+    <body></body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html
new file mode 100644
index 0000000..8b4b7ad
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_1.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                background-color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <a href="resized_iframe_2.html">resized_iframe_2.html</a>
+        <br/>
+        Nam nulla nibh, tempus ut dictum eget, euismod vitae metus. Donec vitae nulla nec quam sagittis gravida vel quis eros. Nullam vel est justo. Donec euismod interdum magna, et rutrum libero tincidunt vel. Praesent imperdiet, magna et suscipit facilisis, nulla justo consequat nisl, et mollis elit nunc a est. Sed felis quam, condimentum eget gravida non, semper non quam. Duis vestibulum sem id erat tristique eleifend. Phasellus ante nunc, pulvinar nec facilisis at, hendrerit sed leo. Morbi lacinia nisl id nunc faucibus lacinia. Curabitur adipiscing leo a odio aliquet hendrerit. Nullam laoreet pulvinar suscipit.
+        Cras ante tortor, rutrum non pharetra vel, tempor et velit. Mauris semper, libero sit amet interdum interdum, metus purus rutrum libero, eget suscipit lectus augue eu magna. Aliquam quis dui a nunc luctus faucibus. Sed viverra augue rutrum odio placerat laoreet. Nulla scelerisque augue nec enim condimentum sollicitudin. Proin accumsan, turpis in viverra lobortis, nulla mauris euismod turpis, sit amet auctor felis lacus sed leo. Nullam posuere bibendum urna, ut mattis eros varius ac. Mauris sed metus orci, ut lobortis eros. Sed imperdiet bibendum tincidunt. Donec adipiscing sapien vitae ligula faucibus quis auctor nisi pretium. Morbi at nulla quam, in aliquet quam. Suspendisse potenti. Fusce varius gravida egestas. Nulla lectus velit, posuere et auctor a, congue id massa. Quisque ut lectus eu metus malesuada sollicitudin ac a risus.
+        Nullam massa ipsum, pulvinar ut facilisis a, commodo ut orci. Mauris ac ipsum diam, sit amet laoreet tortor. In pretium, nulla vel ornare euismod, nibh augue pharetra magna, at semper felis diam in ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus blandit ornare dignissim. Fusce et nulla urna. Morbi nec ante erat. Nullam ut urna libero. Nulla non ipsum purus, et cursus lectus. Etiam vehicula, mauris in faucibus vehicula, dolor quam sodales neque, sed laoreet est augue at lacus. Nunc tincidunt lacinia elit eu dignissim. Mauris at enim mauris. Donec congue auctor dui, eget posuere ante accumsan in. Nulla non quam enim, eget tempor arcu. Suspendisse nec nibh diam, ut congue est. Fusce at urna eget velit posuere ornare nec eget mauris. Sed accumsan magna et enim mollis dignissim.
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html
new file mode 100644
index 0000000..7c4085d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/resized_iframe_2.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <style type="text/css">
+            html, body {
+                overflow: hidden;
+                margin: 0px;
+                padding: 0px;
+                background-color: red;
+            }
+        </style>
+    </head>
+    <body>
+        <a href="resized_iframe_1.html">resized_iframe_1.html</a>
+        <br/>
+        (This page will resize its content after three seconds)
+        <br/>
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eu felis libero, non ultricies ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in lorem libero. Phasellus malesuada, mauris eget suscipit tristique, dolor dui blandit purus, ut mollis eros dolor et elit. Ut consequat ultrices metus, pretium mattis dui adipiscing vitae. Nunc cursus, sapien vehicula auctor faucibus, enim orci pretium risus, id congue ligula justo sed felis. Proin nec quam justo. Cras tempor odio eget orci lacinia sit amet malesuada leo feugiat. In accumsan tincidunt enim, vitae ultricies arcu egestas in. Nulla rhoncus eros vel ipsum venenatis porta. Suspendisse id erat nec mauris ultricies consectetur id feugiat odio. Vestibulum pretium tristique magna sed ultrices. Suspendisse tortor mauris, facilisis et lobortis quis, suscipit sed est. Sed vitae tortor at lacus pretium blandit. Donec vitae nibh quis orci mollis fringilla. Duis tempus augue nec ipsum euismod elementum.
+        Donec pharetra sem nec lacus posuere et lacinia ligula sollicitudin. Morbi semper commodo posuere. In adipiscing nulla ut urna fermentum vestibulum. Sed consectetur massa non neque facilisis interdum. Quisque semper massa et urna euismod nec fermentum metus feugiat. Morbi tempor commodo enim non lacinia. Aliquam elementum tortor mattis odio congue a egestas lacus bibendum. Integer nec leo massa, a ullamcorper mi. Morbi vitae massa arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
+        Nam nulla nibh, tempus ut dictum eget, euismod vitae metus. Donec vitae nulla nec quam sagittis gravida vel quis eros. Nullam vel est justo. Donec euismod interdum magna, et rutrum libero tincidunt vel. Praesent imperdiet, magna et suscipit facilisis, nulla justo consequat nisl, et mollis elit nunc a est. Sed felis quam, condimentum eget gravida non, semper non quam. Duis vestibulum sem id erat tristique eleifend. Phasellus ante nunc, pulvinar nec facilisis at, hendrerit sed leo. Morbi lacinia nisl id nunc faucibus lacinia. Curabitur adipiscing leo a odio aliquet hendrerit. Nullam laoreet pulvinar suscipit.
+        Cras ante tortor, rutrum non pharetra vel, tempor et velit. Mauris semper, libero sit amet interdum interdum, metus purus rutrum libero, eget suscipit lectus augue eu magna. Aliquam quis dui a nunc luctus faucibus. Sed viverra augue rutrum odio placerat laoreet. Nulla scelerisque augue nec enim condimentum sollicitudin. Proin accumsan, turpis in viverra lobortis, nulla mauris euismod turpis, sit amet auctor felis lacus sed leo. Nullam posuere bibendum urna, ut mattis eros varius ac. Mauris sed metus orci, ut lobortis eros. Sed imperdiet bibendum tincidunt. Donec adipiscing sapien vitae ligula faucibus quis auctor nisi pretium. Morbi at nulla quam, in aliquet quam. Suspendisse potenti. Fusce varius gravida egestas. Nulla lectus velit, posuere et auctor a, congue id massa. Quisque ut lectus eu metus malesuada sollicitudin ac a risus.
+        Nullam massa ipsum, pulvinar ut facilisis a, commodo ut orci. Mauris ac ipsum diam, sit amet laoreet tortor. In pretium, nulla vel ornare euismod, nibh augue pharetra magna, at semper felis diam in ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus blandit ornare dignissim. Fusce et nulla urna. Morbi nec ante erat. Nullam ut urna libero. Nulla non ipsum purus, et cursus lectus. Etiam vehicula, mauris in faucibus vehicula, dolor quam sodales neque, sed laoreet est augue at lacus. Nunc tincidunt lacinia elit eu dignissim. Mauris at enim mauris. Donec congue auctor dui, eget posuere ante accumsan in. Nulla non quam enim, eget tempor arcu. Suspendisse nec nibh diam, ut congue est. Fusce at urna eget velit posuere ornare nec eget mauris. Sed accumsan magna et enim mollis dignissim.
+        <script type="text/javascript">
+            // here we fake an action that would the casue the body's size to mutate.
+            setTimeout(function() {
+                var html = document.body.innerHTML;
+                document.body.innerHTML = html.substring(0, html.length / 2);
+            }, 3000);
+
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/transport.html b/asterix-examples/src/main/resources/js/easyXDM/example/transport.html
new file mode 100644
index 0000000..769feb0
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/transport.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            var transport = new easyXDM.Socket(/** The configuration */{
+                /**
+                 * Register the url to name.html, this must be an absolute path
+                 * or a path relative to the root.
+                 * @field
+                 */
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                /**
+                 * Register the url to the remote interface
+                 * @field
+                 */
+                remote: REMOTE + "/remotetransport.html",
+                remoteHelper: REMOTE + "/../name.html",
+                onReady: function(){
+                    /**
+                     * If we want to do something once the transport is ready then we can place it here
+                     */
+                }
+            });
+            // messages will be buffered until the transport is ready
+            transport.postMessage("This is a message sent from " + location);
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload.html b/asterix-examples/src/main/resources/js/easyXDM/example/upload.html
new file mode 100644
index 0000000..569feb4
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            
+            // this is just some bootstrapping code in order to provide
+            // the correct host name depending on where it is being run.
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            
+            
+            var btn;
+            var remote = new easyXDM.Rpc({
+                remote: REMOTE + "/upload_rpc.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                onReady: function(){
+                    //display the upload form
+                    var frm = document.getElementById("frmUpload");
+                    frm.action = REMOTE + "/upload_handler.aspx";
+                    frm.style.display = "block";
+                    btn = document.getElementById("btnSubmit");
+                    
+                    frm.onsubmit = function(){
+                        btn.disabled = "disabled";
+                    };
+                }
+            }, {
+                local: {
+                    returnUploadResponse: function(response){
+                        // here you should call back into your regular workflow
+                        btn.disabled = null;
+                        alert(response.msg);
+                    }
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <form id="frmUpload" style="display:none" method="POST" target="upload_target" enctype="multipart/form-data">
+            <input type="file" name="upload_file"/><input type="submit" id="btnSubmit" value="Upload file"/>
+        </form><!--
+        tracking code
+        -->
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx b/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx
new file mode 100644
index 0000000..8c652ee
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload_handler.aspx
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+    </head>
+    <body>
+        <script type="text/javascript">
+            // this should be outputted by the server side code 
+            parent.rpc.returnUploadResponse({
+                status: "success",
+                msg: "The upload succeeded!"
+            });
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html b/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html
new file mode 100644
index 0000000..37123ec
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/upload_rpc.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            // the `rpc` object will be referenced by the upload handler
+            var rpc = new easyXDM.Rpc({
+                swf: "../easyxdm.swf"
+            }, {
+                remote: {
+                    returnUploadResponse: {}
+                }
+            });
+        </script>
+    </head>
+    <body>
+        <iframe name="upload_target" src="about:blank">
+        </iframe>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/widget.html b/asterix-examples/src/main/resources/js/easyXDM/example/widget.html
new file mode 100644
index 0000000..5093eeb
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/widget.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM.Widget</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript" src="../easyXDM.Widgets.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.whenReady(function(){
+                var widget = new easyXDM.Widget({
+                    subscriptions: ["testtopic"],
+                    swf: "../easyxdm.swf",
+                    initialize: function(widget, widgetManager){
+                        // Set up the widget
+                        var _container, _btnPublish;
+                        
+                        // Render the UI
+                        _container = document.body.appendChild(document.createElement("div"));
+                        _btnPublish = _container.appendChild(document.createElement("button"));
+                        _btnPublish.innerHTML = "Publish";
+                        easyXDM.DomHelper.on(_btnPublish, "click", function(){
+                            widget.publish("testtopic", {
+                                latitude: 1,
+                                longitude: 2
+                            });
+                        });
+                        
+                        // Register the handler for incoming messages
+                        widget.registerMessageHandler(function(url, topic, data){
+                            _container.appendChild(document.createElement("div")).innerHTML = "got data on topic " + topic + " from " + url;
+                        });
+                    },
+                    initialized: function(widget, widgetManager){
+                        widget.publish("testtopic", {
+                            latitude: 1,
+                            longitude: 2
+                        });
+                    }
+                });
+            });
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html b/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html
new file mode 100644
index 0000000..17bff03
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/widgets.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript" src="../easyXDM.Widgets.debug.js">
+        </script>
+        <script type="text/javascript">
+            var _widgetManager;
+            easyXDM.whenReady(function(){
+                _widgetManager = new easyXDM.WidgetManager({
+                    swf: "../easyxdm.swf",
+                    container: document.getElementById("widgets")
+                });
+                document.getElementById("widget1url").value = location.href.replace("consumer", "provider").replace("widgets.html", "widget.html");
+                document.getElementById("widget2url").value = location.href.replace("consumer.", "").replace("widgets.html", "widget.html");
+            });
+        </script>
+        <style type="text/css">
+            
+            #widgets {
+                height: 400px;
+            }
+            
+            #widgets iframe {
+                width: 200px;
+                height: 300px;
+                float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div>
+            <input type="text" id="widget1url" style="width:300px" value=""/><input type="button" onclick="_widgetManager.addWidget(document.getElementById('widget1url').value,{});" value="Add Widget"/><input type="button" onclick="_widgetManager.removeWidget(document.getElementById('widget1url').value);" value="Remove Widget"/>
+        </div>
+        <div>
+            <input type="text" id="widget2url" style="width:300px" value=""/><input type="button" onclick="_widgetManager.addWidget(document.getElementById('widget2url').value,{});" value="Add Widget"/><input type="button" onclick="_widgetManager.removeWidget(document.getElementById('widget2url').value);" value="Remove Widget"/>
+        </div><input type="button" onclick="_widgetManager.publish('testtopic','abc');" value="publish"/>
+        <div id="widgets">
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html b/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html
new file mode 100644
index 0000000..a6d7f5d
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/example/xhr.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            /**
+             * Request the use of the JSON object
+             */
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            // this is only bootstrapping code
+            var REMOTE = (function(){
+                var remote = location.href;
+                switch (location.host) {
+                    case "provider.easyxdm.net":
+                        location.href = remote.replace("provider", "consumer");
+                        break;
+                    case "easyxdm.net":
+                        remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+                        break;
+                    case "consumer.easyxdm.net":
+                        remote = remote.replace("consumer", "provider");
+                        break;
+                    case "xdm1":
+                        remote = remote.replace("xdm1", "xdm2");
+                        break;
+                }
+                return remote.substring(0, remote.lastIndexOf("/"));
+            }());
+            
+            // this is really what you are after
+            var xhr = new easyXDM.Rpc({
+                local: "../name.html",
+                swf: REMOTE + "/../easyxdm.swf",
+                remote: REMOTE + "/../cors/",
+                remoteHelper: REMOTE + "/../name.html"
+            }, {
+                remote: {
+                    request: {}
+                }
+            });
+            
+            function getGlossary(){
+                xhr.request({
+                    url: "../example/glossary.aspx",
+                    method: "POST",
+                    headers: {
+                        "x-auth-token": "abcde"
+                    },
+                    data: {
+                        param1: "a",
+                        param2: "b"
+                    }
+                }, function(rpcdata){
+                    var json = easyXDM.getJSONObject().parse(rpcdata.data);
+                    
+                    document.getElementById("response").innerHTML = json.glossary.title;
+                    document.getElementById("header").innerHTML = rpcdata.headers["x-foo"];
+                });
+                
+            }
+        </script>
+    </head>
+    <body>
+        <div style="border:1px solid black;padding:3px;margin:10px;">
+            <a href="index.html">Index of examples</a>
+            | <a href="http://github.com/oyvindkinsey/easyXDM/#readme">Readme at github</a>
+            | 
+            | <a href="http://easyxdm.net/">easyXDM.net</a>
+            | <a href="http://groups.google.com/group/easyxdm">easyXDM at Google Groups</a>
+            <br/>
+            The examples are executing slower than the production build due to the extensive tracing.
+            <br/>
+            If you are alerted about a popup, then this is only the trace log feature. You can ignore this.
+        </div>
+        <script type="text/javascript">
+            document.write("Domain: " + location.host);
+        </script>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log" style="height:100px;border:1px dotted black;overflow:auto">
+        </div>
+        <div id="embedded">
+        </div>
+        <div>
+            This example shows how to use easyXDM to call regular ajax/cors services (no JSONP) from remote domains.
+            <br/>
+            <input type="button" onclick="getGlossary()" value="Call getGlossary using the exposed method"/>
+            <br/>
+            Data from response:<span id="response"></span>
+            <br/>
+            Data from header:<span id="header"></span>
+        </div>
+        <script type="text/javascript">
+            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/json2.js b/asterix-examples/src/main/resources/js/easyXDM/json2.js
new file mode 100644
index 0000000..a1a3b17
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/json2.js
@@ -0,0 +1,482 @@
+/*
+    http://www.JSON.org/json2.js
+    2010-03-20
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON) {
+    this.JSON = {};
+}
+
+(function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                   this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
diff --git a/asterix-examples/src/main/resources/js/easyXDM/name.html b/asterix-examples/src/main/resources/js/easyXDM/name.html
new file mode 100644
index 0000000..cc403b1
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/name.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<html>
+    <head>
+        <title></title>
+        <meta http-equiv="CACHE-CONTROL" content="PUBLIC"/>
+        <meta http-equiv="EXPIRES" content="Sat, 01 Jan 2050 00:00:00 GMT"/>
+    </head>
+    <body>
+        <script type="text/javascript">
+        
+        function sendMessage(message, url){
+            window.setTimeout(function(){
+                window.name = message;
+                location.href = url + "," + encodeURIComponent(location.protocol + "//" + location.host + location.pathname);
+            }, 0);
+        }
+        
+        if (location.hash) {
+            if (location.hash.substring(1, 2) === "_") {
+                var channel, url, hash = location.href.substring(location.href.indexOf("#") + 3), indexOf = hash.indexOf(",");
+                if (indexOf == -1) {
+                    channel = hash;
+                }
+                else {
+                    channel = hash.substring(0, indexOf);
+                    url = decodeURIComponent(hash.substring(indexOf + 1));
+                }
+                switch (location.hash.substring(2, 3)) {
+                    case "2":
+                        // NameTransport local
+                        window.parent.parent.easyXDM.Fn.get(channel)(window.name);
+                        location.href = url + "#_4" + channel + ",";
+                        break;
+                    case "3":
+                        // NameTransport remote
+                        var guest = window.parent.frames["easyXDM_" + channel + "_provider"];
+                        if (!guest) {
+                            throw new Error("unable to reference window");
+                        }
+                        guest.easyXDM.Fn.get(channel)(window.name);
+                        location.href = url + "#_4" + channel + ",";
+                        break;
+                    case "4":
+                        // NameTransport idle
+                        var fn = window.parent.easyXDM.Fn.get(channel + "_load");
+                        if (fn) {
+                            fn();
+                        }
+                        break;
+                }
+            }
+        }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css
new file mode 100644
index 0000000..0df87e3
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.css
@@ -0,0 +1,14 @@
+.easyTest_messages {
+}
+
+.easyTest_error {
+    color: red;
+}
+
+.easyTest_success {
+    color: green;
+}
+
+.easyTest_msg {
+    color: black;
+}
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
new file mode 100644
index 0000000..1da4812
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
@@ -0,0 +1,262 @@
+var easyTest = (function(){
+    var _messages;
+    var _start;
+    var MessageType = {
+        Error: 1,
+        Success: 2,
+        Info: 3
+    };
+    
+    /**
+     * Logs the message to the body
+     * @param {String} msg The message to displey
+     * @param {MessageType} type The messagetype
+     */
+    function _log(msg, type){
+        var el = _messages.appendChild(document.createElement("div"));
+        el.innerHTML = msg;
+        _messages.scrollTop = _messages.scrollHeight;
+        switch (type) {
+            case MessageType.Error:
+                el.className = "easyTest_error";
+                break;
+            case MessageType.Success:
+                el.className = "easyTest_success";
+                break;
+            default:
+                el.className = "easyTest_msg";
+                break;
+        }
+    }
+    
+    var Assert = {
+        // Type checks
+        isTypeOf: function(type, obj){
+            return typeof obj === type;
+        },
+        isInstanceOf: function(type, obj){
+            return obj instanceof type;
+        },
+        isString: function(obj){
+            return this.isTypeOf("string", obj);
+        },
+        isNumber: function(obj){
+            return this.isTypeOf("number", obj);
+        },
+        isObject: function(obj){
+            return this.isTypeOf("object", obj);
+        },
+        isBoolean: function(obj){
+            return this.isTypeOf("boolean", obj);
+        },
+        isFunction: function(obj){
+            return this.isTypeOf("function", obj);
+        },
+        // Equality
+        areEqual: function(a, b){
+            return a == b;
+        },
+        areNotEqual: function(a, b){
+            return a != b;
+        },
+        // Identical
+        areSame: function(a, b){
+            return a === b;
+        },
+        areNotSame: function(a, b){
+            return a !== b;
+        }
+        
+    };
+    
+    function Test(test, fn){
+        var _scope, _steps = test.steps, _step, _stepIndex = 0;
+        var _timer, _runStep, _startedAt, _stepStartedAt;
+        
+        /**
+         * Clean up and tear down the test.<br/>
+         * Calls back to notify that the test is complete
+         */
+        function _endTest(){
+            // Tear down the test
+            if (test.tearDown) {
+                try {
+                    test.tearDown.call(_scope);
+                } 
+                catch (ex) {
+                    _log("Teardown '" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'", MessageType.Error);
+                }
+            }
+            for (var key in _scope) {
+                if (_scope.hasOwnProperty(key)) {
+                    delete _scope[key];
+                }
+            }
+            
+            // Call back
+            fn();
+        }
+        
+        /**
+         * Used to notify the framework of the result of the test
+         * @param {String} name The name of the test
+         * @param {Boolean} result The result of the test
+         * @param {String} reason An optional reason why the test returned the result
+         */
+        function _notifyResult(name, result, reason){
+            var now = new Date().getTime();
+            var testsetTime = now - _start.getTime();
+            var testTime = now - _startedAt.getTime();
+            var stepTime = now - _stepStartedAt.getTime();
+            
+            var times = testsetTime + "ms, " + testTime + "ms, " + stepTime + "ms - ";
+            if (result) {
+                _log(times + name + " succeeded! " + (reason || ""), MessageType.Success);
+            }
+            else {
+                _log(times + name + " failed! " + (reason || ""), MessageType.Error);
+                if (test.failedMessage) {
+                    _log(test.failedMessage, MessageType.Info);
+                }
+            }
+            // Go to next step
+            if (result) {
+                _stepIndex++;
+                window.setTimeout(function(){
+                    _runStep();
+                }, 0);
+            }
+            else {
+                _endTest();
+            }
+        }
+        
+        
+        /**
+         * Runs through the test step
+         */
+        _runStep = function(){
+            if (_stepIndex < _steps.length) {
+                // We still have steps to run
+                _step = _steps[_stepIndex];
+                _stepStartedAt = new Date();
+                if (_step.timeout) {
+                    // This an asynchronous test
+                    _timer = window.setTimeout(function(){
+                        _notifyResult(_step.name, false, "Failed due to timeout.");
+                    }, _step.timeout);
+                    try {
+                        _step.run.call(_scope);
+                    } 
+                    catch (ex) {
+                        //If it fails we cancel the timeout
+                        window.clearTimeout(_timer);
+                        _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+                    }
+                }
+                else {
+                    // This is a synchronous test
+                    try {
+                        var result = _step.run.call(_scope);
+                        _notifyResult(_step.name, result);
+                    } 
+                    catch (ex) {
+                        _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+                    }
+                }
+            }
+            else {
+                _endTest();
+            }
+        };
+        
+        return {
+            /**
+             * Runs the test.
+             * Will first try to execute the setup method before continuing the steps
+             */
+            run: function(){
+                var excuse;
+                if (test.runIf) {
+                    excuse = test.runIf();
+                }
+                if (excuse) {
+                    _log("Skipping test ' " + test.name + "'. " + excuse);
+                    fn();
+                }
+                else {
+                    _log("Running test '" + test.name + "'");
+                    _scope = {
+                        Assert: Assert,
+                        log: _log,
+                        notifyResult: function(result){
+                            window.clearTimeout(_timer);
+                            _notifyResult(_step.name, result);
+                        }
+                    };
+                    if (test.setUp) {
+                        // Setup the test
+                        try {
+                            test.setUp.call(_scope);
+                            _log("Setup succeeded", MessageType.Success);
+                        } 
+                        catch (ex) {
+                            _log("Setup failed", MessageType.Error);
+                        }
+                    }
+                    _startedAt = new Date();
+                    _runStep();
+                }
+            }
+        };
+    }
+    
+    return {
+        /**
+         * Runs through all the tests
+         * @param {Array} tests The tests to run
+         */
+        test: function(testset){
+            var tests = [], testConfig, i = testset.length, test;
+            
+            // Prepare the messaging facilities
+            if (!_messages) {
+                _messages = document.createElement("div");
+                _messages.className = "easyTest_messages";
+                (document.getElementById("messages") || document.body).appendChild(_messages);
+            }
+            else {
+                _messages.innerHTML = "";
+            }
+            
+            // Convert the testset
+            while (i--) {
+                testConfig = testset[i];
+                if (!testConfig.steps) {
+                    // Convert a single step test to a proper test
+                    testConfig = {
+                        steps: testConfig
+                    };
+                }
+                
+                tests.push(new Test(testConfig, function(){
+                    // Get the next test to run
+                    test = tests.pop();
+                    if (test) {
+                        // This is needed to avoid a strange bug in Opera,
+                        window.setTimeout(function(){
+                            test.run();
+                        }, 0);
+                    }
+                    else {
+                        // No more tests to run
+                        _log("Test run complete", MessageType.Info);
+                    }
+                }));
+            }
+            // Start the first test
+            _start = new Date();
+            tests.pop().run();
+        }
+    };
+}());
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js b/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js
new file mode 100644
index 0000000..c1c614a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyXDM.debug.js
@@ -0,0 +1,2848 @@
+(function (window, document, location, setTimeout, decodeURIComponent, encodeURIComponent) {
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global JSON, XMLHttpRequest, window, escape, unescape, ActiveXObject */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var global = this;
+var channelId = Math.floor(Math.random() * 10000); // randomize the initial id in case of multiple closures loaded 
+var emptyFn = Function.prototype;
+var reURI = /^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/; // returns groups for protocol (2), domain (3) and port (4) 
+var reParent = /[\-\w]+\/\.\.\//; // matches a foo/../ expression 
+var reDoubleSlash = /([^:])\/\//g; // matches // anywhere but in the protocol
+var namespace = ""; // stores namespace under which easyXDM object is stored on the page (empty if object is global)
+var easyXDM = {};
+var _easyXDM = window.easyXDM; // map over global easyXDM in case of overwrite
+var IFRAME_PREFIX = "easyXDM_";
+var HAS_NAME_PROPERTY_BUG;
+var useHash = false; // whether to use the hash over the query
+var flashVersion; // will be set if using flash
+var HAS_FLASH_THROTTLED_BUG;
+var _trace = emptyFn;
+
+
+// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
+function isHostMethod(object, property){
+    var t = typeof object[property];
+    return t == 'function' ||
+    (!!(t == 'object' && object[property])) ||
+    t == 'unknown';
+}
+
+function isHostObject(object, property){
+    return !!(typeof(object[property]) == 'object' && object[property]);
+}
+
+// end
+
+// http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+function isArray(o){
+    return Object.prototype.toString.call(o) === '[object Array]';
+}
+
+// end
+function hasFlash(){
+    var name = "Shockwave Flash", mimeType = "application/x-shockwave-flash";
+    
+    if (!undef(navigator.plugins) && typeof navigator.plugins[name] == "object") {
+        // adapted from the swfobject code
+        var description = navigator.plugins[name].description;
+        if (description && !undef(navigator.mimeTypes) && navigator.mimeTypes[mimeType] && navigator.mimeTypes[mimeType].enabledPlugin) {
+            flashVersion = description.match(/\d+/g);
+        }
+    }
+    if (!flashVersion) {
+        var flash;
+        try {
+            flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+            flashVersion = Array.prototype.slice.call(flash.GetVariable("$version").match(/(\d+),(\d+),(\d+),(\d+)/), 1);
+            flash = null;
+        } 
+        catch (notSupportedException) {
+        }
+    }
+    if (!flashVersion) {
+        return false;
+    }
+    var major = parseInt(flashVersion[0], 10), minor = parseInt(flashVersion[1], 10);
+    HAS_FLASH_THROTTLED_BUG = major > 9 && minor > 0;
+    return true;
+}
+
+/*
+ * Cross Browser implementation for adding and removing event listeners.
+ */
+var on, un;
+if (isHostMethod(window, "addEventListener")) {
+    on = function(target, type, listener){
+        _trace("adding listener " + type);
+        target.addEventListener(type, listener, false);
+    };
+    un = function(target, type, listener){
+        _trace("removing listener " + type);
+        target.removeEventListener(type, listener, false);
+    };
+}
+else if (isHostMethod(window, "attachEvent")) {
+    on = function(object, sEvent, fpNotify){
+        _trace("adding listener " + sEvent);
+        object.attachEvent("on" + sEvent, fpNotify);
+    };
+    un = function(object, sEvent, fpNotify){
+        _trace("removing listener " + sEvent);
+        object.detachEvent("on" + sEvent, fpNotify);
+    };
+}
+else {
+    throw new Error("Browser not supported");
+}
+
+/*
+ * Cross Browser implementation of DOMContentLoaded.
+ */
+var domIsReady = false, domReadyQueue = [], readyState;
+if ("readyState" in document) {
+    // If browser is WebKit-powered, check for both 'loaded' (legacy browsers) and
+    // 'interactive' (HTML5 specs, recent WebKit builds) states.
+    // https://bugs.webkit.org/show_bug.cgi?id=45119
+    readyState = document.readyState;
+    domIsReady = readyState == "complete" || (~ navigator.userAgent.indexOf('AppleWebKit/') && (readyState == "loaded" || readyState == "interactive"));
+}
+else {
+    // If readyState is not supported in the browser, then in order to be able to fire whenReady functions apropriately
+    // when added dynamically _after_ DOM load, we have to deduce wether the DOM is ready or not.
+    // We only need a body to add elements to, so the existence of document.body is enough for us.
+    domIsReady = !!document.body;
+}
+
+function dom_onReady(){
+    if (domIsReady) {
+        return;
+    }
+    domIsReady = true;
+    _trace("firing dom_onReady");
+    for (var i = 0; i < domReadyQueue.length; i++) {
+        domReadyQueue[i]();
+    }
+    domReadyQueue.length = 0;
+}
+
+
+if (!domIsReady) {
+    if (isHostMethod(window, "addEventListener")) {
+        on(document, "DOMContentLoaded", dom_onReady);
+    }
+    else {
+        on(document, "readystatechange", function(){
+            if (document.readyState == "complete") {
+                dom_onReady();
+            }
+        });
+        if (document.documentElement.doScroll && window === top) {
+            var doScrollCheck = function(){
+                if (domIsReady) {
+                    return;
+                }
+                // http://javascript.nwbox.com/IEContentLoaded/
+                try {
+                    document.documentElement.doScroll("left");
+                } 
+                catch (e) {
+                    setTimeout(doScrollCheck, 1);
+                    return;
+                }
+                dom_onReady();
+            };
+            doScrollCheck();
+        }
+    }
+    
+    // A fallback to window.onload, that will always work
+    on(window, "load", dom_onReady);
+}
+/**
+ * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+ * If functions are added after this event then they will be executed immediately.
+ * @param {function} fn The function to add
+ * @param {Object} scope An optional scope for the function to be called with.
+ */
+function whenReady(fn, scope){
+    if (domIsReady) {
+        fn.call(scope);
+        return;
+    }
+    domReadyQueue.push(function(){
+        fn.call(scope);
+    });
+}
+
+/**
+ * Returns an instance of easyXDM from the parent window with
+ * respect to the namespace.
+ *
+ * @return An instance of easyXDM (in the parent window)
+ */
+function getParentObject(){
+    var obj = parent;
+    if (namespace !== "") {
+        for (var i = 0, ii = namespace.split("."); i < ii.length; i++) {
+            if (!obj) {
+                throw new Error(ii.slice(0, i + 1).join('.') + ' is not an object');
+            }
+            obj = obj[ii[i]];
+        }
+    }
+    if (!obj || !obj.easyXDM) {
+        throw new Error('Could not find easyXDM in parent.' + namespace);
+    }
+    return obj.easyXDM;
+}
+
+/**
+ * Removes easyXDM variable from the global scope. It also returns control
+ * of the easyXDM variable to whatever code used it before.
+ *
+ * @param {String} ns A string representation of an object that will hold
+ *                    an instance of easyXDM.
+ * @return An instance of easyXDM
+ */
+function noConflict(ns){
+    if (typeof ns != "string" || !ns) {
+        throw new Error('namespace must be a non-empty string');
+    }
+    _trace("Settings namespace to '" + ns + "'");
+    
+    window.easyXDM = _easyXDM;
+    namespace = ns;
+    if (namespace) {
+        IFRAME_PREFIX = "easyXDM_" + namespace.replace(".", "_") + "_";
+    }
+    return easyXDM;
+}
+
+/*
+ * Methods for working with URLs
+ */
+/**
+ * Get the domain name from a url.
+ * @param {String} url The url to extract the domain from.
+ * @return The domain part of the url.
+ * @type {String}
+ */
+function getDomainName(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[3];
+}
+
+/**
+ * Get the port for a given URL, or "" if none
+ * @param {String} url The url to extract the port from.
+ * @return The port part of the url.
+ * @type {String}
+ */
+function getPort(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    return url.match(reURI)[4] || "";
+}
+
+/**
+ * Returns  a string containing the schema, domain and if present the port
+ * @param {String} url The url to extract the location from
+ * @return {String} The location part of the url
+ */
+function getLocation(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    if (/^file/.test(url)) {
+        throw new Error("The file:// protocol is not supported");
+    }
+    var m = url.toLowerCase().match(reURI);
+    var proto = m[2], domain = m[3], port = m[4] || "";
+    if ((proto == "http:" && port == ":80") || (proto == "https:" && port == ":443")) {
+        port = "";
+    }
+    return proto + "//" + domain + port;
+}
+
+/**
+ * Resolves a relative url into an absolute one.
+ * @param {String} url The path to resolve.
+ * @return {String} The resolved url.
+ */
+function resolveUrl(url){
+    if (!url) {
+        throw new Error("url is undefined or empty");
+    }
+    
+    // replace all // except the one in proto with /
+    url = url.replace(reDoubleSlash, "$1/");
+    
+    // If the url is a valid url we do nothing
+    if (!url.match(/^(http||https):\/\//)) {
+        // If this is a relative path
+        var path = (url.substring(0, 1) === "/") ? "" : location.pathname;
+        if (path.substring(path.length - 1) !== "/") {
+            path = path.substring(0, path.lastIndexOf("/") + 1);
+        }
+        
+        url = location.protocol + "//" + location.host + path + url;
+    }
+    
+    // reduce all 'xyz/../' to just '' 
+    while (reParent.test(url)) {
+        url = url.replace(reParent, "");
+    }
+    
+    _trace("resolved url '" + url + "'");
+    return url;
+}
+
+/**
+ * Appends the parameters to the given url.<br/>
+ * The base url can contain existing query parameters.
+ * @param {String} url The base url.
+ * @param {Object} parameters The parameters to add.
+ * @return {String} A new valid url with the parameters appended.
+ */
+function appendQueryParameters(url, parameters){
+    if (!parameters) {
+        throw new Error("parameters is undefined or null");
+    }
+    
+    var hash = "", indexOf = url.indexOf("#");
+    if (indexOf !== -1) {
+        hash = url.substring(indexOf);
+        url = url.substring(0, indexOf);
+    }
+    var q = [];
+    for (var key in parameters) {
+        if (parameters.hasOwnProperty(key)) {
+            q.push(key + "=" + encodeURIComponent(parameters[key]));
+        }
+    }
+    return url + (useHash ? "#" : (url.indexOf("?") == -1 ? "?" : "&")) + q.join("&") + hash;
+}
+
+
+// build the query object either from location.query, if it contains the xdm_e argument, or from location.hash
+var query = (function(input){
+    input = input.substring(1).split("&");
+    var data = {}, pair, i = input.length;
+    while (i--) {
+        pair = input[i].split("=");
+        data[pair[0]] = decodeURIComponent(pair[1]);
+    }
+    return data;
+}(/xdm_e=/.test(location.search) ? location.search : location.hash));
+
+/*
+ * Helper methods
+ */
+/**
+ * Helper for checking if a variable/property is undefined
+ * @param {Object} v The variable to test
+ * @return {Boolean} True if the passed variable is undefined
+ */
+function undef(v){
+    return typeof v === "undefined";
+}
+
+/**
+ * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+ * @return {JSON} A valid JSON conforming object, or null if not found.
+ */
+var getJSON = function(){
+    var cached = {};
+    var obj = {
+        a: [1, 2, 3]
+    }, json = "{\"a\":[1,2,3]}";
+    
+    if (typeof JSON != "undefined" && typeof JSON.stringify === "function" && JSON.stringify(obj).replace((/\s/g), "") === json) {
+        // this is a working JSON instance
+        return JSON;
+    }
+    if (Object.toJSON) {
+        if (Object.toJSON(obj).replace((/\s/g), "") === json) {
+            // this is a working stringify method
+            cached.stringify = Object.toJSON;
+        }
+    }
+    
+    if (typeof String.prototype.evalJSON === "function") {
+        obj = json.evalJSON();
+        if (obj.a && obj.a.length === 3 && obj.a[2] === 3) {
+            // this is a working parse method           
+            cached.parse = function(str){
+                return str.evalJSON();
+            };
+        }
+    }
+    
+    if (cached.stringify && cached.parse) {
+        // Only memoize the result if we have valid instance
+        getJSON = function(){
+            return cached;
+        };
+        return cached;
+    }
+    return null;
+};
+
+/**
+ * Applies properties from the source object to the target object.<br/>
+ * @param {Object} target The target of the properties.
+ * @param {Object} source The source of the properties.
+ * @param {Boolean} noOverwrite Set to True to only set non-existing properties.
+ */
+function apply(destination, source, noOverwrite){
+    var member;
+    for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+            if (prop in destination) {
+                member = source[prop];
+                if (typeof member === "object") {
+                    apply(destination[prop], member, noOverwrite);
+                }
+                else if (!noOverwrite) {
+                    destination[prop] = source[prop];
+                }
+            }
+            else {
+                destination[prop] = source[prop];
+            }
+        }
+    }
+    return destination;
+}
+
+// This tests for the bug in IE where setting the [name] property using javascript causes the value to be redirected into [submitName].
+function testForNamePropertyBug(){
+    var form = document.body.appendChild(document.createElement("form")), input = form.appendChild(document.createElement("input"));
+    input.name = IFRAME_PREFIX + "TEST" + channelId; // append channelId in order to avoid caching issues
+    HAS_NAME_PROPERTY_BUG = input !== form.elements[input.name];
+    document.body.removeChild(form);
+    _trace("HAS_NAME_PROPERTY_BUG: " + HAS_NAME_PROPERTY_BUG);
+}
+
+/**
+ * Creates a frame and appends it to the DOM.
+ * @param config {object} This object can have the following properties
+ * <ul>
+ * <li> {object} prop The properties that should be set on the frame. This should include the 'src' property.</li>
+ * <li> {object} attr The attributes that should be set on the frame.</li>
+ * <li> {DOMElement} container Its parent element (Optional).</li>
+ * <li> {function} onLoad A method that should be called with the frames contentWindow as argument when the frame is fully loaded. (Optional)</li>
+ * </ul>
+ * @return The frames DOMElement
+ * @type DOMElement
+ */
+function createFrame(config){
+    _trace("creating frame: " + config.props.src);
+    if (undef(HAS_NAME_PROPERTY_BUG)) {
+        testForNamePropertyBug();
+    }
+    var frame;
+    // This is to work around the problems in IE6/7 with setting the name property. 
+    // Internally this is set as 'submitName' instead when using 'iframe.name = ...'
+    // This is not required by easyXDM itself, but is to facilitate other use cases 
+    if (HAS_NAME_PROPERTY_BUG) {
+        frame = document.createElement("<iframe name=\"" + config.props.name + "\"/>");
+    }
+    else {
+        frame = document.createElement("IFRAME");
+        frame.name = config.props.name;
+    }
+    
+    frame.id = frame.name = config.props.name;
+    delete config.props.name;
+    
+    if (typeof config.container == "string") {
+        config.container = document.getElementById(config.container);
+    }
+    
+    if (!config.container) {
+        // This needs to be hidden like this, simply setting display:none and the like will cause failures in some browsers.
+        apply(frame.style, {
+            position: "absolute",
+            top: "-2000px",
+            // Avoid potential horizontal scrollbar
+            left: "0px"
+        });
+        config.container = document.body;
+    }
+    
+    // HACK: IE cannot have the src attribute set when the frame is appended
+    //       into the container, so we set it to "javascript:false" as a
+    //       placeholder for now.  If we left the src undefined, it would
+    //       instead default to "about:blank", which causes SSL mixed-content
+    //       warnings in IE6 when on an SSL parent page.
+    var src = config.props.src;
+    config.props.src = "javascript:false";
+    
+    // transfer properties to the frame
+    apply(frame, config.props);
+    
+    frame.border = frame.frameBorder = 0;
+    frame.allowTransparency = true;
+    config.container.appendChild(frame);
+    
+    if (config.onLoad) {
+        on(frame, "load", config.onLoad);
+    }
+    
+    // set the frame URL to the proper value (we previously set it to
+    // "javascript:false" to work around the IE issue mentioned above)
+    if(config.usePost) {
+        var form = config.container.appendChild(document.createElement('form')), input;
+        form.target = frame.name;
+        form.action = src;
+        form.method = 'POST';
+        if (typeof(config.usePost) === 'object') {
+            for (var i in config.usePost) {
+                if (config.usePost.hasOwnProperty(i)) {
+                    if (HAS_NAME_PROPERTY_BUG) {
+                        input = document.createElement('<input name="' + i + '"/>');
+                    } else {
+                        input = document.createElement("INPUT");
+                        input.name = i;
+                    }
+                    input.value = config.usePost[i];
+                    form.appendChild(input);
+                }
+            }
+        }
+        form.submit();
+        form.parentNode.removeChild(form);
+    } else {
+        frame.src = src;
+    }
+    config.props.src = src;
+    
+    return frame;
+}
+
+/**
+ * Check whether a domain is allowed using an Access Control List.
+ * The ACL can contain * and ? as wildcards, or can be regular expressions.
+ * If regular expressions they need to begin with ^ and end with $.
+ * @param {Array/String} acl The list of allowed domains
+ * @param {String} domain The domain to test.
+ * @return {Boolean} True if the domain is allowed, false if not.
+ */
+function checkAcl(acl, domain){
+    // normalize into an array
+    if (typeof acl == "string") {
+        acl = [acl];
+    }
+    var re, i = acl.length;
+    while (i--) {
+        re = acl[i];
+        re = new RegExp(re.substr(0, 1) == "^" ? re : ("^" + re.replace(/(\*)/g, ".$1").replace(/\?/g, ".") + "$"));
+        if (re.test(domain)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Functions related to stacks
+ */
+/**
+ * Prepares an array of stack-elements suitable for the current configuration
+ * @param {Object} config The Transports configuration. See easyXDM.Socket for more.
+ * @return {Array} An array of stack-elements with the TransportElement at index 0.
+ */
+function prepareTransportStack(config){
+    var protocol = config.protocol, stackEls;
+    config.isHost = config.isHost || undef(query.xdm_p);
+    useHash = config.hash || false;
+    _trace("preparing transport stack");
+    
+    if (!config.props) {
+        config.props = {};
+    }
+    if (!config.isHost) {
+        _trace("using parameters from query");
+        config.channel = query.xdm_c.replace(/["'<>\\]/g, "");
+        config.secret = query.xdm_s;
+        config.remote = query.xdm_e.replace(/["'<>\\]/g, "");
+        ;
+        protocol = query.xdm_p;
+        if (config.acl && !checkAcl(config.acl, config.remote)) {
+            throw new Error("Access denied for " + config.remote);
+        }
+    }
+    else {
+        config.remote = resolveUrl(config.remote);
+        config.channel = config.channel || "default" + channelId++;
+        config.secret = Math.random().toString(16).substring(2);
+        if (undef(protocol)) {
+            if (getLocation(location.href) == getLocation(config.remote)) {
+                /*
+                 * Both documents has the same origin, lets use direct access.
+                 */
+                protocol = "4";
+            }
+            else if (isHostMethod(window, "postMessage") || isHostMethod(document, "postMessage")) {
+                /*
+                 * This is supported in IE8+, Firefox 3+, Opera 9+, Chrome 2+ and Safari 4+
+                 */
+                protocol = "1";
+            }
+            else if (config.swf && isHostMethod(window, "ActiveXObject") && hasFlash()) {
+                /*
+                 * The Flash transport superseedes the NixTransport as the NixTransport has been blocked by MS
+                 */
+                protocol = "6";
+            }
+            else if (navigator.product === "Gecko" && "frameElement" in window && navigator.userAgent.indexOf('WebKit') == -1) {
+                /*
+                 * This is supported in Gecko (Firefox 1+)
+                 */
+                protocol = "5";
+            }
+            else if (config.remoteHelper) {
+                /*
+                 * This is supported in all browsers that retains the value of window.name when
+                 * navigating from one domain to another, and where parent.frames[foo] can be used
+                 * to get access to a frame from the same domain
+                 */
+                protocol = "2";
+            }
+            else {
+                /*
+                 * This is supported in all browsers where [window].location is writable for all
+                 * The resize event will be used if resize is supported and the iframe is not put
+                 * into a container, else polling will be used.
+                 */
+                protocol = "0";
+            }
+            _trace("selecting protocol: " + protocol);
+        }
+        else {
+            _trace("using protocol: " + protocol);
+        }
+    }
+    config.protocol = protocol; // for conditional branching
+    switch (protocol) {
+        case "0":// 0 = HashTransport
+            apply(config, {
+                interval: 100,
+                delay: 2000,
+                useResize: true,
+                useParent: false,
+                usePolling: false
+            }, true);
+            if (config.isHost) {
+                if (!config.local) {
+                    _trace("looking for image to use as local");
+                    // If no local is set then we need to find an image hosted on the current domain
+                    var domain = location.protocol + "//" + location.host, images = document.body.getElementsByTagName("img"), image;
+                    var i = images.length;
+                    while (i--) {
+                        image = images[i];
+                        if (image.src.substring(0, domain.length) === domain) {
+                            config.local = image.src;
+                            break;
+                        }
+                    }
+                    if (!config.local) {
+                        _trace("no image found, defaulting to using the window");
+                        // If no local was set, and we are unable to find a suitable file, then we resort to using the current window 
+                        config.local = window;
+                    }
+                }
+                
+                var parameters = {
+                    xdm_c: config.channel,
+                    xdm_p: 0
+                };
+                
+                if (config.local === window) {
+                    // We are using the current window to listen to
+                    config.usePolling = true;
+                    config.useParent = true;
+                    config.local = location.protocol + "//" + location.host + location.pathname + location.search;
+                    parameters.xdm_e = config.local;
+                    parameters.xdm_pa = 1; // use parent
+                }
+                else {
+                    parameters.xdm_e = resolveUrl(config.local);
+                }
+                
+                if (config.container) {
+                    config.useResize = false;
+                    parameters.xdm_po = 1; // use polling
+                }
+                config.remote = appendQueryParameters(config.remote, parameters);
+            }
+            else {
+                apply(config, {
+                    channel: query.xdm_c,
+                    remote: query.xdm_e,
+                    useParent: !undef(query.xdm_pa),
+                    usePolling: !undef(query.xdm_po),
+                    useResize: config.useParent ? false : config.useResize
+                });
+            }
+            stackEls = [new easyXDM.stack.HashTransport(config), new easyXDM.stack.ReliableBehavior({}), new easyXDM.stack.QueueBehavior({
+                encode: true,
+                maxLength: 4000 - config.remote.length
+            }), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "1":
+            stackEls = [new easyXDM.stack.PostMessageTransport(config)];
+            break;
+        case "2":
+            config.remoteHelper = resolveUrl(config.remoteHelper);
+            stackEls = [new easyXDM.stack.NameTransport(config), new easyXDM.stack.QueueBehavior(), new easyXDM.stack.VerifyBehavior({
+                initiate: config.isHost
+            })];
+            break;
+        case "3":
+            stackEls = [new easyXDM.stack.NixTransport(config)];
+            break;
+        case "4":
+            stackEls = [new easyXDM.stack.SameOriginTransport(config)];
+            break;
+        case "5":
+            stackEls = [new easyXDM.stack.FrameElementTransport(config)];
+            break;
+        case "6":
+            if (!flashVersion) {
+                hasFlash();
+            }
+            stackEls = [new easyXDM.stack.FlashTransport(config)];
+            break;
+    }
+    // this behavior is responsible for buffering outgoing messages, and for performing lazy initialization
+    stackEls.push(new easyXDM.stack.QueueBehavior({
+        lazy: config.lazy,
+        remove: true
+    }));
+    return stackEls;
+}
+
+/**
+ * Chains all the separate stack elements into a single usable stack.<br/>
+ * If an element is missing a necessary method then it will have a pass-through method applied.
+ * @param {Array} stackElements An array of stack elements to be linked.
+ * @return {easyXDM.stack.StackElement} The last element in the chain.
+ */
+function chainStack(stackElements){
+    var stackEl, defaults = {
+        incoming: function(message, origin){
+            this.up.incoming(message, origin);
+        },
+        outgoing: function(message, recipient){
+            this.down.outgoing(message, recipient);
+        },
+        callback: function(success){
+            this.up.callback(success);
+        },
+        init: function(){
+            this.down.init();
+        },
+        destroy: function(){
+            this.down.destroy();
+        }
+    };
+    for (var i = 0, len = stackElements.length; i < len; i++) {
+        stackEl = stackElements[i];
+        apply(stackEl, defaults, true);
+        if (i !== 0) {
+            stackEl.down = stackElements[i - 1];
+        }
+        if (i !== len - 1) {
+            stackEl.up = stackElements[i + 1];
+        }
+    }
+    return stackEl;
+}
+
+/**
+ * This will remove a stackelement from its stack while leaving the stack functional.
+ * @param {Object} element The elment to remove from the stack.
+ */
+function removeFromStack(element){
+    element.up.down = element.down;
+    element.down.up = element.up;
+    element.up = element.down = null;
+}
+
+/*
+ * Export the main object and any other methods applicable
+ */
+/** 
+ * @class easyXDM
+ * A javascript library providing cross-browser, cross-domain messaging/RPC.
+ * @version 2.4.17.1
+ * @singleton
+ */
+apply(easyXDM, {
+    /**
+     * The version of the library
+     * @type {string}
+     */
+    version: "2.4.17.1",
+    /**
+     * This is a map containing all the query parameters passed to the document.
+     * All the values has been decoded using decodeURIComponent.
+     * @type {object}
+     */
+    query: query,
+    /**
+     * @private
+     */
+    stack: {},
+    /**
+     * Applies properties from the source object to the target object.<br/>
+     * @param {object} target The target of the properties.
+     * @param {object} source The source of the properties.
+     * @param {boolean} noOverwrite Set to True to only set non-existing properties.
+     */
+    apply: apply,
+    
+    /**
+     * A safe implementation of HTML5 JSON. Feature testing is used to make sure the implementation works.
+     * @return {JSON} A valid JSON conforming object, or null if not found.
+     */
+    getJSONObject: getJSON,
+    /**
+     * This will add a function to the queue of functions to be run once the DOM reaches a ready state.
+     * If functions are added after this event then they will be executed immediately.
+     * @param {function} fn The function to add
+     * @param {object} scope An optional scope for the function to be called with.
+     */
+    whenReady: whenReady,
+    /**
+     * Removes easyXDM variable from the global scope. It also returns control
+     * of the easyXDM variable to whatever code used it before.
+     *
+     * @param {String} ns A string representation of an object that will hold
+     *                    an instance of easyXDM.
+     * @return An instance of easyXDM
+     */
+    noConflict: noConflict
+});
+
+// Expose helper functions so we can test them
+apply(easyXDM, {
+    checkAcl: checkAcl,
+    getDomainName: getDomainName,
+    getLocation: getLocation,
+    appendQueryParameters: appendQueryParameters
+});
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global console, _FirebugCommandLine,  easyXDM, window, escape, unescape, isHostObject, undef, _trace, domIsReady, emptyFn, namespace */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+var debug = {
+    _deferred: [],
+    flush: function(){
+        this.trace("... deferred messages ...");
+        for (var i = 0, len = this._deferred.length; i < len; i++) {
+            this.trace(this._deferred[i]);
+        }
+        this._deferred.length = 0;
+        this.trace("... end of deferred messages ...");
+    },
+    getTime: function(){
+        var d = new Date(), h = d.getHours() + "", m = d.getMinutes() + "", s = d.getSeconds() + "", ms = d.getMilliseconds() + "", zeros = "000";
+        if (h.length == 1) {
+            h = "0" + h;
+        }
+        if (m.length == 1) {
+            m = "0" + m;
+        }
+        if (s.length == 1) {
+            s = "0" + s;
+        }
+        ms = zeros.substring(ms.length) + ms;
+        return h + ":" + m + ":" + s + "." + ms;
+    },
+    /**
+     * Logs the message to console.log if available
+     * @param {String} msg The message to log
+     */
+    log: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!isHostObject(window, "console") || undef(console.log)) {
+            /**
+             * Sets log to be an empty function since we have no output available
+             * @ignore
+             */
+            this.log = emptyFn;
+        }
+        else {
+            /**
+             * Sets log to be a wrapper around console.log
+             * @ignore
+             * @param {String} msg
+             */
+            this.log = function(msg){
+                console.log(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ": " + msg);
+            };
+        }
+        this.log(msg);
+    },
+    /**
+     * Will try to trace the given message either to a DOMElement with the id "log",
+     * or by using console.info.
+     * @param {String} msg The message to trace
+     */
+    trace: function(msg){
+        // Uses memoizing to cache the implementation
+        if (!domIsReady) {
+            if (this._deferred.length === 0) {
+                easyXDM.whenReady(debug.flush, debug);
+            }
+            this._deferred.push(msg);
+            this.log(msg);
+        }
+        else {
+            var el = document.getElementById("log");
+            // is there a log element present?
+            if (el) {
+                /**
+                 * Sets trace to be a function that outputs the messages to the DOMElement with id "log"
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    try {
+                        el.appendChild(document.createElement("div")).appendChild(document.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                        el.scrollTop = el.scrollHeight;
+                    } 
+                    catch (e) {
+                        //In case we are unloading
+                    }
+                };
+            }
+            else if (isHostObject(window, "console") && !undef(console.info)) {
+                /**
+                 * Sets trace to be a wrapper around console.info
+                 * @ignore
+                 * @param {String} msg
+                 */
+                this.trace = function(msg){
+                    console.info(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg);
+                };
+            }
+            else {
+                /**
+                 * Create log window
+                 * @ignore
+                 */
+                var domain = location.host, windowname = domain.replace(/[\-.:]/g, "") + "easyxdm_log", logWin;
+                try {
+                    logWin = window.open("", windowname, "width=800,height=200,status=0,navigation=0,scrollbars=1");
+                } 
+                catch (e) {
+                }
+                if (logWin) {
+                    var doc = logWin.document;
+                    el = doc.getElementById("log");
+                    if (!el) {
+                        doc.write("<html><head><title>easyXDM log " + domain + "</title></head>");
+                        doc.write("<body><div id=\"log\"></div></body></html>");
+                        doc.close();
+                        el = doc.getElementById("log");
+                    }
+                    this.trace = function(msg){
+                        try {
+                            el.appendChild(doc.createElement("div")).appendChild(doc.createTextNode(location.host + (namespace ? ":" + namespace : "") + " - " + this.getTime() + ":" + msg));
+                            el.scrollTop = el.scrollHeight;
+                        } 
+                        catch (e) {
+                            //In case we are unloading
+                        }
+                    };
+                    this.trace("---- new logger at " + location.href);
+                }
+                
+                if (!el) {
+                    // We are unable to use any logging
+                    this.trace = emptyFn;
+                }
+            }
+            this.trace(msg);
+        }
+    },
+    /**
+     * Creates a method usable for tracing.
+     * @param {String} name The name the messages should be marked with
+     * @return {Function} A function that accepts a single string as argument.
+     */
+    getTracer: function(name){
+        return function(msg){
+            debug.trace(name + ": " + msg);
+        };
+    }
+};
+debug.log("easyXDM present on '" + location.href);
+easyXDM.Debug = debug;
+_trace = debug.getTracer("{Private}");
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, isHostObject, isHostMethod, un, on, createFrame, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.DomHelper
+ * Contains methods for dealing with the DOM
+ * @singleton
+ */
+easyXDM.DomHelper = {
+    /**
+     * Provides a consistent interface for adding eventhandlers
+     * @param {Object} target The target to add the event to
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    on: on,
+    /**
+     * Provides a consistent interface for removing eventhandlers
+     * @param {Object} target The target to remove the event from
+     * @param {String} type The name of the event
+     * @param {Function} listener The listener
+     */
+    un: un,
+    /**
+     * Checks for the presence of the JSON object.
+     * If it is not present it will use the supplied path to load the JSON2 library.
+     * This should be called in the documents head right after the easyXDM script tag.
+     * http://json.org/json2.js
+     * @param {String} path A valid path to json2.js
+     */
+    requiresJSON: function(path){
+        if (!isHostObject(window, "JSON")) {
+            debug.log("loading external JSON");
+            // we need to encode the < in order to avoid an illegal token error
+            // when the script is inlined in a document.
+            document.write('<' + 'script type="text/javascript" src="' + path + '"><' + '/script>');
+        }
+        else {
+            debug.log("native JSON found");
+        }
+    }
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+(function(){
+    // The map containing the stored functions
+    var _map = {};
+    
+    /**
+     * @class easyXDM.Fn
+     * This contains methods related to function handling, such as storing callbacks.
+     * @singleton
+     * @namespace easyXDM
+     */
+    easyXDM.Fn = {
+        /**
+         * Stores a function using the given name for reference
+         * @param {String} name The name that the function should be referred by
+         * @param {Function} fn The function to store
+         * @namespace easyXDM.fn
+         */
+        set: function(name, fn){
+            this._trace("storing function " + name);
+            _map[name] = fn;
+        },
+        /**
+         * Retrieves the function referred to by the given name
+         * @param {String} name The name of the function to retrieve
+         * @param {Boolean} del If the function should be deleted after retrieval
+         * @return {Function} The stored function
+         * @namespace easyXDM.fn
+         */
+        get: function(name, del){
+            this._trace("retrieving function " + name);
+            var fn = _map[name];
+            if (!fn) {
+                this._trace(name + " not found");
+            }
+            
+            if (del) {
+                delete _map[name];
+            }
+            return fn;
+        }
+    };
+    
+    easyXDM.Fn._trace = debug.getTracer("easyXDM.Fn");
+}());
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, chainStack, prepareTransportStack, getLocation, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.Socket
+ * This class creates a transport channel between two domains that is usable for sending and receiving string-based messages.<br/>
+ * The channel is reliable, supports queueing, and ensures that the message originates from the expected domain.<br/>
+ * Internally different stacks will be used depending on the browsers features and the available parameters.
+ * <h2>How to set up</h2>
+ * Setting up the provider:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; local: "name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * Setting up the consumer:
+ * <pre><code>
+ * var socket = new easyXDM.Socket({
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/page.html",
+ * &nbsp; remoteHelper: "http:&#47;&#47;remotedomain/name.html",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the socket
+ * &nbsp; &nbsp; socket.postMessage("foo-message");
+ * &nbsp; },
+ * &nbsp; onMessage: function(message, origin) {
+ * &nbsp;&nbsp; alert("received " + message + " from " + origin);
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If you are unable to upload the <code>name.html</code> file to the consumers domain then remove the <code>remoteHelper</code> property
+ * and easyXDM will fall back to using the HashTransport instead of the NameTransport when not able to use any of the primary transports.
+ * @namespace easyXDM
+ * @constructor
+ * @cfg {String/Window} local The url to the local name.html document, a local static file, or a reference to the local window.
+ * @cfg {Boolean} lazy (Consumer only) Set this to true if you want easyXDM to defer creating the transport until really needed. 
+ * @cfg {String} remote (Consumer only) The url to the providers document.
+ * @cfg {String} remoteHelper (Consumer only) The url to the remote name.html file. This is to support NameTransport as a fallback. Optional.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.  Optional, defaults to 2000.
+ * @cfg {Number} interval The interval used when polling for messages. Optional, defaults to 300.
+ * @cfg {String} channel (Consumer only) The name of the channel to use. Can be used to set consistent iframe names. Must be unique. Optional.
+ * @cfg {Function} onMessage The method that should handle incoming messages.<br/> This method should accept two arguments, the message as a string, and the origin as a string. Optional.
+ * @cfg {Function} onReady A method that should be called when the transport is ready. Optional.
+ * @cfg {DOMElement|String} container (Consumer only) The element, or the id of the element that the primary iframe should be inserted into. If not set then the iframe will be positioned off-screen. Optional.
+ * @cfg {Array/String} acl (Provider only) Here you can specify which '[protocol]://[domain]' patterns that should be allowed to act as the consumer towards this provider.<br/>
+ * This can contain the wildcards ? and *.  Examples are 'http://example.com', '*.foo.com' and '*dom?.com'. If you want to use reqular expressions then you pattern needs to start with ^ and end with $.
+ * If none of the patterns match an Error will be thrown.  
+ * @cfg {Object} props (Consumer only) Additional properties that should be applied to the iframe. This can also contain nested objects e.g: <code>{style:{width:"100px", height:"100px"}}</code>. 
+ * Properties such as 'name' and 'src' will be overrided. Optional.
+ */
+easyXDM.Socket = function(config){
+    var trace = debug.getTracer("easyXDM.Socket");
+    trace("constructor");
+    
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([{
+        incoming: function(message, origin){
+            config.onMessage(message, origin);
+        },
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }])), recipient = getLocation(config.remote);
+    
+    // set the origin
+    this.origin = getLocation(config.remote);
+	
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    /**
+     * Posts a message to the remote end of the channel
+     * @param {String} message The message to send
+     */
+    this.postMessage = function(message){
+        stack.outgoing(message, recipient);
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef,, chainStack, prepareTransportStack, debug, getLocation */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/** 
+ * @class easyXDM.Rpc
+ * Creates a proxy object that can be used to call methods implemented on the remote end of the channel, and also to provide the implementation
+ * of methods to be called from the remote end.<br/>
+ * The instantiated object will have methods matching those specified in <code>config.remote</code>.<br/>
+ * This requires the JSON object present in the document, either natively, using json.org's json2 or as a wrapper around library spesific methods.
+ * <h2>How to set up</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; &#47;&#47; this configuration is equal to that used by the Socket.
+ * &nbsp; remote: "http:&#47;&#47;remotedomain/...",
+ * &nbsp; onReady: function(){
+ * &nbsp; &nbsp; &#47;&#47; you need to wait for the onReady callback before using the proxy
+ * &nbsp; &nbsp; rpc.foo(...
+ * &nbsp; }
+ * },{
+ * &nbsp; local: {..},
+ * &nbsp; remote: {..}
+ * });
+ * </code></pre>
+ * 
+ * <h2>Exposing functions (procedures)</h2>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {
+ * &nbsp; &nbsp; nameOfMethod: {
+ * &nbsp; &nbsp; &nbsp; method: function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; &nbsp; &nbsp; ...
+ * &nbsp; &nbsp; &nbsp; }
+ * &nbsp; &nbsp; },
+ * &nbsp; &nbsp; &#47;&#47; with shorthand notation 
+ * &nbsp; &nbsp; nameOfAnotherMethod:  function(arg1, arg2, success, error){
+ * &nbsp; &nbsp; }
+ * &nbsp; },
+ * &nbsp; remote: {...}
+ * });
+ * </code></pre>
+
+ * The function referenced by  [method] will receive the passed arguments followed by the callback functions <code>success</code> and <code>error</code>.<br/>
+ * To send a successfull result back you can use
+ *     <pre><code>
+ *     return foo;
+ *     </pre></code>
+ * or
+ *     <pre><code>
+ *     success(foo);
+ *     </pre></code>
+ *  To return an error you can use
+ *     <pre><code>
+ *     throw new Error("foo error");
+ *     </code></pre>
+ * or
+ *     <pre><code>
+ *     error("foo error");
+ *     </code></pre>
+ *
+ * <h2>Defining remotely exposed methods (procedures/notifications)</h2>
+ * The definition of the remote end is quite similar:
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {
+ * &nbsp; &nbsp; nameOfMethod: {}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * To call a remote method use
+ * <pre><code>
+ * rpc.nameOfMethod("arg1", "arg2", function(value) {
+ * &nbsp; alert("success: " + value);
+ * }, function(message) {
+ * &nbsp; alert("error: " + message + );
+ * });
+ * </code></pre>
+ * Both the <code>success</code> and <code>errror</code> callbacks are optional.<br/>
+ * When called with no callback a JSON-RPC 2.0 notification will be executed.
+ * Be aware that you will not be notified of any errors with this method.
+ * <br/>
+ * <h2>Specifying a custom serializer</h2>
+ * If you do not want to use the JSON2 library for non-native JSON support, but instead capabilities provided by some other library
+ * then you can specify a custom serializer using <code>serializer: foo</code>
+ * <pre><code>
+ * var rpc = new easyXDM.Rpc({
+ * &nbsp; ...
+ * },{
+ * &nbsp; local: {...},
+ * &nbsp; remote: {...},
+ * &nbsp; serializer : {
+ * &nbsp; &nbsp; parse: function(string){ ... },
+ * &nbsp; &nbsp; stringify: function(object) {...}
+ * &nbsp; }
+ * });
+ * </code></pre>
+ * If <code>serializer</code> is set then the class will not attempt to use the native implementation.
+ * @namespace easyXDM
+ * @constructor
+ * @param {Object} config The underlying transports configuration. See easyXDM.Socket for available parameters.
+ * @param {Object} jsonRpcConfig The description of the interface to implement.
+ */
+easyXDM.Rpc = function(config, jsonRpcConfig){
+    var trace = debug.getTracer("easyXDM.Rpc");
+    trace("constructor");
+    
+    // expand shorthand notation
+    if (jsonRpcConfig.local) {
+        for (var method in jsonRpcConfig.local) {
+            if (jsonRpcConfig.local.hasOwnProperty(method)) {
+                var member = jsonRpcConfig.local[method];
+                if (typeof member === "function") {
+                    jsonRpcConfig.local[method] = {
+                        method: member
+                    };
+                }
+            }
+        }
+    }
+	
+    // create the stack
+    var stack = chainStack(prepareTransportStack(config).concat([new easyXDM.stack.RpcBehavior(this, jsonRpcConfig), {
+        callback: function(success){
+            if (config.onReady) {
+                config.onReady(success);
+            }
+        }
+    }]));
+	
+    // set the origin 
+    this.origin = getLocation(config.remote);
+	
+    
+    /**
+     * Initiates the destruction of the stack.
+     */
+    this.destroy = function(){
+        stack.destroy();
+    };
+    
+    stack.init();
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, getParentObject, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.SameOriginTransport
+ * SameOriginTransport is a transport class that can be used when both domains have the same origin.<br/>
+ * This can be useful for testing and for when the main application supports both internal and external sources.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.SameOriginTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.SameOriginTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send(message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: location.protocol + "//" + location.host + location.pathname,
+                        xdm_c: config.channel,
+                        xdm_p: 4 // 4 = SameOriginTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                easyXDM.Fn.set(config.channel, function(sendFn){
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                });
+            }
+            else {
+                send = getParentObject().Fn.get(config.channel, true)(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global global, easyXDM, window, getLocation, appendQueryParameters, createFrame, debug, apply, whenReady, IFRAME_PREFIX, namespace, resolveUrl, getDomainName, HAS_FLASH_THROTTLED_BUG, getPort, query*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FlashTransport
+ * FlashTransport is a transport class that uses an SWF with LocalConnection to pass messages back and forth.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ * @cfg {String} secret the pre-shared secret used to secure the communication.
+ * @cfg {String} swf The path to the swf file
+ * @cfg {Boolean} swfNoThrottle Set this to true if you want to take steps to avoid beeing throttled when hidden.
+ * @cfg {String || DOMElement} swfContainer Set this if you want to control where the swf is placed
+ */
+easyXDM.stack.FlashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FlashTransport");
+    trace("constructor");
+    if (!config.swf) {
+        throw new Error("Path to easyxdm.swf is missing");
+    }
+    var pub, // the public interface
+ frame, send, targetOrigin, swf, swfContainer;
+    
+    function onMessage(message, origin){
+        setTimeout(function(){
+            trace("received message");
+            pub.up.incoming(message, targetOrigin);
+        }, 0);
+    }
+    
+    /**
+     * This method adds the SWF to the DOM and prepares the initialization of the channel
+     */
+    function addSwf(domain){
+        trace("creating factory with SWF from " + domain);
+        // the differentiating query argument is needed in Flash9 to avoid a caching issue where LocalConnection would throw an error.
+        var url = config.swf + "?host=" + config.isHost;
+        var id = "easyXDM_swf_" + Math.floor(Math.random() * 10000);
+        
+        // prepare the init function that will fire once the swf is ready
+        easyXDM.Fn.set("flash_loaded" + domain.replace(/[\-.]/g, "_"), function(){
+            easyXDM.stack.FlashTransport[domain].swf = swf = swfContainer.firstChild;
+            var queue = easyXDM.stack.FlashTransport[domain].queue;
+            for (var i = 0; i < queue.length; i++) {
+                queue[i]();
+            }
+            queue.length = 0;
+        });
+        
+        if (config.swfContainer) {
+            swfContainer = (typeof config.swfContainer == "string") ? document.getElementById(config.swfContainer) : config.swfContainer;
+        }
+        else {
+            // create the container that will hold the swf
+            swfContainer = document.createElement('div');
+            
+            // http://bugs.adobe.com/jira/browse/FP-4796
+            // http://tech.groups.yahoo.com/group/flexcoders/message/162365
+            // https://groups.google.com/forum/#!topic/easyxdm/mJZJhWagoLc
+            apply(swfContainer.style, HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle ? {
+                height: "20px",
+                width: "20px",
+                position: "fixed",
+                right: 0,
+                top: 0
+            } : {
+                height: "1px",
+                width: "1px",
+                position: "absolute",
+                overflow: "hidden",
+                right: 0,
+                top: 0
+            });
+            document.body.appendChild(swfContainer);
+        }
+        
+        // create the object/embed
+        var flashVars = "callback=flash_loaded" + domain.replace(/[\-.]/g, "_") + "&proto=" + global.location.protocol + "&domain=" + getDomainName(global.location.href) + "&port=" + getPort(global.location.href) + "&ns=" + namespace;
+        flashVars += "&log=true";
+        swfContainer.innerHTML = "<object height='20' width='20' type='application/x-shockwave-flash' id='" + id + "' data='" + url + "'>" +
+        "<param name='allowScriptAccess' value='always'></param>" +
+        "<param name='wmode' value='transparent'>" +
+        "<param name='movie' value='" +
+        url +
+        "'></param>" +
+        "<param name='flashvars' value='" +
+        flashVars +
+        "'></param>" +
+        "<embed type='application/x-shockwave-flash' FlashVars='" +
+        flashVars +
+        "' allowScriptAccess='always' wmode='transparent' src='" +
+        url +
+        "' height='1' width='1'></embed>" +
+        "</object>";
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            swf.postMessage(config.channel, message.toString());
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            try {
+                swf.destroyChannel(config.channel);
+            } 
+            catch (e) {
+            }
+            swf = null;
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            
+            targetOrigin = config.remote;
+            
+            // Prepare the code that will be run after the swf has been intialized
+            easyXDM.Fn.set("flash_" + config.channel + "_init", function(){
+                setTimeout(function(){
+                    trace("firing onReady");
+                    pub.up.callback(true);
+                });
+            });
+            
+            // set up the omMessage handler
+            easyXDM.Fn.set("flash_" + config.channel + "_onMessage", onMessage);
+            
+            config.swf = resolveUrl(config.swf); // reports have been made of requests gone rogue when using relative paths
+            var swfdomain = getDomainName(config.swf);
+            var fn = function(){
+                // set init to true in case the fn was called was invoked from a separate instance
+                easyXDM.stack.FlashTransport[swfdomain].init = true;
+                swf = easyXDM.stack.FlashTransport[swfdomain].swf;
+                // create the channel
+                swf.createChannel(config.channel, config.secret, getLocation(config.remote), config.isHost);
+                
+                if (config.isHost) {
+                    // if Flash is going to be throttled and we want to avoid this
+                    if (HAS_FLASH_THROTTLED_BUG && config.swfNoThrottle) {
+                        apply(config.props, {
+                            position: "fixed",
+                            right: 0,
+                            top: 0,
+                            height: "20px",
+                            width: "20px"
+                        });
+                    }
+                    // set up the iframe
+                    apply(config.props, {
+                        src: appendQueryParameters(config.remote, {
+                            xdm_e: getLocation(location.href),
+                            xdm_c: config.channel,
+                            xdm_p: 6, // 6 = FlashTransport
+                            xdm_s: config.secret
+                        }),
+                        name: IFRAME_PREFIX + config.channel + "_provider"
+                    });
+                    frame = createFrame(config);
+                }
+            };
+            
+            if (easyXDM.stack.FlashTransport[swfdomain] && easyXDM.stack.FlashTransport[swfdomain].init) {
+                // if the swf is in place and we are the consumer
+                fn();
+            }
+            else {
+                // if the swf does not yet exist
+                if (!easyXDM.stack.FlashTransport[swfdomain]) {
+                    // add the queue to hold the init fn's
+                    easyXDM.stack.FlashTransport[swfdomain] = {
+                        queue: [fn]
+                    };
+                    addSwf(swfdomain);
+                }
+                else {
+                    easyXDM.stack.FlashTransport[swfdomain].queue.push(fn);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.PostMessageTransport
+ * PostMessageTransport is a transport class that uses HTML5 postMessage for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx</a><br/>
+ * <a href="https://developer.mozilla.org/en/DOM/window.postMessage">https://developer.mozilla.org/en/DOM/window.postMessage</a>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote domain to communicate with.
+ */
+easyXDM.stack.PostMessageTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.PostMessageTransport");
+    trace("constructor");
+    var pub, // the public interface
+ frame, // the remote frame, if any
+ callerWindow, // the window that we will call with
+ targetOrigin; // the domain to communicate with
+    /**
+     * Resolves the origin from the event object
+     * @private
+     * @param {Object} event The messageevent
+     * @return {String} The scheme, host and port of the origin
+     */
+    function _getOrigin(event){
+        if (event.origin) {
+            // This is the HTML5 property
+            return getLocation(event.origin);
+        }
+        if (event.uri) {
+            // From earlier implementations 
+            return getLocation(event.uri);
+        }
+        if (event.domain) {
+            // This is the last option and will fail if the 
+            // origin is not using the same schema as we are
+            return location.protocol + "//" + event.domain;
+        }
+        throw "Unable to retrieve the origin of the event";
+    }
+    
+    /**
+     * This is the main implementation for the onMessage event.<br/>
+     * It checks the validity of the origin and passes the message on if appropriate.
+     * @private
+     * @param {Object} event The messageevent
+     */
+    function _window_onMessage(event){
+        var origin = _getOrigin(event);
+        trace("received message '" + event.data + "' from " + origin);
+        if (origin == targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
+            pub.up.incoming(event.data.substring(config.channel.length + 1), origin);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callerWindow.postMessage(config.channel + " " + message, domain || targetOrigin);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            un(window, "message", _window_onMessage);
+            if (frame) {
+                callerWindow = null;
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            if (config.isHost) {
+                // add the event handler for listening
+                var waitForReady = function(event){  
+                    if (event.data == config.channel + "-ready") {
+                        trace("firing onReady");
+                        // replace the eventlistener
+                        callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document;
+                        un(window, "message", waitForReady);
+                        on(window, "message", _window_onMessage);
+                        setTimeout(function(){
+                            pub.up.callback(true);
+                        }, 0);
+                    }
+                };
+                on(window, "message", waitForReady);
+                
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 1 // 1 = PostMessage
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+            }
+            else {
+                // add the event handler for listening
+                on(window, "message", _window_onMessage);
+                callerWindow = ("postMessage" in window.parent) ? window.parent : window.parent.document;
+                callerWindow.postMessage(config.channel + "-ready", targetOrigin);
+                
+                setTimeout(function(){
+                    pub.up.callback(true);
+                }, 0);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, appendQueryParameters, createFrame, debug, apply, query, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.FrameElementTransport
+ * FrameElementTransport is a transport class that can be used with Gecko-browser as these allow passing variables using the frameElement property.<br/>
+ * Security is maintained as Gecho uses Lexical Authorization to determine under which scope a function is running.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remote The remote document to communicate with.
+ */
+easyXDM.stack.FrameElementTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.FrameElementTransport");
+    trace("constructor");
+    var pub, frame, send, targetOrigin;
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            send.call(this, message);
+            if (fn) {
+                fn();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            if (frame) {
+                frame.parentNode.removeChild(frame);
+                frame = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            targetOrigin = getLocation(config.remote);
+            
+            if (config.isHost) {
+                // set up the iframe
+                apply(config.props, {
+                    src: appendQueryParameters(config.remote, {
+                        xdm_e: getLocation(location.href),
+                        xdm_c: config.channel,
+                        xdm_p: 5 // 5 = FrameElementTransport
+                    }),
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                frame = createFrame(config);
+                frame.fn = function(sendFn){
+                    delete frame.fn;
+                    send = sendFn;
+                    setTimeout(function(){
+                        pub.up.callback(true);
+                    }, 0);
+                    // remove the function so that it cannot be used to overwrite the send function later on
+                    return function(msg){
+                        pub.up.incoming(msg, targetOrigin);
+                    };
+                };
+            }
+            else {
+                // This is to mitigate origin-spoofing
+                if (document.referrer && getLocation(document.referrer) != query.xdm_e) {
+                    window.top.location = query.xdm_e;
+                }
+                send = window.frameElement.fn(function(msg){
+                    pub.up.incoming(msg, targetOrigin);
+                });
+                pub.up.callback(true);
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getLocation, appendQueryParameters, resolveUrl, createFrame, debug, un, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.NameTransport
+ * NameTransport uses the window.name property to relay data.
+ * The <code>local</code> parameter needs to be set on both the consumer and provider,<br/>
+ * and the <code>remoteHelper</code> parameter needs to be set on the consumer.
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String} remoteHelper The url to the remote instance of hash.html - this is only needed for the host.
+ * @namespace easyXDM.stack
+ */
+easyXDM.stack.NameTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.NameTransport");
+    trace("constructor");
+    if (config.isHost && undef(config.remoteHelper)) {
+        trace("missing remoteHelper");
+        throw new Error("missing remoteHelper");
+    }
+    
+    var pub; // the public interface
+    var isHost, callerWindow, remoteWindow, readyCount, callback, remoteOrigin, remoteUrl;
+    
+    function _sendMessage(message){
+        var url = config.remoteHelper + (isHost ? "#_3" : "#_2") + config.channel;
+        trace("sending message " + message);
+        trace("navigating to  '" + url + "'");
+        callerWindow.contentWindow.sendMessage(message, url);
+    }
+    
+    function _onReady(){
+        if (isHost) {
+            if (++readyCount === 2 || !isHost) {
+                pub.up.callback(true);
+            }
+        }
+        else {
+            _sendMessage("ready");
+            trace("calling onReady");
+            pub.up.callback(true);
+        }
+    }
+    
+    function _onMessage(message){
+        trace("received message " + message);
+        pub.up.incoming(message, remoteOrigin);
+    }
+    
+    function _onLoad(){
+        if (callback) {
+            setTimeout(function(){
+                callback(true);
+            }, 0);
+        }
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain, fn){
+            callback = fn;
+            _sendMessage(message);
+        },
+        destroy: function(){
+            trace("destroy");
+            callerWindow.parentNode.removeChild(callerWindow);
+            callerWindow = null;
+            if (isHost) {
+                remoteWindow.parentNode.removeChild(remoteWindow);
+                remoteWindow = null;
+            }
+        },
+        onDOMReady: function(){
+            trace("init");
+            isHost = config.isHost;
+            readyCount = 0;
+            remoteOrigin = getLocation(config.remote);
+            config.local = resolveUrl(config.local);
+            
+            if (isHost) {
+                // Register the callback
+                easyXDM.Fn.set(config.channel, function(message){
+                    trace("received initial message " + message);
+                    if (isHost && message === "ready") {
+                        // Replace the handler
+                        easyXDM.Fn.set(config.channel, _onMessage);
+                        _onReady();
+                    }
+                });
+                
+                // Set up the frame that points to the remote instance
+                remoteUrl = appendQueryParameters(config.remote, {
+                    xdm_e: config.local,
+                    xdm_c: config.channel,
+                    xdm_p: 2
+                });
+                apply(config.props, {
+                    src: remoteUrl + '#' + config.channel,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                remoteWindow = createFrame(config);
+            }
+            else {
+                config.remoteHelper = config.remote;
+                easyXDM.Fn.set(config.channel, _onMessage);
+            }
+            
+            // Set up the iframe that will be used for the transport
+            var onLoad = function(){
+                // Remove the handler
+                var w = callerWindow || this;
+                un(w, "load", onLoad);
+                easyXDM.Fn.set(config.channel + "_load", _onLoad);
+                (function test(){
+                    if (typeof w.contentWindow.sendMessage == "function") {
+                        _onReady();
+                    }
+                    else {
+                        setTimeout(test, 50);
+                    }
+                }());
+            };
+            
+            callerWindow = createFrame({
+                props: {
+                    src: config.local + "#_4" + config.channel
+                },
+                onLoad: onLoad
+            });
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, getLocation, createFrame, debug, un, on, apply, whenReady, IFRAME_PREFIX*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.HashTransport
+ * HashTransport is a transport class that uses the IFrame URL Technique for communication.<br/>
+ * <a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx">http://msdn.microsoft.com/en-us/library/bb735305.aspx</a><br/>
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The transports configuration.
+ * @cfg {String/Window} local The url to the local file used for proxying messages, or the local window.
+ * @cfg {Number} delay The number of milliseconds easyXDM should try to get a reference to the local window.
+ * @cfg {Number} interval The interval used when polling for messages.
+ */
+easyXDM.stack.HashTransport = function(config){
+    var trace = debug.getTracer("easyXDM.stack.HashTransport");
+    trace("constructor");
+    var pub;
+    var me = this, isHost, _timer, pollInterval, _lastMsg, _msgNr, _listenerWindow, _callerWindow;
+    var useParent, _remoteOrigin;
+    
+    function _sendMessage(message){
+        trace("sending message '" + (_msgNr + 1) + " " + message + "' to " + _remoteOrigin);
+        if (!_callerWindow) {
+            trace("no caller window");
+            return;
+        }
+        var url = config.remote + "#" + (_msgNr++) + "_" + message;
+        ((isHost || !useParent) ? _callerWindow.contentWindow : _callerWindow).location = url;
+    }
+    
+    function _handleHash(hash){
+        _lastMsg = hash;
+        trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
+        pub.up.incoming(_lastMsg.substring(_lastMsg.indexOf("_") + 1), _remoteOrigin);
+    }
+    
+    /**
+     * Checks location.hash for a new message and relays this to the receiver.
+     * @private
+     */
+    function _pollHash(){
+        if (!_listenerWindow) {
+            return;
+        }
+        var href = _listenerWindow.location.href, hash = "", indexOf = href.indexOf("#");
+        if (indexOf != -1) {
+            hash = href.substring(indexOf);
+        }
+        if (hash && hash != _lastMsg) {
+            trace("poll: new message");
+            _handleHash(hash);
+        }
+    }
+    
+    function _attachListeners(){
+        trace("starting polling");
+        _timer = setInterval(_pollHash, pollInterval);
+    }
+    
+    return (pub = {
+        outgoing: function(message, domain){
+            _sendMessage(message);
+        },
+        destroy: function(){
+            window.clearInterval(_timer);
+            if (isHost || !useParent) {
+                _callerWindow.parentNode.removeChild(_callerWindow);
+            }
+            _callerWindow = null;
+        },
+        onDOMReady: function(){
+            isHost = config.isHost;
+            pollInterval = config.interval;
+            _lastMsg = "#" + config.channel;
+            _msgNr = 0;
+            useParent = config.useParent;
+            _remoteOrigin = getLocation(config.remote);
+            if (isHost) {
+                apply(config.props, {
+                    src: config.remote,
+                    name: IFRAME_PREFIX + config.channel + "_provider"
+                });
+                if (useParent) {
+                    config.onLoad = function(){
+                        _listenerWindow = window;
+                        _attachListeners();
+                        pub.up.callback(true);
+                    };
+                }
+                else {
+                    var tries = 0, max = config.delay / 50;
+                    (function getRef(){
+                        if (++tries > max) {
+                            trace("unable to get reference to _listenerWindow, giving up");
+                            throw new Error("Unable to reference listenerwindow");
+                        }
+                        try {
+                            _listenerWindow = _callerWindow.contentWindow.frames[IFRAME_PREFIX + config.channel + "_consumer"];
+                        } 
+                        catch (ex) {
+                        }
+                        if (_listenerWindow) {
+                            _attachListeners();
+                            trace("got a reference to _listenerWindow");
+                            pub.up.callback(true);
+                        }
+                        else {
+                            setTimeout(getRef, 50);
+                        }
+                    }());
+                }
+                _callerWindow = createFrame(config);
+            }
+            else {
+                _listenerWindow = window;
+                _attachListeners();
+                if (useParent) {
+                    _callerWindow = parent;
+                    pub.up.callback(true);
+                }
+                else {
+                    apply(config, {
+                        props: {
+                            src: config.remote + "#" + config.channel + new Date(),
+                            name: IFRAME_PREFIX + config.channel + "_consumer"
+                        },
+                        onLoad: function(){
+                            pub.up.callback(true);
+                        }
+                    });
+                    _callerWindow = createFrame(config);
+                }
+            }
+        },
+        init: function(){
+            whenReady(pub.onDOMReady, pub);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.ReliableBehavior
+ * This is a behavior that tries to make the underlying transport reliable by using acknowledgements.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ */
+easyXDM.stack.ReliableBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.ReliableBehavior");
+    trace("constructor");
+    var pub, // the public interface
+ callback; // the callback to execute when we have a confirmed success/failure
+    var idOut = 0, idIn = 0, currentMessage = "";
+    
+    return (pub = {
+        incoming: function(message, origin){
+            trace("incoming: " + message);
+            var indexOf = message.indexOf("_"), ack = message.substring(0, indexOf).split(",");
+            message = message.substring(indexOf + 1);
+            
+            if (ack[0] == idOut) {
+                trace("message delivered");
+                currentMessage = "";
+                if (callback) {
+                    callback(true);
+                    callback = null;
+                }
+            }
+            if (message.length > 0) {
+                trace("sending ack, and passing on " + message);
+                pub.down.outgoing(ack[1] + "," + idOut + "_" + currentMessage, origin);
+                if (idIn != ack[1]) {
+                    idIn = ack[1];
+                    pub.up.incoming(message, origin);
+                }
+            }
+            
+        },
+        outgoing: function(message, origin, fn){
+            currentMessage = message;
+            callback = fn;
+            pub.down.outgoing(idIn + "," + (++idOut) + "_" + message, origin);
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, debug, undef, removeFromStack*/
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.QueueBehavior
+ * This is a behavior that enables queueing of messages. <br/>
+ * It will buffer incoming messages and dispach these as fast as the underlying transport allows.
+ * This will also fragment/defragment messages so that the outgoing message is never bigger than the
+ * set length.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration. Optional.
+ * @cfg {Number} maxLength The maximum length of each outgoing message. Set this to enable fragmentation.
+ */
+easyXDM.stack.QueueBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.QueueBehavior");
+    trace("constructor");
+    var pub, queue = [], waiting = true, incoming = "", destroying, maxLength = 0, lazy = false, doFragment = false;
+    
+    function dispatch(){
+        if (config.remove && queue.length === 0) {
+            trace("removing myself from the stack");
+            removeFromStack(pub);
+            return;
+        }
+        if (waiting || queue.length === 0 || destroying) {
+            return;
+        }
+        trace("dispatching from queue");
+        waiting = true;
+        var message = queue.shift();
+        
+        pub.down.outgoing(message.data, message.origin, function(success){
+            waiting = false;
+            if (message.callback) {
+                setTimeout(function(){
+                    message.callback(success);
+                }, 0);
+            }
+            dispatch();
+        });
+    }
+    return (pub = {
+        init: function(){
+            if (undef(config)) {
+                config = {};
+            }
+            if (config.maxLength) {
+                maxLength = config.maxLength;
+                doFragment = true;
+            }
+            if (config.lazy) {
+                lazy = true;
+            }
+            else {
+                pub.down.init();
+            }
+        },
+        callback: function(success){
+            waiting = false;
+            var up = pub.up; // in case dispatch calls removeFromStack
+            dispatch();
+            up.callback(success);
+        },
+        incoming: function(message, origin){
+            if (doFragment) {
+                var indexOf = message.indexOf("_"), seq = parseInt(message.substring(0, indexOf), 10);
+                incoming += message.substring(indexOf + 1);
+                if (seq === 0) {
+                    trace("received the last fragment");
+                    if (config.encode) {
+                        incoming = decodeURIComponent(incoming);
+                    }
+                    pub.up.incoming(incoming, origin);
+                    incoming = "";
+                }
+                else {
+                    trace("waiting for more fragments, seq=" + message);
+                }
+            }
+            else {
+                pub.up.incoming(message, origin);
+            }
+        },
+        outgoing: function(message, origin, fn){
+            if (config.encode) {
+                message = encodeURIComponent(message);
+            }
+            var fragments = [], fragment;
+            if (doFragment) {
+                // fragment into chunks
+                while (message.length !== 0) {
+                    fragment = message.substring(0, maxLength);
+                    message = message.substring(fragment.length);
+                    fragments.push(fragment);
+                }
+                // enqueue the chunks
+                while ((fragment = fragments.shift())) {
+                    trace("enqueuing");
+                    queue.push({
+                        data: fragments.length + "_" + fragment,
+                        origin: origin,
+                        callback: fragments.length === 0 ? fn : null
+                    });
+                }
+            }
+            else {
+                queue.push({
+                    data: message,
+                    origin: origin,
+                    callback: fn
+                });
+            }
+            if (lazy) {
+                pub.down.init();
+            }
+            else {
+                dispatch();
+            }
+        },
+        destroy: function(){
+            trace("destroy");
+            destroying = true;
+            pub.down.destroy();
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, debug */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.VerifyBehavior
+ * This behavior will verify that communication with the remote end is possible, and will also sign all outgoing,
+ * and verify all incoming messages. This removes the risk of someone hijacking the iframe to send malicious messages.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} config The behaviors configuration.
+ * @cfg {Boolean} initiate If the verification should be initiated from this end.
+ */
+easyXDM.stack.VerifyBehavior = function(config){
+    var trace = debug.getTracer("easyXDM.stack.VerifyBehavior");
+    trace("constructor");
+    if (undef(config.initiate)) {
+        throw new Error("settings.initiate is not set");
+    }
+    var pub, mySecret, theirSecret, verified = false;
+    
+    function startVerification(){
+        trace("requesting verification");
+        mySecret = Math.random().toString(16).substring(2);
+        pub.down.outgoing(mySecret);
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var indexOf = message.indexOf("_");
+            if (indexOf === -1) {
+                if (message === mySecret) {
+                    trace("verified, calling callback");
+                    pub.up.callback(true);
+                }
+                else if (!theirSecret) {
+                    trace("returning secret");
+                    theirSecret = message;
+                    if (!config.initiate) {
+                        startVerification();
+                    }
+                    pub.down.outgoing(message);
+                }
+            }
+            else {
+                if (message.substring(0, indexOf) === theirSecret) {
+                    pub.up.incoming(message.substring(indexOf + 1), origin);
+                }
+            }
+        },
+        outgoing: function(message, origin, fn){
+            pub.down.outgoing(mySecret + "_" + message, origin, fn);
+        },
+        callback: function(success){
+            if (config.initiate) {
+                startVerification();
+            }
+        }
+    });
+};
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyXDM, window, escape, unescape, undef, getJSON, debug, emptyFn, isArray */
+//
+// easyXDM
+// http://easyxdm.net/
+// Copyright(c) 2009-2011, Øyvind Sean Kinsey, oyvind@kinsey.no.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ * @class easyXDM.stack.RpcBehavior
+ * This uses JSON-RPC 2.0 to expose local methods and to invoke remote methods and have responses returned over the the string based transport stack.<br/>
+ * Exposed methods can return values synchronous, asyncronous, or bet set up to not return anything.
+ * @namespace easyXDM.stack
+ * @constructor
+ * @param {Object} proxy The object to apply the methods to.
+ * @param {Object} config The definition of the local and remote interface to implement.
+ * @cfg {Object} local The local interface to expose.
+ * @cfg {Object} remote The remote methods to expose through the proxy.
+ * @cfg {Object} serializer The serializer to use for serializing and deserializing the JSON. Should be compatible with the HTML5 JSON object. Optional, will default to JSON.
+ */
+easyXDM.stack.RpcBehavior = function(proxy, config){
+    var trace = debug.getTracer("easyXDM.stack.RpcBehavior");
+    var pub, serializer = config.serializer || getJSON();
+    var _callbackCounter = 0, _callbacks = {};
+    
+    /**
+     * Serializes and sends the message
+     * @private
+     * @param {Object} data The JSON-RPC message to be sent. The jsonrpc property will be added.
+     */
+    function _send(data){
+        data.jsonrpc = "2.0";
+        pub.down.outgoing(serializer.stringify(data));
+    }
+    
+    /**
+     * Creates a method that implements the given definition
+     * @private
+     * @param {Object} The method configuration
+     * @param {String} method The name of the method
+     * @return {Function} A stub capable of proxying the requested method call
+     */
+    function _createMethod(definition, method){
+        var slice = Array.prototype.slice;
+        
+        trace("creating method " + method);
+        return function(){
+            trace("executing method " + method);
+            var l = arguments.length, callback, message = {
+                method: method
+            };
+            
+            if (l > 0 && typeof arguments[l - 1] === "function") {
+                //with callback, procedure
+                if (l > 1 && typeof arguments[l - 2] === "function") {
+                    // two callbacks, success and error
+                    callback = {
+                        success: arguments[l - 2],
+                        error: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 2);
+                }
+                else {
+                    // single callback, success
+                    callback = {
+                        success: arguments[l - 1]
+                    };
+                    message.params = slice.call(arguments, 0, l - 1);
+                }
+                _callbacks["" + (++_callbackCounter)] = callback;
+                message.id = _callbackCounter;
+            }
+            else {
+                // no callbacks, a notification
+                message.params = slice.call(arguments, 0);
+            }
+            if (definition.namedParams && message.params.length === 1) {
+                message.params = message.params[0];
+            }
+            // Send the method request
+            _send(message);
+        };
+    }
+    
+    /**
+     * Executes the exposed method
+     * @private
+     * @param {String} method The name of the method
+     * @param {Number} id The callback id to use
+     * @param {Function} method The exposed implementation
+     * @param {Array} params The parameters supplied by the remote end
+     */
+    function _executeMethod(method, id, fn, params){
+        if (!fn) {
+            trace("requested to execute non-existent procedure " + method);
+            if (id) {
+                _send({
+                    id: id,
+                    error: {
+                        code: -32601,
+                        message: "Procedure not found."
+                    }
+                });
+            }
+            return;
+        }
+        
+        trace("requested to execute procedure " + method);
+        var success, error;
+        if (id) {
+            success = function(result){
+                success = emptyFn;
+                _send({
+                    id: id,
+                    result: result
+                });
+            };
+            error = function(message, data){
+                error = emptyFn;
+                var msg = {
+                    id: id,
+                    error: {
+                        code: -32099,
+                        message: message
+                    }
+                };
+                if (data) {
+                    msg.error.data = data;
+                }
+                _send(msg);
+            };
+        }
+        else {
+            success = error = emptyFn;
+        }
+        // Call local method
+        if (!isArray(params)) {
+            params = [params];
+        }
+        try {
+            var result = fn.method.apply(fn.scope, params.concat([success, error]));
+            if (!undef(result)) {
+                success(result);
+            }
+        } 
+        catch (ex1) {
+            error(ex1.message);
+        }
+    }
+    
+    return (pub = {
+        incoming: function(message, origin){
+            var data = serializer.parse(message);
+            if (data.method) {
+                trace("received request to execute method " + data.method + (data.id ? (" using callback id " + data.id) : ""));
+                // A method call from the remote end
+                if (config.handle) {
+                    config.handle(data, _send);
+                }
+                else {
+                    _executeMethod(data.method, data.id, config.local[data.method], data.params);
+                }
+            }
+            else {
+                trace("received return value destined to callback with id " + data.id);
+                // A method response from the other end
+                var callback = _callbacks[data.id];
+                if (data.error) {
+                    if (callback.error) {
+                        callback.error(data.error);
+                    }
+                    else {
+                        trace("unhandled error returned.");
+                    }
+                }
+                else if (callback.success) {
+                    callback.success(data.result);
+                }
+                delete _callbacks[data.id];
+            }
+        },
+        init: function(){
+            trace("init");
+            if (config.remote) {
+                trace("creating stubs");
+                // Implement the remote sides exposed methods
+                for (var method in config.remote) {
+                    if (config.remote.hasOwnProperty(method)) {
+                        proxy[method] = _createMethod(config.remote[method], method);
+                    }
+                }
+            }
+            pub.down.init();
+        },
+        destroy: function(){
+            trace("destroy");
+            for (var method in config.remote) {
+                if (config.remote.hasOwnProperty(method) && proxy.hasOwnProperty(method)) {
+                    delete proxy[method];
+                }
+            }
+            pub.down.destroy();
+        }
+    });
+};
+global.easyXDM = easyXDM;
+})(window, document, location, window.setTimeout, decodeURIComponent, encodeURIComponent);
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/index.html b/asterix-examples/src/main/resources/js/easyXDM/tests/index.html
new file mode 100644
index 0000000..0232da9
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/index.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+        <meta http-equiv="X-UA-Compatible" content="IE=100">
+        <title>easyTest results</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // The first instance of easyXDM
+        </script>
+        <script type="text/javascript">
+            easyXDM._test_global = true;
+        </script>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+            // The second instance of easyXDM (to test noConflict)
+        </script>
+        <script type="text/javascript">
+            // Used in the noConflict test
+            var modules = {
+                easyXDM: easyXDM.noConflict("modules")
+            };
+        </script>
+        <script type="text/javascript">
+            if (location.href.indexOf("src") !== -1) {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../../tools/json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+            else {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+        </script>
+        <script type="text/javascript" src="easyTest.js">
+        </script>
+        <link type="text/css" rel="stylesheet" href="easyTest.css"/>
+        <script type="text/javascript" src="tests.js">
+        </script>
+        <style type="text/css">
+            
+            #embedded {
+                height: 100px;
+            }
+            
+            #embedded iframe {
+                height: 50px;
+            }
+            
+            #log {
+                height: 100px;
+                border: 1px dotted black;
+                overflow: auto
+            }
+            
+            .easyTest_messages {
+                height: 300px;
+                border: 1px dotted black;
+                overflow: auto;
+            }
+        </style>
+    </head>
+    <body onload="runTests();">
+        <h1>easyXDM test suite</h1>
+        <h4>easyTest messages</h4>
+        <div id="messages">
+        </div>
+        <h4>easyXDM tracelog</h4>
+        <!-- easyXDM.Debug.trace(msg) will output its messages to any element with the id "log" -->
+        <div id="log">
+        </div>
+        <div id="embedded">
+        </div>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+                document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+            }
+        </script>
+        <script type="text/javascript">
+            if (location.host.indexOf("easyxdm.net") !== -1) {
+                try {
+                    var pageTracker = _gat._getTracker("UA-9535591-3");
+                    pageTracker._setDomainName(".easyxdm.net");
+                    pageTracker._trackPageview();
+                } 
+                catch (err) {
+                }
+            }
+        </script>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif b/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/s.gif
Binary files differ
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html
new file mode 100644
index 0000000..63d7a3e
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_namespace.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var modules = {
+                easyXDM: easyXDM.noConflict("modules")
+            };
+            
+            var transport;
+            window.onload = function(){
+                transport = new modules.easyXDM.Socket({
+                    local: "../name.html",
+                    swf: "../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        // Echo back the message
+                        transport.postMessage(message);
+                    }
+                });
+            };
+            window.onunload = function(){
+                if (transport) {
+                    transport.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html
new file mode 100644
index 0000000..11a489f
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_rpc.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            if (location.href.indexOf("src") !== -1) {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../../tools/json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+            else {
+                if (typeof JSON === "undefined") {
+                    document.write(unescape("%3Cscript src='../json2.js' type='text/javascript'%3E%3C/script%3E"));
+                }
+            }
+        </script>
+        <script type="text/javascript">
+            easyXDM.DomHelper.requiresJSON("../json2.js");
+        </script>
+        <script type="text/javascript">
+            var remote = new easyXDM.Rpc({
+                local: "../name.html",
+                swf: "../easyxdm.swf"
+            }, {
+                remote: {
+                    voidCallback: {}
+                },
+                local: {
+                    voidMethod: function(msg){
+                        // Echo back the message
+                        remote.voidCallback(msg);
+                    },
+                    asyncMethod: function(msg, fn){
+                        window.setTimeout(function(){
+                            // Echo back the msg
+                            fn(msg);
+                        }, 100);
+                    },
+                    // use the shorthand notation
+                    method: function(msg){
+                        // Echo back the msg
+                        return msg;
+                    },
+                    error: function(){
+                        var a, b = a.c;
+                    },
+                    namedParamsMethod: {
+                        method: function(params){
+                            return params.msg;
+                        }
+                    }
+                }
+            });
+            window.onunload = function(){
+                if (remote) {
+                    remote.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html b/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html
new file mode 100644
index 0000000..eb405cf
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/test_transport.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+    <head>
+        <title>easyXDM</title>
+        <script type="text/javascript" src="../easyXDM.debug.js">
+        </script>
+        <script type="text/javascript">
+            var transport;
+            window.onload = function(){
+                transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: "../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        // Echo back the message
+                        transport.postMessage(message);
+                    }
+                });
+            };
+            window.onunload = function(){
+                if (transport) {
+                    transport.destroy();
+                }
+            };
+        </script>
+    </head>
+    <body>
+    </body>
+</html>
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js b/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js
new file mode 100644
index 0000000..d0a940a
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/tests.js
@@ -0,0 +1,855 @@
+/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
+/*global easyTest, easyXDM, window, modules*/
+var REMOTE = (function(){
+    var remote = location.href;
+    switch (location.host) {
+        case "provider.easyxdm.net":
+            location.href = remote.replace("provider", "consumer");
+            break;
+        case "easyxdm.net":
+            remote = remote.replace("easyxdm.net", "consumer.easyxdm.net");
+            break;
+        case "consumer.easyxdm.net":
+            remote = remote.replace("consumer", "provider");
+            break;
+        case "xdm1":
+            remote = remote.replace("xdm1", "xdm2");
+            break;
+    }
+    return remote.substring(0, remote.lastIndexOf("/"));
+}());
+
+var LOCAL = location.protocol + "//" + location.host + location.pathname.substring(0, location.pathname.lastIndexOf("/"));
+
+function runTests(){
+    var i = 0;
+    easyTest.test([/**Tests for the presence of namespaces and classes*/{
+        name: "Check that the library is complete",
+        steps: [{
+            name: "check for the presence of easyXDM",
+            run: function(){
+                if (this.Assert.isObject(easyXDM) && this.Assert.isString(easyXDM.version)) {
+                    this.log("found easyXDM, version=" + easyXDM.version);
+                    return true;
+                }
+                return false;
+            }
+        }, {
+            name: "check for the presence of easyXDM.DomHelper",
+            run: function(){
+                return this.Assert.isObject(easyXDM.DomHelper);
+            }
+        }, {
+            name: "check for the presence of easyXDM.Socket",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.Socket);
+            }
+        }, {
+            name: "check for the presence of easyXDM.Rpc",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.Rpc);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack",
+            run: function(){
+                return this.Assert.isObject(easyXDM.stack);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.SameOriginTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.SameOriginTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.PostMessageTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.PostMessageTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.FlashTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.FlashTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.NameTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.NameTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.HashTransport",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.HashTransport);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.ReliableBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.ReliableBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.QueueBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.QueueBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.VerifyBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.VerifyBehavior);
+            }
+        }, {
+            name: "check for the presence of easyXDM.stack.RpcBehavior",
+            run: function(){
+                return this.Assert.isFunction(easyXDM.stack.RpcBehavior);
+            }
+        }]
+    }, {
+        name: "Check helper functions",
+        runIf: function(){
+            if (location.href.indexOf("/src/") == -1) {
+                return "This can only be run in development.";
+            }
+        },
+        setUp: function(){
+            this.url1 = "http://foo.bar/a/b/c?d=e#f";
+            this.url2 = "http://foo.bar:80/a/b/c?d=e#f";
+            this.url3 = "http://foo.bar:88/a/b/c?d=e#f";
+            this.url4 = "hTtp://Foo.Bar:88/a/b/c?d=e#f";
+            
+        },
+        steps: [{
+            name: "getDomainName",
+            run: function(){
+                return easyXDM.getDomainName(this.url1) === "foo.bar";
+            }
+        }, {
+            name: "getLocation",
+            run: function(){
+                return easyXDM.getLocation(this.url1) === "http://foo.bar";
+            }
+        }, {
+            name: "getLocation with standard port",
+            run: function(){
+                return easyXDM.getLocation(this.url2) === "http://foo.bar";
+            }
+        }, {
+            name: "getLocation with non-standard port",
+            run: function(){
+                return easyXDM.getLocation(this.url3) === "http://foo.bar:88";
+            }
+        }, {
+            name: "getLocation with capitals",
+            run: function(){
+                return easyXDM.getLocation(this.url4) === "http://foo.bar:88";
+            }
+        }, {
+            name: "appendQueryParameters",
+            run: function(){
+                return easyXDM.appendQueryParameters(this.url2, {
+                    g: "h"
+                }) ===
+                "http://foo.bar:80/a/b/c?d=e&g=h#f";
+            }
+        }]
+    }, {
+        name: "Check the ACL feature",
+        runIf: function(){
+            if (location.href.indexOf("/src/") == -1) {
+                return "This can only be run in development.";
+            }
+        },
+        setUp: function(){
+            this.acl = ["http://www.domain.invalid", "*.domaina.com", "http://dom?inb.com", "^http://domc{3}ain\\.com$"];
+        },
+        steps: [{
+            name: "Match complete string",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://www.domain.invalid");
+            }
+        }, {
+            name: "Match *",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://www.domaina.com");
+            }
+        }, {
+            name: "Match ?",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://domainb.com");
+            }
+        }, {
+            name: "Match RegExp",
+            run: function(){
+                return easyXDM.checkAcl(this.acl, "http://domcccain.com");
+            }
+        }, {
+            name: "No match",
+            run: function(){
+                return !easyXDM.checkAcl(this.acl, "http://foo.com");
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{SameOriginTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "4",
+                    remote: LOCAL + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{PostMessageTransport}",
+        runIf: function(){
+            if (!("postMessage" in window || "postMessage" in document)) {
+                return "This test requires the HTML5 postMessage interface.";
+            }
+        },
+        
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "1",
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{FlashTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "6",
+                    remote: REMOTE + "/test_transport.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: "embedded",
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{FrameElementTransport}",
+        runIf: function(){
+            if (!(navigator.product === "Gecko" && "frameElement" in window && !("postMessage" in window) && navigator.userAgent.indexOf('WebKit') == -1)) {
+                return "This test requires an older Gecko browser and the presence of the frameElement object";
+            }
+        },
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "5",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{NameTransport}",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "2", // This is just to override the automatic selection
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} using window",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: window,
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with no blank local, available image and resize",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+            this.img = document.createElement("img");
+            this.img.src = "s.gif";
+            document.body.appendChild(this.img);
+        },
+        tearDown: function(){
+            document.body.removeChild(this.img);
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (++messages === 2) {
+                            scope.notifyResult(true);
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with s.gif and polling",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: "s.gif",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        if (++messages === 2) {
+                            scope.notifyResult(true);
+                        }
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{HashTransport} with fragmentation (8192)",
+        failedMessage: "This might fail in modern browsers due to restrictions in referencing existing windows",
+        setUp: function(){
+            var i = 11;
+            this.expectedMessage = "aaaa";
+            while (i--) {
+                this.expectedMessage += this.expectedMessage;
+            }
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    protocol: "0", // This is just to override the automatic selection
+                    local: "../name.html",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult(scope.expectedMessage === message);
+                    },
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.noConflict {SameOriginTransport}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        steps: [{
+            name: "window.easyXDM is released {namespace}",
+            timeout: 5000,
+            run: function(){
+                this.notifyResult(window.easyXDM._test_global && !modules.easyXDM._test_global);
+            }
+        }, {
+            name: "onReady is fired {namespace}",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                var messages = 0;
+                this.transport = new modules.easyXDM.Socket({
+                    protocol: "4",
+                    remote: LOCAL + "/test_namespace.html",
+                    onMessage: function(message, origin){
+                        if (scope.expectedMessage === message) {
+                            if (++messages === 2) {
+                                scope.notifyResult(true);
+                            }
+                        }
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back {namespace}",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }, {
+            name: "destroy {namespace}",
+            run: function(){
+                this.transport.destroy();
+                return ((document.getElementsByTagName("iframe").length === 0));
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{}",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} using hash for passing data",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html?foo=bar",
+                    hash: true,
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} with buffering",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "Buffered messages are sent",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    }
+                });
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Socket{} with query parameters",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.transport.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.transport = new easyXDM.Socket({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_transport.html?a=b&c=d#foo,faa",
+                    onMessage: function(message, origin){
+                        scope.notifyResult((scope.expectedMessage === message));
+                    },
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                });
+            }
+        }, {
+            name: "message is echoed back",
+            timeout: 5000,
+            run: function(){
+                this.transport.postMessage(this.expectedMessage);
+            }
+        }]
+    }, {
+        name: "test easyXDM.Rpc",
+        setUp: function(){
+            this.expectedMessage = ++i + "_abcd1234%@¤/";
+        },
+        tearDown: function(){
+            this.remote.destroy();
+            if (document.getElementsByTagName("iframe").length !== 0) {
+                throw new Error("iframe still present");
+            }
+        },
+        steps: [{
+            name: "onReady is fired",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote = new easyXDM.Rpc({
+                    local: "../name.html",
+                    swf: REMOTE + "/../easyxdm.swf",
+                    remote: REMOTE + "/test_rpc.html",
+                    remoteHelper: REMOTE + "/../name.html",
+                    container: document.getElementById("embedded"),
+                    onReady: function(){
+                        scope.notifyResult(true);
+                    }
+                }, {
+                    remote: {
+                        voidMethod: {},
+                        asyncMethod: {},
+                        method: {},
+                        error: {},
+                        nonexistent: {},
+                        namedParamsMethod: {
+                            namedParams: true
+                        }
+                    },
+                    local: {
+                        voidCallback: {
+                            method: function(message){
+                                scope.notifyResult((scope.expectedMessage === message));
+                            }
+                        }
+                    }
+                });
+            }
+        }, {
+            name: "void method",
+            timeout: 5000,
+            run: function(){
+                this.remote.voidMethod(this.expectedMessage);
+            }
+        }, {
+            name: "async method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.asyncMethod(this.expectedMessage, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }, {
+            name: "regular method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.method(this.expectedMessage, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }, {
+            name: "with error",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.error(this.expectedMessage, function(){
+                    this.notifyResult(false, "success handler called");
+                }, function(message){
+                    scope.notifyResult(true);
+                });
+            }
+        }, {
+            name: "calling nonexistent method",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.nonexistent(this.expectedMessage, function(){
+                    this.notifyResult(false, "success handler called");
+                }, function(message){
+                    scope.notifyResult(true);
+                });
+            }
+        }, {
+            name: "using named parameters",
+            timeout: 5000,
+            run: function(){
+                var scope = this;
+                this.remote.namedParamsMethod({
+                    msg: this.expectedMessage
+                }, function(message){
+                    scope.notifyResult((scope.expectedMessage === message));
+                });
+            }
+        }]
+    }]);
+}
diff --git a/asterix-examples/src/main/resources/js/example.js b/asterix-examples/src/main/resources/js/example.js
index e69de29..cf5d02b 100644
--- a/asterix-examples/src/main/resources/js/example.js
+++ b/asterix-examples/src/main/resources/js/example.js
@@ -0,0 +1,39 @@
+var tinySocialCreate = ["drop dataverse TinySocial if exists;",
+"create dataverse TinySocial;",
+"use dataverse TinySocial;",
+"create type TwitterUserType as open {",
+"screen-name: string,",
+"lang: string,",
+"friends_count: int32,",
+"statuses_count: int32,",
+"name: string,",
+"followers_count: int32",
+"}",
+"create type TweetMessageType as closed {",
+"tweetid: string,",
+"user: TwitterUserType,",
+"sender-location: point?,",
+"send-time: datetime,",
+"referred-topics: {{ string }},",
+"message-text: string",
+"}",
+"create type EmploymentType as open {",
+"organization-name: string,",
+"start-date: date,",
+"end-date: date?",
+"}",
+"create type FacebookUserType as closed {",
+"id: int32,",
+"alias: string,",
+"name: string,",
+"user-since: datetime,",
+"friend-ids: {{ int32 }},",
+"employment: [EmploymentType]",
+"}",
+"create type FacebookMessageType as closed {",
+"message-id: int32,",
+"author-id: int32,",
+"in-response-to: int32?,",
+"sender-location: point?,",
+"message: string",
+"}"];
