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);
