AsterixSDK Stable Beta Demo - TinySocial - Simple Aggregate Correct
diff --git a/asterix-app/src/main/resources/sdk/static/example/data/fbm.adm b/asterix-app/src/main/resources/sdk/static/example/data/fbm.adm
new file mode 100644
index 0000000..58d7f08
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/data/fbm.adm
@@ -0,0 +1,15 @@
+{"message-id":1,"author-id":3,"in-response-to":2,"sender-location":point("47.16,77.75"),"message":" love sprint its shortcut-menu is awesome:)"}
+{"message-id":2,"author-id":1,"in-response-to":4,"sender-location":point("41.66,80.87"),"message":" dislike iphone its touch-screen is horrible"}
+{"message-id":3,"author-id":2,"in-response-to":4,"sender-location":point("48.09,81.01"),"message":" like samsung the plan is amazing"}
+{"message-id":4,"author-id":1,"in-response-to":2,"sender-location":point("37.73,97.04"),"message":" can't stand at&t the network is horrible:("}
+{"message-id":5,"author-id":6,"in-response-to":2,"sender-location":point("34.7,90.76"),"message":" love sprint the customization is mind-blowing"}
+{"message-id":6,"author-id":2,"in-response-to":1,"sender-location":point("31.5,75.56"),"message":" like t-mobile its platform is mind-blowing"}
+{"message-id":7,"author-id":5,"in-response-to":15,"sender-location":point("32.91,85.05"),"message":" dislike sprint the speed is horrible"}
+{"message-id":8,"author-id":1,"in-response-to":11,"sender-location":point("40.33,80.87"),"message":" like verizon the 3G is awesome:)"}
+{"message-id":9,"author-id":3,"in-response-to":12,"sender-location":point("34.45,96.48"),"message":" love verizon its wireless is good"}
+{"message-id":10,"author-id":1,"in-response-to":12,"sender-location":point("42.5,70.01"),"message":" can't stand motorola the touch-screen is terrible"}
+{"message-id":11,"author-id":1,"in-response-to":1,"sender-location":point("38.97,77.49"),"message":" can't stand at&t its plan is terrible"}
+{"message-id":12,"author-id":10,"in-response-to":6,"sender-location":point("42.26,77.76"),"message":" can't stand t-mobile its voicemail-service is OMG:("}
+{"message-id":13,"author-id":10,"in-response-to":4,"sender-location":point("42.77,78.92"),"message":" dislike iphone the voice-command is bad:("}
+{"message-id":14,"author-id":9,"in-response-to":12,"sender-location":point("41.33,85.28"),"message":" love at&t its 3G is good:)"}
+{"message-id":15,"author-id":7,"in-response-to":11,"sender-location":point("44.47,67.11"),"message":" like iphone the voicemail-service is awesome"}
diff --git a/asterix-app/src/main/resources/sdk/static/example/data/fbu.adm b/asterix-app/src/main/resources/sdk/static/example/data/fbu.adm
new file mode 100644
index 0000000..7e99ea4
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/data/fbu.adm
@@ -0,0 +1,10 @@
+{"id":1,"alias":"Margarita","name":"MargaritaStoddard","user-since":datetime("2012-08-20T10:10:00"),"friend-ids":{{2,3,6,10}},"employment":[{"organization-name":"Codetechno","start-date":date("2006-08-06")}]}
+{"id":2,"alias":"Isbel","name":"IsbelDull","user-since":datetime("2011-01-22T10:10:00"),"friend-ids":{{1,4}},"employment":[{"organization-name":"Hexviafind","start-date":date("2010-04-27")}]}
+{"id":3,"alias":"Emory","name":"EmoryUnk","user-since":datetime("2012-07-10T10:10:00"),"friend-ids":{{1,5,8,9}},"employment":[{"organization-name":"geomedia","start-date":date("2010-06-17"),"end-date":date("2010-01-26")}]}
+{"id":4,"alias":"Nicholas","name":"NicholasStroh","user-since":datetime("2010-12-27T10:10:00"),"friend-ids":{{2}},"employment":[{"organization-name":"Zamcorporation","start-date":date("2010-06-08")}]}
+{"id":5,"alias":"Von","name":"VonKemble","user-since":datetime("2010-01-05T10:10:00"),"friend-ids":{{3,6,10}},"employment":[{"organization-name":"Kongreen","start-date":date("2010-11-27")}]}
+{"id":6,"alias":"Willis","name":"WillisWynne","user-since":datetime("2005-01-17T10:10:00"),"friend-ids":{{1,3,7}},"employment":[{"organization-name":"jaydax","start-date":date("2009-05-15")}]}
+{"id":7,"alias":"Suzanna","name":"SuzannaTillson","user-since":datetime("2012-08-07T10:10:00"),"friend-ids":{{6}},"employment":[{"organization-name":"Labzatron","start-date":date("2011-04-19")}]}
+{"id":8,"alias":"Nila","name":"NilaMilliron","user-since":datetime("2008-01-01T10:10:00"),"friend-ids":{{3}},"employment":[{"organization-name":"Plexlane","start-date":date("2010-02-28")}]}
+{"id":9,"alias":"Woodrow","name":"WoodrowNehling","user-since":datetime("2005-09-20T10:10:00"),"friend-ids":{{3,10}},"employment":[{"organization-name":"Zuncan","start-date":date("2003-04-22"),"end-date":date("2009-12-13")}]}
+{"id":10,"alias":"Bram","name":"BramHatch","user-since":datetime("2010-10-16T10:10:00"),"friend-ids":{{1,5,9}},"employment":[{"organization-name":"physcane","start-date":date("2007-06-05"),"end-date":date("2011-11-05")}]}
diff --git a/asterix-app/src/main/resources/sdk/static/example/data/twm.adm b/asterix-app/src/main/resources/sdk/static/example/data/twm.adm
new file mode 100644
index 0000000..fa764af
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/data/twm.adm
@@ -0,0 +1,12 @@
+{"tweetid":"1","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("47.44,80.65"),"send-time":datetime("2008-04-26T10:10:00"),"referred-topics":{{"t-mobile","customization"}},"message-text":" love t-mobile its customization is good:)"}
+{"tweetid":"2","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("32.84,67.14"),"send-time":datetime("2010-05-13T10:10:00"),"referred-topics":{{"verizon","shortcut-menu"}},"message-text":" like verizon its shortcut-menu is awesome:)"}
+{"tweetid":"3","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("29.72,75.8"),"send-time":datetime("2006-11-04T10:10:00"),"referred-topics":{{"motorola","speed"}},"message-text":" like motorola the speed is good:)"}
+{"tweetid":"4","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("39.28,70.48"),"send-time":datetime("2011-12-26T10:10:00"),"referred-topics":{{"sprint","voice-command"}},"message-text":" like sprint the voice-command is mind-blowing:)"}
+{"tweetid":"5","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("40.09,92.69"),"send-time":datetime("2006-08-04T10:10:00"),"referred-topics":{{"motorola","speed"}},"message-text":" can't stand motorola its speed is terrible:("}
+{"tweetid":"6","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("47.51,83.99"),"send-time":datetime("2010-05-07T10:10:00"),"referred-topics":{{"iphone","voice-clarity"}},"message-text":" like iphone the voice-clarity is good:)"}
+{"tweetid":"7","user":{"screen-name":"ChangEwing_573","lang":"en","friends_count":182,"statuses_count":394,"name":"Chang Ewing","followers_count":32136},"sender-location":point("36.21,72.6"),"send-time":datetime("2011-08-25T10:10:00"),"referred-topics":{{"samsung","platform"}},"message-text":" like samsung the platform is good"}
+{"tweetid":"8","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("46.05,93.34"),"send-time":datetime("2005-10-14T10:10:00"),"referred-topics":{{"t-mobile","shortcut-menu"}},"message-text":" like t-mobile the shortcut-menu is awesome:)"}
+{"tweetid":"9","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("36.86,74.62"),"send-time":datetime("2012-07-21T10:10:00"),"referred-topics":{{"verizon","voicemail-service"}},"message-text":" love verizon its voicemail-service is awesome"}
+{"tweetid":"10","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("29.15,76.53"),"send-time":datetime("2008-01-26T10:10:00"),"referred-topics":{{"verizon","voice-clarity"}},"message-text":" hate verizon its voice-clarity is OMG:("}
+{"tweetid":"11","user":{"screen-name":"NilaMilliron_tw","lang":"en","friends_count":445,"statuses_count":164,"name":"Nila Milliron","followers_count":22649},"sender-location":point("37.59,68.42"),"send-time":datetime("2008-03-09T10:10:00"),"referred-topics":{{"iphone","platform"}},"message-text":" can't stand iphone its platform is terrible"}
+{"tweetid":"12","user":{"screen-name":"OliJackson_512","lang":"en","friends_count":445,"statuses_count":164,"name":"Oli Jackson","followers_count":22649},"sender-location":point("24.82,94.63"),"send-time":datetime("2010-02-13T10:10:00"),"referred-topics":{{"samsung","voice-command"}},"message-text":" like samsung the voice-command is amazing:)"}
diff --git a/asterix-app/src/main/resources/sdk/static/example/data/twu.adm b/asterix-app/src/main/resources/sdk/static/example/data/twu.adm
new file mode 100644
index 0000000..32a1917
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/data/twu.adm
@@ -0,0 +1,4 @@
+{"screen-name":"NathanGiesen@211","lang":"en","friends_count":18,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416}
+{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159}
+{"screen-name":"NilaMilliron_tw","lang":"en","friends_count":445,"statuses_count":164,"name":"Nila Milliron","followers_count":22649}
+{"screen-name":"ChangEwing_573","lang":"en","friends_count":182,"statuses_count":394,"name":"Chang Ewing","followers_count":32136}
diff --git a/asterix-app/src/main/resources/sdk/static/example/demo.html b/asterix-app/src/main/resources/sdk/static/example/demo.html
new file mode 100644
index 0000000..3a8d353
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/demo.html
@@ -0,0 +1,391 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <title>AsterixDB TinySocial Demo</title>
+
+    <style>
+        .pretty-printed {
+            background-color: #eeeeee;
+            margin-bottom: 1em;
+        }
+
+        .how-to-run {
+            background-color: #c8c8c8;
+            margin-bottom: 1em;
+        }
+
+        .result-output {
+            background-color: #BED8E5;
+            margin-bottom: 1em;
+        }
+
+        body {
+            font-family : "Helvetica";
+            margin-bottom: 1em;
+        }
+    </style>
+
+    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
+    <script src="../js/asterix-sdk-stable.js"></script>
+    <script src="js/demo.js"></script>
+</head>
+<body>
+    <h1>AQL: Querying TinySocial AsterixDB</h1>
+    
+    <h2>Query 0-A - Exact-Match Lookup</h2>
+    <div class="sample-query">
+
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            where $user.id = 8<br/>
+            return $user;<br/>
+        </div>
+
+        <div class="how-to-run">
+            javascript here
+        </div>
+
+        <div class="result-output" id="result0A">
+        </div>
+
+        <button id="run0a">Run #0-A</button>
+    </div>
+    <hr/>
+    <h2>Query 0-B - Range Scan</h2>
+    <div class="sample-query">
+        
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            where $user.id >= 2 and $user.id <= 4<br/>
+            return $user;<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result0B">
+        </div>
+
+        <button id="run0b">Run #0-B</button>
+    </div>
+    <hr/>
+
+    <h2>Query 1 - Other Query Filters</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            where $user.user-since >= datetime('2010-07-22T00:00:00')<br/>
+            and $user.user-since <= datetime('2012-07-29T23:59:59')<br/>
+            return $user;<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result1">
+        </div>
+
+        <button id="run1">Run #1</button>
+    </div>
+    <hr/>
+
+    <h2>Query 2-A - Equijoin</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            for $message in dataset FacebookMessages<br/>
+            where $message.author-id = $user.id<br/> 
+            return {<br/>
+            "uname": $user.name,<br/>
+            "message": $message.message<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result2a">
+        </div>
+
+        <button id="run2a">Run #2-A</button>
+    </div>
+    <hr/>
+
+    <h2>Query 2-B - Index join</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            for $message in dataset FacebookMessages<br/>
+            where $message.author-id /*+ indexnl */  = $user.id<br/>
+            return {<br/>
+            "uname": $user.name,<br/>
+            "message": $message.message<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result2b">
+        </div>
+
+        <button id="run2b">Run #2-B</button>
+    </div>
+    <hr/>
+
+    <h2>Query 3 - Nested Outer Join</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $user in dataset FacebookUsers<br/>
+            return {<br/>
+            "uname": $user.name,<br/>
+            "messages": for $message in dataset FacebookMessages<br/>
+            where $message.author-id = $user.id<br/>
+            return $message.message<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result3">
+        </div>
+
+        <button id="run3">Run #3</button>
+    </div>
+    <hr/>
+
+    <h2>Query 4 - Theta Join</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $t in dataset TweetMessages<br/>
+            return {<br/>
+            "message": $t.message-text,<br/>
+            "nearby-messages": for $t2 in dataset TweetMessages<br/>
+            where spatial-distance($t.sender-location, $t2.sender-location) <= 1<br/>
+            return { "msgtxt":$t2.message-text}<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result4">
+        </div>
+
+        <button id="run4">Run #4</button>
+    </div>
+    <hr/>
+
+    <h2>Query 5 - Fuzzy Join</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            set simfunction "edit-distance";<br/>
+            set simthreshold "3";<br/><br/>
+
+            for $fbu in dataset FacebookUsers<br/>
+            return {<br/>
+                "id": $fbu.id,<br/>
+                "name": $fbu.name,<br/>
+                "similar-users": for $t in dataset TweetMessages<br/>
+                        let $tu := $t.user<br/>
+                        where $tu.name ~= $fbu.name<br/>
+                        return {<br/>
+                        "twitter-screenname": $tu.screen-name,<br/>
+                        "twitter-name": $tu.name<br/>
+                        }<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result5">
+        </div>
+
+        <button id="run5">Run #5</button>
+    </div>
+    <hr/>
+
+    <h2>Query 6 - Existential Quantification</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $fbu in dataset FacebookUsers<br/>
+            where (some $e in $fbu.employment satisfies is-null($e.end-date))<br/> 
+            return $fbu;<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result6">
+        </div>
+
+        <button id="run6">Run #6</button>
+    </div>
+    <hr/>
+
+    <h2>Query 7 - Universal Quantification</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $fbu in dataset FacebookUsers<br/>
+            where (every $e in $fbu.employment satisfies not(is-null($e.end-date))) <br/>
+            return $fbu;<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result7">
+        </div>
+
+        <button id="run7">Run #7</button>
+    </div>
+    <hr/>
+
+    <h2>Query 8 - Simple Aggregation</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            count(for $fbu in dataset FacebookUsers return $fbu);<br/>
+        </div>
+        
+        <div class="how-to-run">
+        var expression8 = new FunctionExpression({<br/>
+            "function"      : "count",<br/>
+            "expression"    : new ForClause("fbu", null, new AsterixExpression().set(["dataset FacebookUsers"])).bind({"return" : "$fbu"}),<br/>
+            "dataverse"     : "TinySocial"<br/>
+        }).run();
+        </div>
+
+        <div class="result-output" id="result8">
+        </div>
+
+        <button id="run8">Run #8</button>
+    </div>
+    <hr/>
+
+    <h2>Query 9-A - Grouping and Aggregation</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $t in dataset TweetMessages<br/>
+            group by $uid := $t.user.screen-name with $t<br/>
+            return {<br/>
+            "user": $uid,<br/>
+            "count": count($t)<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result9">
+        </div>
+
+        <button id="run9a">Run #9-A</button>
+    </div>
+    <hr/>
+
+    <h2>Query 9-B - (Hash-Based) Grouping and Aggregation</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+           use dataverse TinySocial;<br/><br/>
+
+            for $t in dataset TweetMessages<br/>
+            /*+ hash*/<br/>
+            group by $uid := $t.user.screen-name with $t<br/>
+            return {<br/>
+            "user": $uid,<br/>
+            "count": count($t)<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result10">
+        </div>
+
+        <button id="run9b">Run #9-B</button>
+    </div>
+    <hr/>
+
+    <h2>Query 10 - Grouping and Limits</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            for $t in dataset TweetMessages<br/>
+            group by $uid := $t.user.screen-name with $t<br/>
+            let $c := count($t)<br/>
+            order by $c desc<br/>
+            limit 3<br/>
+            return {<br/>
+                    "user": $uid,<br/>
+                    "count": $c<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result11">
+        </div>
+
+        <button id="run10">Run #10</button>
+    </div>
+    <hr/>
+
+    <h2>Query 11 - Left Outer Fuzzy Join</h2>
+    <div class="sample-query">
+        <div class="pretty-printed">
+            use dataverse TinySocial;<br/><br/>
+
+            set simfunction "jaccard";<br/>
+            set simthreshold "0.3";<br/><br/>
+
+            for $t in dataset TweetMessages<br/>
+            return {<br/>                     
+                "tweet": $t,<br/>               
+                "similar-tweets": for $t2 in dataset TweetMessages<br/>
+                        where  $t2.referred-topics ~= $t.referred-topics<br/>
+                        and $t2.tweetid != $t.tweetid<br/>
+                        return $t2.referred-topics<br/>
+            };<br/>
+        </div>
+        
+        <div class="how-to-run">
+        </div>
+
+        <div class="result-output" id="result11">
+        </div>
+
+        <button id="run11">Run #11</button>
+    </div>
+
+</body>
+</html>
diff --git a/asterix-app/src/main/resources/sdk/static/example/js/demo.js b/asterix-app/src/main/resources/sdk/static/example/js/demo.js
new file mode 100644
index 0000000..e00e1d5
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/example/js/demo.js
@@ -0,0 +1,19 @@
+$(document).ready(function() {
+
+    // 8 - Simple Aggregation
+    $('#run8').click(function () {
+
+        // Option 1: Simple, Object Syntax     
+        $('#result8').html('');   
+        var expression8 = new FunctionExpression({
+            "function"      : "count",
+            "expression"    : new ForClause("fbu", null, new AsterixExpression().set(["dataset FacebookUsers"])).bind({"return" : "$fbu"}),
+            "dataverse"     : "TinySocial",
+            "success"       : function(res) {
+                                $('#result8').html(res["results"]);
+                              }
+        });
+        expression8.run();
+    });
+    
+});
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
new file mode 100644
index 0000000..f43ae0e
--- /dev/null
+++ b/asterix-app/src/main/resources/sdk/static/js/asterix-sdk-stable.js
@@ -0,0 +1,255 @@
+function AsterixSDK() {
+
+    // 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.bind(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          
+        );
+    };
+
+    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 => 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;
+}
+
+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.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.prototype.send = function(arc) {
+    // Hackiest of hacks
+    var g = new AsterixSDK();
+    g.send(arc, arc["callback"]);
+};
+
+AsterixExpression.prototype.clear = function() {
+    this.clauses.length = 0;
+    return this;
+};
+
+AsterixExpression.prototype.val = function() {
+    return this.clauses.join("\n"); 
+};
+
+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.prototype.set = function(statements_arr) {
+    for (var i = 0; i < statements_arr.length; i++) {
+        this.clauses.push(statements_arr[i]);
+    }
+    return this;
+};
+
+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;
+};
+
+////////
+////////
+////////
+
+// 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) {
+  
+    this._properties = {};
+    this._properties["clause"] = "";
+  
+    // at_variable is optional, check if defined
+    var at = typeof at_variable ? at_variable : null;
+
+    // Prepare clause
+    this._properties["clause"] = "for $" + for_variable;
+    if (at != null) {
+        this._properties["clause"] += " at $" + at_variable;
+    }
+    this._properties["clause"] += " in " + expression.val();
+    return this;
+}
+
+ForClause.prototype.bind = function(options) {
+    var options = options || {};
+
+    if (options.hasOwnProperty("return")) {
+        this._properties["return"] = options["return"];
+    }
+
+    return this;
+};
+
+ForClause.prototype.val = function() {
+
+    var value = this._properties["clause"];
+
+    if (this._properties.hasOwnProperty("return")) {
+        value += " return " + this._properties["return"];
+    }
+ 
+    return value;
+};
+
+
+// FunctionExpression
+// Parent: AsterixExpression
+// 
+// @param   bindables [Various], 
+// @key     fn [String], a function to be applid to the expression
+// @param   expr [AsterixExpression or AsterixClause] an AsterixExpression/Clause to which the fn will be applied
+function FunctionExpression(options) {
+    
+    // Initialize own properties to be null
+    this._properties = {};
+    this._success = function() {};
+
+    // Possible to initialize a function epxression without inputs, or with them
+    this.bind(options);
+
+    // Return object
+    return this;
+}
+
+FunctionExpression.prototype.bind = function(options) {
+    var options = options || {};
+
+    if (options.hasOwnProperty("function")) {
+        this._properties["function"] = options["function"];
+    }
+
+    if (options.hasOwnProperty("expression")) {
+        this._properties["expression"] = options["expression"];
+    }
+
+    if (options.hasOwnProperty("dataverse")) {
+        this._properties["dataverse"] = options["dataverse"];
+    }
+
+    if (options.hasOwnProperty("success")) {
+        this._success = options["success"];
+    }
+
+    return this;
+};
+
+FunctionExpression.prototype.val = function () { 
+
+    var value = "";
+
+    // If there is a dataverse defined, provide it. TODO Can be overriden
+    if (this._properties.hasOwnProperty("dataverse")) {
+        value += "use dataverse " + this._properties["dataverse"] + ";\n";
+    }
+
+    return value + this._properties["function"] + "(" + this._properties["expression"].val() + ");"; 
+};
+
+FunctionExpression.prototype.error = function(msg) {
+    return "Asterix FunctionExpression Error: " + msg;
+};
+
+FunctionExpression.prototype.run = function() {
+    var success_fn = this._success;
+
+    $.ajax({
+        type : 'GET',
+        url : "http://localhost:19101/query",
+        data : {"query" : this.val()},
+        dataType : "json",
+        success : function(data) {     
+            success_fn(data);
+        }
+    });
+
+    return this;
+}