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