diff --git a/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js b/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js
deleted file mode 100755
index 9553997..0000000
--- a/asterix-app/src/main/resources/sdk/static/cherry/js/asterix-api-core.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/** 
-* Asterix Core API
-* @returns  {AsterixCoreAPI}    AsterixCoreAPI
-*/
-function AsterixCoreAPI() {
-    this.parameters = {
-        "statements"    : [],
-        "mode"          : "synchronous"
-    };
-    this.ui_callback_on_success = function() {};
-    this.ui_callback_on_success_async = function() {};
-    this.on_error = function() {};
-    this.extra = {};
-    return this;
-}
-
-/** Parameter Management **/
-
-/**
-* Sets the dataverse of this Asterix API call
-* @param    {String}            dataverse
-* @returns  {AsterixCoreAPI}    AsterixCoreAPI 
-*/
-AsterixCoreAPI.prototype.dataverse = function (dataverse) {
-    this.dataverse = dataverse;
-    return this;
-}
-
-/**
-* Set the on-success callback of the api call
-* @param    {Function}          on_success
-* @param    {Boolean}           is_synchronous
-* @returns  {AsterixCoreAPI}    AsterixCoreAPI 
-*/
-AsterixCoreAPI.prototype.success = function(on_success, is_synchronous) {
-    if (is_synchronous) {
-        this.ui_callback_on_success = on_success;
-    } else {
-        this.ui_callback_on_success_async = on_success;
-    }
-    
-    return this;
-}
-
-/**
-* Set the on-error callback of the api call
-* @param    {Function}          on_error
-* @returns  {AsterixCoreAPI}    AsterixCoreAPI 
-*/
-AsterixCoreAPI.prototype.error = function(on_error) {
-    this.on_error = on_error;
-    return this;
-}
-
-/**
-* Sets a parameter key, value
-* @param    {String}            param_key
-* @param    {Object}            param_value
-* @returns  {AsterixCoreAPI}    AsterixCoreAPI  
-*/
-AsterixCoreAPI.prototype.parameter = function (param_key, param_value) {
-    this.parameters[param_key] = param_value;
-    return this;
-}
-
-/**
-* Sets query statements
-* @param    {Array}             statements
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.statements = function (statements) {
-    this.parameters["statements"] = statements;
-    return this;
-}
-
-/**
-* Pushes a single query statement
-* @param    {String}            statement containing one line of a query
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.add_statement = function (statement) {
-    this.parameters["statements"].push(statement);
-    return this;
-}
-
-/**
-* Sets synchronization mode
-* @param    {String}            sync, either "synchronous" or "asynchronous"
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.mode = function(sync) {
-    this.parameters["mode"] = sync;
-    return this;
-}
-
-/**
-* Extra data to run on success
-* @param    {String}            extra_key
-* @param    {Object}            extra_value
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.add_extra = function(extra_key, extra_value) {
-    this.extra[extra_key] = extra_value;
-    return this;
-}
-
-/**
-* Create a dataset of a given type with a given key (optional)
-* @param    {Object}            param: keys "dataset", "type", "primary_key", 
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.create_dataset = function(param) {
-    // Parse create object
-    var create_statement = 'create dataset ' + param["dataset"] + '(' + param["type"] + ')';
-    if (param.hasOwnProperty("primary_key")) {
-        create_statement += ' primary key ' + param["primary_key"] + ';';
-    }
-    
-    // Add to statements
-    this.parameters["statements"].push(create_statement);
-    
-    return this;
-}
-
-/**
-* Drop a dataset of a given name
-* @param    {String}            dataset
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.drop_dataset = function(dataset) {
-    var drop_statement = 'drop dataset ' + dataset + ';';
-    this.parameters["statements"].push(drop_statement);
-    return this;
-}
-
-/**
-* Reference a query given a query object
-* @param    {Object}            async_handle, an opaque handle from a prior asynchronous query
-* @returns  {AsterixCoreAPI}    this API object 
-*/
-AsterixCoreAPI.prototype.handle = function(async_handle) {
-    this.query_handle = async_handle;
-    return this;
-}
-
-/**
-* @param    {Object}            for : {"var" in "dataset"}
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.aql_for = function(for_object) {
-    var for_statement = "for $"; 
-    for (var key in for_object) {
-        for_statement += key + " in dataset " + for_object[key];
-    }
-    
-    this.parameters["statements"].push(for_statement);
-    return this;
-}
-
-/**
-* @param    {Object}            let : {"key" => "values"}
-* @returns  {AsterixCoreAPI}    this API object
-*
-* TODO This one needs work - hacky
-*/
-AsterixCoreAPI.prototype.aql_let = function(let_object) {
-    var let_statement = "";
-    
-    for (var var_name in let_object) {
-        let_statement = 'let $' + var_name + ' := ' + let_object[var_name];
-        this.parameters["statements"].push(let_statement);
-    }
-
-    return this;
-}
-
-/**
-* @param    {Array}             where_object : [statements]
-* @returns  {AsterixCoreAPI}    this API object
-*
-* TODO Fix me
-*/
-AsterixCoreAPI.prototype.aql_where = function(where_object) {
-    this.parameters["statements"].push("where " + where_object.join(" and "));
-    return this;    
-}
-
-/**
-* @param    {Object}            groupby, a map { "groupby" , "with" }
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.aql_groupby = function(groupby_object) {
-    var groupby_statement = "group by " + groupby_object["groupby"];
-    groupby_statement += " with " + groupby_object["with"];
-    
-    this.parameters["statements"].push(groupby_statement);
-    
-    return this;
-}
-
-/**
-* Prepares a return statement of keys and value variables
-* @param    {Object}            return { "keys" => "values" }
-* @returns  {AsterixCoreAPI}    this API object
-*/
-AsterixCoreAPI.prototype.aql_return = function(return_object) {
-    var components = [];
-    for (var key in return_object) {
-        components.push('"' + key + '" : ' + return_object[key]);
-    }
-    
-    var return_statement = 'return { ' + components.join(', ') + ' }'; 
-    this.parameters["statements"].push(return_statement);
-    
-    return this;
-}
-
-/** API Calls: Query API **/
-
-/**
-* Query
-*
-* @rest-parameter   {String, REQUIRED}  query, query string to pass to ASTERIX
-* @rest-parameter   {String}            mode, whether a call is "synchronous" or "asynchronous"
-* @rest-result      {Object}
-*                       {
-*                           @result     <result as a string, if mode = synchronous>
-*                           @error-code [<code>, <message>] if an error occurs
-*                           @handle:    <opaqure result handle, if mode = asynchronous>
-*                       }              
-* @endpoint         {Asterix REST API}  /query
-*/
-AsterixCoreAPI.prototype.api_core_query = function () {
-    
-    var api = this;
-    var use_dataverse = "use dataverse " + api.dataverse + ";\n";
-    var callbacks = {
-        "sync" : api.ui_callback_on_success,
-        "async" : api.ui_callback_on_success_async
-    };
-    var json = {
-        "endpoint" : "http://localhost:19101/query",
-        "query" : use_dataverse + api.parameters["statements"].join("\n"),
-        "mode" : api.parameters["mode"]
-    };
-
-    api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/**
-* Query Status
-*
-* @rest-parameter   {Object, REQUIRED}  handle, opaque result handle from previous asynchronous query call
-* @rest-result      {Object}
-*                       {
-*                           @status: ("RUNNING" | "SUCCESS" | "ERROR" )
-*                       }
-* @endpoint         {Asterix REST API}  /query/status
-*/
-AsterixCoreAPI.prototype.api_core_query_status = function () {
-
-    var api = this;
-    
-    var use_dataverse = "use dataverse " + api.dataverse + ";\n";
-    
-    var callbacks = {
-        "sync" : this.ui_callback_on_success
-    };
-    
-    var json = {
-        "endpoint"  : "http://localhost:19101/query/status",
-        "handle"    : api.query_handle
-    };
-    
-    api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/**
-* Query Result
-*
-* @rest-parameter   {Object, REQUIRED}  handle, opaque result handle from previous asynchronous query call
-* @rest-parameter   {String}            mode, "synchronous" by default, "asynchronous" if not
-* @rest-result      {Object}
-*                       {
-*                           @result     <result as a string, if mode = synchronous or asynchrous result available
-*                                           {} if mode is asynchronous and results not available >
-*                           @error-code [<code>, <message>] if an error occurs
-*                       }
-* @endpoint         {Asterix REST API}  /query/result
-*/
-AsterixCoreAPI.prototype.api_core_query_result = function () {
-    
-    var api = this;
-    
-    var use_dataverse = "use dataverse " + api.dataverse + ";\n";
-    
-    var callbacks = {
-        "sync" : this.ui_callback_on_success
-    };
-    
-    var json = {
-        "endpoint" : "http://localhost:19101/query/result",
-        "handle" : api.query_handle      
-    };
-    
-    api.api_helper_proxy_handler(json, callbacks, api.extra);
-}
-
-/** API Calls - Update API **/
-
-/**
-* Update
-*
-* @rest-parameter 
-*/
-AsterixCoreAPI.prototype.api_core_update = function () {
-
-    var api = this;
-    
-    var dataverse_statement = 'use dataverse ' + this.dataverse + '; ';
-    
-    var json = {
-        "endpoint" : "http://localhost:19101/update",
-        "statements" : dataverse_statement + this.parameters["statements"].join(" ")
-    };
-    
-   $.ajax({
-        type : 'POST',
-        url: "ajaxFacadeCherry.php",
-        data: json,
-        dataType: "json",
-        success: function(data) {
-
-            // Update API special case
-            if (data == "") {
-                api.ui_callback_on_success(api.extra);
-                
-            } else {
-                var response = $.parseJSON(data[0]);
-                
-                if (response && response["error-code"]) {
-                
-                    api.api_helper_default_on_error(response["error-code"][0], response["error-code"][1]);
-                
-                } else if (response && response["results"]) {
-                
-                    alert("Response: " + response["results"]);
-                
-                } else if (!response) {
-                
-                    api.api_helper_default_on_error(4, "Update API Call Error");
-                
-                }
-            }
-        }
-    
-    });
-}
-
-/** API Calls - DDL API **/
-    
-/**
-* DDL
-*
-* @rest-parameter   {Object, REQUIRED}  DDL
-* @rest-result      {Object}
-*                       {
-*                           @result:    <array of results, one per DDL statement in input>
-*                       }
-* @endpoint         {Asterix REST API}  /ddl
-*/
-AsterixCoreAPI.prototype.api_core_ddl = function () {
-    var api = this;
-    
-    var dataverse_statement = 'use dataverse ' + this.dataverse + '; ';
-    
-    var json = {
-        "endpoint" : "http://localhost:19101/ddl",
-        "ddl" : dataverse_statement + this.parameters["statements"].join(" ")
-    };
-    
-    var callback = {
-        "sync" : api.ui_callback_on_success
-    };
-    
-    api.api_helper_proxy_handler(json, callback, api.extra);
-}
-
-/** API Utilities **/
-
-/**
-* API Helper - Proxy Handler [TEMPORARY]
-*
-* @param    {Object}    json, the JSON object containing the parameters and endpoint for this API call
-* @param    {Objct}     callback, the on-success callbacks for this handler
-*               {
-*                   "sync" : default callback
-*                   "async" : non-default callback
-*               }
-* @param    {Object}    extra, any extra stuff passed from UI [TEMPORARY]
-*/
-AsterixCoreAPI.prototype.api_helper_proxy_handler = function(json, callback, extra) {
-    
-    /*var callbacks = {
-        "sync" : api.ui_callback_on_success,
-        "async" : api.ui_callback_on_success_async
-    };
-    var json = {
-        "endpoint" : "http://localhost:19101/query",
-        "query" : use_dataverse + api.parameters["statements"].join("\n"),
-        "mode" : api.parameters["mode"]
-    };*/
-    var as = new AsterixSDK();
-    api = this;
-
-    var branch = function(response) {
-        
-        if (response && response["error-code"]) {
-            
-            api.api_helper_default_on_error( response["error-code"][0], response["error-code"][1] );     
-            
-        } else if (response && response["results"]) {
-            var fn_callback = callback["sync"];
-            fn_callback(response, extra);
-            
-        } else if (response["handle"]) {
-            
-            var fn_callback = callback["async"];
-            fn_callback(response, extra);
-            
-        } else if (response["status"]) {
-                
-            var fn_callback = callback["sync"];
-            fn_callback(response, extra);
-        }
-    };
-
-    var c = {
-        "onSend" : function() {
-            return {
-                "endpoint" : json["endpoint"],
-                "apiData" : {
-                    "query" : json["query"],
-                    "mode" : json["mode"]
-                },
-                "callback" : branch
-            };
-        }
-    };
-    as.send(c);
-}
-
-/**
-* API Helper - Error Handler
-* Currently does an alert, but a more graceful notification would be better.
-* 
-* @param    {Number}    error_code, ( 1 | 2 | 99 ) denoting type of error
-* @param    {String}    error_message, an informative message about the error
-*/
-AsterixCoreAPI.prototype.api_helper_default_on_error = function (error_code, error_message) {
-    alert("ERROR " + error_code + ": " + error_message);       
-}
diff --git a/asterix-app/src/main/resources/sdk/static/client.html b/asterix-app/src/main/resources/sdk/static/client.html
deleted file mode 100644
index d421a7a1..0000000
--- a/asterix-app/src/main/resources/sdk/static/client.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!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
deleted file mode 100644
index 442842b..0000000
--- a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
+++ /dev/null
@@ -1,499 +0,0 @@
-// AsterixSDK 
-// Core Object for REST API communication
-// Handles callbacks to client applications, communication to REST API, and 
-// endpoint selection. Initializes an RPC consumer object.
-// 
-// Usage:
-// var a = new AsterixSDK();
-function AsterixSDK() {
-    
-    // Asterix SDK request handler initialization
-    // TODO Depending on configuration, may need multiples of these...
-    this.xhr = new easyXDM.Rpc({
-        remote: "http://localhost:19002/sdk/static/client.html"
-    }, {
-        remote: {
-            post: {}
-        }
-    });
-    
-
-    // Asterix SDK => send
-    // Posts a message containing an API endpoint, json data,
-    // and a UI callback function.
-    //
-    // @param handler [Asterix REST Controller], a handler object
-    // that provides REST request information. 
-    //
-    // Anticipated Usage:
-    //
-    // var a = AsterixSDK();
-    // var e = Expression;
-    // var h = AsterixRestController.bindExpression(e);
-    // a.send(h);
-    myThis = this;
-    this.callbacks = {
-        "sync" : function() { alert("default sync"); },
-        "async" : function() {}
-    };
-    this.send = function(handler, cb) {
-        myThis.callbacks = cb;
-        this.handler = handler;
-        this.extras = handler["extras"];
-        this.xhr.post(
-            handler["endpoint"],
-            handler["apiData"],
-            this.branch          
-        );
-    };
-
-
-    // TODO DOC
-    this.branch = function(response) {
-        if (response && response["error-code"]) {
-           
-            alert("Error [Code" + response["error-code"][0] + "]: " + response["error-code"][1]);
-            
-        } else if (response && response["results"]) {
-            var fn_callback = myThis.callbacks["sync"];
-            fn_callback(response, myThis.extras);
-            
-        } else if (response["handle"]) {
-            
-            var fn_callback = this.callbacks["async"];
-            fn_callback(response, extra);
-            
-        } else if (response["status"]) {
-                
-            var fn_callback = this.callbacks["sync"];
-            fn_callback(response, extra);
-        }
-    }
-
-        
-    // Asterix SDK => requestHandler
-    // Handlers remote requests to Asterix REST API
-    // using the easyXDM RPC protocol
-    // Usually should only be called by client side, could be overridden
-    // TODO Get rid of jQuery ajax notation in favor of xmlhttprequest pure js
-    this.requestHandler = function() {
-        var rpc = new easyXDM.Rpc({}, {
-            local: {
-                post: {
-                    method: function(url, data, fn, fnError){ 
-                        $.ajax({
-                            type : 'GET',
-                            url : url,
-                            data : data,
-                            dataType : "json",
-                            success : function(res) {
-                                fn(res);
-                            }
-                        });
-                    }
-                }
-            }
-        });
-    }
-
-
-    // Asterix SDK => bindingHandler
-    // AsterixExpression form handler where a new REST API point is bound. Takes as input any
-    // AsterixExpression, each of which is bindable.
-    this.bindingHandler = new AsterixExpression();
-    this.bind = this.bindingHandler.bind;
-}
-
-// AsterixExpression => Base AQL Syntax Class
-//
-// Components: 
-//      boundTo -> a "next" expression
-function AsterixExpression() {
-    this.init();
-    return this;
-}
-
-AsterixExpression.prototype.init = function () {
-    this.dataverse = ""; // TODO This shouldn't make it to send
-    this.boundTo = {};
-    this.clauses = [];
-    this.ui_callback_on_success = function() {};
-    this.ui_callback_on_success_async = function() {};
-};
-
-// AsterixExpression => bind
-//
-// Binds a "next" AsterixExpression to this one.
-//
-// @param expression [AsterixExpression] MUST be instanceof AsterixExpression
-// TODO Check if it has a bind method or things will get messy.
-AsterixExpression.prototype.bind = function(expression) {
-    // If expression is an AsterixExpression, it becomes base
-    if (expression instanceof AsterixExpression) {
-        this.boundTo = expression;
-    } else if (expression instanceof AsterixClause) {
-        this.clauses.push(expression.val());
-    }
-    return this;
-};
-
-// AsterixExpression => send
-//
-// @param arc [AsterixRESTController]
-// TODO: Arc parameter is temporary
-AsterixExpression.prototype.send = function(arc) {
-    // Hackiest of hacks
-    var g = new AsterixSDK();
-    g.send(arc, arc["callback"]);
-};
-
-// AsterixExpression => clear
-//
-// Clears clauses array
-AsterixExpression.prototype.clear = function() {
-    this.clauses.length = 0;
-    return this;
-};
-
-// AsterixExpression => value
-//
-// Retrieves string value of current expression
-AsterixExpression.prototype.val = function() {
-    return this.clauses.join("\n"); 
-};
-
-// AsterixExpression => success
-//
-// @param method [FUNCTION]
-// @param isSynchronous [BOOLEAN]
-AsterixExpression.prototype.success = function(fn, isSync) {
-    if (isSync) {
-        this.ui_callback_on_success = fn;
-    } else { 
-        this.ui_callback_on_success_async = fn;
-    }
-    return this;
-};
-
-// AsterixExpression => set
-// Pushes statements onto the clause stack
-//
-// TODO typecheck
-// @param statements_arr [ARRAY]
-AsterixExpression.prototype.set = function(statements_arr) {
-    for (var i = 0; i < statements_arr.length; i++) {
-        this.clauses.push(statements_arr[i]);
-    }
-    return this;
-};
-
-// AsterixExpression => dataverse
-//
-// Sets the dataverse for a given api call
-AsterixExpression.prototype.use_dataverse = function(dv) {
-    this.dataverse = dv;
-    this.clauses.push("use dataverse " + dv + ";");
-    return this; 
-};
-
-AsterixExpression.prototype.return = function(return_object) {
-    var components = [];
-    for (var key in return_object) {
-        components.push('"' + key + '" : ' + return_object[key]);
-    }
-    
-    var return_expression = 'return { ' + components.join(', ') + ' }'; 
-    this.clauses.push(return_expression);
-    return this;
-};
-
-//////////////
-/*
-inherit(FLWOGRExpression, AsterixExpression);
-
-function FLWOGRExpression() { 
-    AsterixExpression.prototype.init.call(this);
-    return this; 
-} // ( ForClause | LetClause ) ( Clause )* "return" Expression
-
-function CreateExpression() { 
-    AsterixExpression.prototype.init.call(this);
-    return this; 
-} // "create" ( "type" | "nodegroup" | "external" <DATASET> | <DATASET> | "index" | "dataverse" 
-
-
-
-
-function LegacyExpression() { 
-    AsterixExpression.prototype.init.call(this);
-    return this; 
-} // Legacy for old AsterixAPI version: handle hardcoded strings. Will phase out.
-
-function FunctionCallExpr() {
-    AsterixExpression.prototype.init.call(this);
-    return this; 
-} //( <IDENTIFIER> | <DATASET> ) <LEFTPAREN> ( Expression ( "," Expression )* )? <RIGHTPAREN>
-
-inherit(CreateExpression, AsterixExpression);
-inherit(LegacyExpression, AsterixExpression);
-inherit(FunctionCallExpr, AsterixExpression);
-
-CreateExpression.prototype.send = function() {
-    myThis = this;
-    var arc = new AsterixRESTController();
-    arc.DDL(
-        { "ddl" : myThis.val() },
-        {
-            "sync" : function () {}, // TODO This should be a default value out of the AsterixExpression base
-            "async" : function () {}
-        }
-    );
-
-    // Call AsterixExpression core send method
-    AsterixExpression.prototype.send.call(this, arc);
-};
-
-// LegacyExpression
-// Handles hardcoded query strings from prior versions
-// of this API. Can be useful for debugging.
-LegacyExpression.prototype.send = function(endpoint, json) {
-    
-    var arc = {
-        "endpoint" : endpoint,
-        "apiData" : json, 
-        "callback" : {
-            "sync" : this.ui_callback_on_success,
-            "async" : this.ui_callback_on_success_async
-        },
-        "extras" : this.extras
-    };
-
-    AsterixExpression.prototype.send.call(this, arc);
-}
-
-LegacyExpression.prototype.extra = function(extras) {
-    this.extras = extras;
-    return this;
-}
-
-// TODO DOC
-FunctionCallExpr.prototype.set = function(identifier, expressions) {
-    var expression_clause = identifier + "(";
-    expression_clause += expressions[0].val();
-    for (var e = 1; e < expressions.length; e++) {
-        expression_clause += "," + expressions[e].val();
-    }
-    expression_clause += ")";
-
-    AsterixExpression.prototype.set.call(this, expression_clause);
-    return this; 
-} //( <IDENTIFIER> | <DATASET> ) <LEFTPAREN> ( Expression ( "," Expression )* )? <RIGHTPAREN>
-
-//
-// Clauses
-//
-function AsterixClause() {
-    this.clause = "";
-    return this;
-}
-
-AsterixClause.prototype.val = function() {
-    return this.clause;
-};
-
-AsterixClause.prototype.set = function(clause) {
-    this.clause = clause;
-    return this;
-};
-
-function ForClause() {}         // "for" Variable ( "at" Variable )? "in" ( Expression )
-function LetClause() {}         // "let" Variable ":=" Expression
-function WhereClause() {}       // "where" Expression
-function OrderbyClause() {}     // ( "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )* )
-function GroupClause() {}       //  "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* 
-                                //      ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
-function LimitClause() {}       // "limit" Expression ( "offset" Expression )?
-function DistinctClause() {}    // "distinct" "by" Expression ( "," Expression )*
-
-inherit(ForClause, AsterixClause);
-inherit(LetClause, AsterixClause);
-inherit(WhereClause, AsterixClause);
-inherit(OrderbyClause, AsterixClause);
-inherit(GroupClause, AsterixClause);
-inherit(LimitClause, AsterixClause);
-inherit(DistinctClause, AsterixClause);
-
-// ForClause
-//
-// Grammar:
-// "for" Variable ( "at" Variable )? "in" ( Expression )
-//
-// @param for_variable [String], REQUIRED, first variable in clause 
-// @param at_variable [String], NOT REQUIRED, first variable in clause
-// @param expression [AsterixExpression], REQUIRED, expression to evaluate
-//
-// TODO Error Checking
-function ForClause(for_variable, at_variable, expression) {
-    
-    // at_variable is optional, check if defined
-    var at = typeof at_variable ? a : null;
-
-    // Prepare clause
-    var clause = "for $" + for_variable;
-    if (at != null) {
-        clause += " at $" + at_variable;
-    }
-    clause += " in " + expression.val();
-   
-    // Set prototype
-    AsterixClause.prototype.set.call(this, clause);
-    return this;
-}
-
-// LetClause
-//
-// Grammar:
-// "let" Variable ":=" Expression
-//  
-// TODO error checking
-// @param let_variable [String], REQUIRED
-// @param expression [AsterixExpression], REQUIRED
-LetClause.prototype.set = function(let_variable, expression) { 
-    var clause = "let $" + let_variable + " := " + expression.val();
-   
-    AsterixClause.prototype.set.call(this, clause);
-    return this;
-};
-
-// TODO
-WhereClause.prototype.set = function(clause) {
-    AsterixClause.prototype.set.call(this, clause); 
-    return this;
-};
-
-// TODO
-OrderbyClause.prototype.set = function(clause) {
-    AsterixClause.prototype.set.call(this, clause); 
-    return this;
-};
-
-// GroupClause
-//
-// Grammer:
-// "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* 
-// ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? 
-// "with" VariableRef ( "," VariableRef )*
-GroupClause.prototype.set = function(clause) {
-    AsterixClause.prototype.set.call(this, clause); 
-    return this;
-};
-
-// TODO
-LimitClause.prototype.set = function(clause) {
-    AsterixClause.prototype.set.call(this, clause); 
-    return this;
-};
-
-// TODO
-DistinctClause.prototype.set = function(clause)  {
-    AsterixClause.prototype.set.call(this, clause); 
-    return this;
-};
-
-
-
-
-// Asterix REST Controller
-//
-// Asterix REST Controller
-// Handles interactions with remote database using a request handler
-function AsterixRESTController() {
-   
-    // bindExpression
-    // Prepares an expression for query the asterix API
-    // TODO: Future expressions will do some kind of parsing on queries, for now
-    // a keyword is used to return the appropriate handler
-    // keywords: ddl, update, query, query_status, query_result
-    //
-    // @param expression [AsterixExpression], an expression or one of its
-    // subclasses
-    // @param handler [AsterixRESTController], a handler to pass to the SDK
-    // remote method call
-    this.bindExpression = function(expression, handler_type) {
-        
-        // TODO Expression handler
-
-        // Parse handler, to be replaced with something more elegant
-        switch (handler_type)
-        {
-            case "ddl":
-                break;
-            case "update":
-                break;
-            case "query":
-                break;
-            case "query_status":
-                break;
-            case "query_result":
-                break;
-            default:
-                this.onHandlerInitError();
-        }
-    };
-
-    // onHandlerInitError
-    // Method for handling expression binding errors in the controller.
-    this.onHandlerInitError = function() {
-        alert("AsterixSDK / AsterixRESTController / bindExpressionError: Could not determine api endpoint, incorrect keyword");
-    }
-
-    // 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));
-        }
-    });
-}
-
-// Helper Functions
-AsterixSDK.prototype.rectangle = function(bounds) {
-   var lower_left = 'create-point(' + bounds["sw"]["lat"] + ',' + bounds["sw"]["lng"] + ')';
-   var upper_right = 'create-point(' + bounds["ne"]["lat"] + ',' + bounds["ne"]["lng"] + ')';
-
-   var rectangle_statement = 'create-rectangle(' + lower_left + ', ' + upper_right + ')';
-   //FunctionCallExpr.prototype.set = function(identifier, expressions) {
-   //TODO
-   return rectangle_statement;
-};*/
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
deleted file mode 100644
index 61b9738..0000000
--- a/asterix-app/src/main/resources/sdk/static/js/easyXDM.debug.js
+++ /dev/null
@@ -1,2871 +0,0 @@
-/**
- * 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);
