Black Cherry spatial query bugfix and refactor
diff --git a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js b/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
index 956767b..442842b 100644
--- a/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
+++ b/asterix-app/src/main/resources/sdk/static/js/asterix-api-core.js
@@ -208,7 +208,7 @@
 };
 
 //////////////
-
+/*
 inherit(FLWOGRExpression, AsterixExpression);
 
 function FLWOGRExpression() { 
@@ -216,8 +216,6 @@
     return this; 
 } // ( ForClause | LetClause ) ( Clause )* "return" Expression
 
-
-/*
 function CreateExpression() { 
     AsterixExpression.prototype.init.call(this);
     return this; 
@@ -499,18 +497,3 @@
    //TODO
    return rectangle_statement;
 };*/
-
- 
-///////////////
-// Utilities //
-///////////////
-
-// Inherit with the proxy pattern
-// Source: https://gist.github.com/jeremyckahn/5552373
-//
-// LEGACY: Will change to Firefox's preferred object creation method :)
-function inherit(inherits, inheritsFrom) {
-    function proxy() {};
-    proxy.prototype = inheritsFrom.prototype;
-    inherits.prototype = new proxy();
-}
diff --git a/asterix-app/src/main/resources/sdk/static/js/asterix-sdk-stable.js b/asterix-app/src/main/resources/sdk/static/js/asterix-sdk-stable.js
index 7989a9e..ae8fae9 100644
--- a/asterix-app/src/main/resources/sdk/static/js/asterix-sdk-stable.js
+++ b/asterix-app/src/main/resources/sdk/static/js/asterix-sdk-stable.js
@@ -1,3 +1,106 @@
+// 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.
+    //
+    // Usage:
+    // var a = AsterixSDK();
+    // a.send(
+    //     http://localhost:19002/XYZ,
+    //     json
+    // );
+    myThis = this;
+    this.send = function (endpoint, data, extras) {
+        this.extras = extras;
+        this.xhr.post(
+            endpoint,
+            data,
+            this.branch          
+        );
+    };
+    
+    
+    // Set callback functions
+    this.callbacks = {};
+    
+    this.callback = function(fn, mode) {
+        if (mode == "sync" || mode == "async") {
+            this.callbacks[mode] = fn;
+        }
+        
+        return this;
+    };
+
+
+    // Set branching method on send
+    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);
+                            }
+                        });
+                    }
+                }
+            }
+        });
+    }
+}
+
+
 // Temporary AsterixExpression Placeholder
 function AExpression () {
     this._properties = {};
@@ -29,7 +132,7 @@
 
     $.ajax({
         type : 'GET',
-        url : "http://localhost:19101/query",
+        url : "http://localhost:19002/query",
         data : {"query" : this.val()},
         dataType : "json",
         success : function(data) {     
@@ -233,9 +336,9 @@
     var at = typeof at_variable ? at_variable : null;
 
     // Prepare clause
-    this._properties["clause"] = "for $" + for_variable;
+    this._properties["clause"] = "for " + for_variable;
     if (at != null) {
-        this._properties["clause"] += " at $" + at_variable;
+        this._properties["clause"] += " at " + at_variable;
     }
     this._properties["clause"] += " in " + expression.val();
     return this;
diff --git a/asterix-examples/src/main/resources/cherry/examples/cherry.html b/asterix-examples/src/main/resources/cherry/examples/cherry.html
index af6b958..8de0ae1 100755
--- a/asterix-examples/src/main/resources/cherry/examples/cherry.html
+++ b/asterix-examples/src/main/resources/cherry/examples/cherry.html
@@ -21,8 +21,7 @@
     <script type="text/javascript" src="../js/geostats.js" ></script>
 
     <script src="../../core/js/easyXDM/easyXDM.debug.js"></script>
-    <script src="http://localhost:19002/sdk/static/js/asterix-api-core.js"></script>
-    <script src="../js/asterix-api-core.js" type="text/javascript"></script>
+    <script src="http://localhost:19002/sdk/static/js/asterix-sdk-stable.js"></script>>
     <script src="../js/cherry.js" type="text/javascript"></script>
     <style type="text/css">
         .column-section {
diff --git a/asterix-examples/src/main/resources/cherry/js/cherry.js b/asterix-examples/src/main/resources/cherry/js/cherry.js
index c9be322..72f40fa 100755
--- a/asterix-examples/src/main/resources/cherry/js/cherry.js
+++ b/asterix-examples/src/main/resources/cherry/js/cherry.js
@@ -231,35 +231,38 @@
 		if ($('#asbox').is(":checked")) {
 		    build_cherry_mode = "asynchronous";
 		}
-		
-		// You don't need to run a query to use the API!
-		// It can also be used to generate queries, which can
-		// then be passed into another API call or stored 
-		// for a different application purpose. 
-        var l = new LegacyExpression()
-            .dataverse("twitter")
-		    .bind(new ForClause("t", new AsterixClause().set("TweetMessages")))
-            .bind(new LetClause("keyword", new AsterixClause().set('"' + formData["keyword"] + '"')))
-            .bind(new LetClause("region", new AsterixSDK().rectangle(formBounds)))
-            .bind(new WhereClause("where " + [
-		        'spatial-intersect($t.sender-location, $region)',
-		        '$t.send-time > datetime("' + formData["startdt"] + '")',
-		        '$t.send-time < datetime("' + formData["enddt"] + '")',
-		        'contains($t.message-text, $keyword)'
-             ]).join(" "))
-            .bind(new GroupClause().set("group by $c := spatial-cell($t.sender-location, create-point(24.5,-125.5), " + formData["gridlat"].toFixed(1) + ", " + formData["gridlng"].toFixed(1) + ")"))
-		    .return({ "cell" : "$c", "count" : "count($t)" })
-            .success(cherryQuerySyncCallback, true)
-		    .success(cherryQueryAsyncCallback, false)
-            .extra({
-                "payload" : formData,
-                "query_string" : "use dataverse twitter;\n" //LEGACY + buildCherryQuery.parameters["statements"].join("\n")
-            })
-            .send("http://localhost:19002/query", 
-            {
-                "query" : "use dataverse twitter;\n" + buildCherryQuery.parameters["statements"].join("\n"),
-                "mode" : build_cherry_mode, 
-            });
+	
+        var f = new FLWOGRExpression()
+            .bind(new ForClause("$t", null, new AQLClause().set("dataset TweetMessages")))
+            .bind(new LetClause("keyword", new AQLClause().set('"' + formData["keyword"] + '"')))
+            .bind(new LetClause("region", new AQLClause().set(temporary_rectangle(formBounds))))
+            .bind(new WhereClause(new AExpression().set(
+                [
+		            'spatial-intersect($t.sender-location, $region)',
+		            '$t.send-time > datetime("' + formData["startdt"] + '")',
+		            '$t.send-time < datetime("' + formData["enddt"] + '")',
+		            'contains($t.message-text, $keyword)'
+                ].join(" and ")
+            )))
+            .bind(new AQLClause().set("group by $c := spatial-cell($t.sender-location, create-point(24.5,-125.5), " + formData["gridlat"].toFixed(1) + ", " + formData["gridlng"].toFixed(1) + ") with $t"))
+            .bind(new ReturnClause({ "cell" : "$c", "count" : "count($t)" }));
+        
+        var extra = {
+            "payload" : formData,
+            "query_string" : "use dataverse twitter;\n"
+        };
+        
+        var a = new AsterixSDK()
+            .callback(cherryQuerySyncCallback, "sync")
+            .callback(cherryQueryAsyncCallback, "async")
+            .send(
+                "http://localhost:19002/query", 
+                {
+                    "query" : "use dataverse twitter;\n" + f.val(),
+                    "mode" : build_cherry_mode
+                },
+                extra        
+            );
         
 		APIqueryTracker = {
 		    "query" : "use dataverse twitter;",// buildCherryQuery.parameters["statements"].join("\n"),
@@ -277,6 +280,12 @@
     
 });
 
+function temporary_rectangle(bounds) {
+    var lower_left = 'create-point(' + bounds["sw"]["lat"] + ',' + bounds["sw"]["lng"] + ')';
+    var upper_right = 'create-point(' + bounds["ne"]["lat"] + ',' + bounds["ne"]["lng"] + ')';
+    return 'create-rectangle(' + lower_left + ', ' + upper_right + ')';
+}
+
 /** Asynchronous Query Management - Handles & Such **/
 
 /**