Refactoring and dependency fixes
diff --git a/asterix-examples/src/main/resources/black-cherry/README.md b/asterix-examples/src/main/resources/black-cherry/README.md
index 22a3dca..84a8123 100755
--- a/asterix-examples/src/main/resources/black-cherry/README.md
+++ b/asterix-examples/src/main/resources/black-cherry/README.md
@@ -6,12 +6,12 @@
 A running, local AsterixDB instance (via Managix), of the latest master version.
 http://asterix.ics.uci.edu/documentation/install.html
 
-Python Requests Library
-http://docs.python-requests.org/en/latest/user/install/#install
+Please note that previous versions of this demo required Python's requests library.
+This dependency is no longer in place.
 
 ## Steps
 
-0. Install Python Requests, if you have not already
+0. Run your local AsterixDB instance via Managix.
 
 1. Go to the top level of this demo and run
 $ python run_black_cherry.py
diff --git a/asterix-examples/src/main/resources/black-cherry/run_black_cherry.py b/asterix-examples/src/main/resources/black-cherry/run_black_cherry.py
index f461934..d78514b 100755
--- a/asterix-examples/src/main/resources/black-cherry/run_black_cherry.py
+++ b/asterix-examples/src/main/resources/black-cherry/run_black_cherry.py
@@ -1,9 +1,8 @@
 import black_cherry_bootstrap
-import requests
-from bottle import route, run, template, get, debug, static_file, request, response
-
-debug(True)
-http_header = { "content-type": "application/json" }
+from urllib2 import URLError, urlopen
+from urllib import urlencode
+from json import loads, dumps
+from bottle import route, run, template, static_file, request
 
 # Core Routing
 @route('/')
@@ -17,11 +16,38 @@
 # API Helpers
 def build_response(endpoint, data):
     api_endpoint = "http://localhost:19002/" + endpoint
-    response = requests.get(api_endpoint, params=data, headers=http_header)
+
     try:
-        return response.json();
-    except ValueError:
-        return []
+        # Encode data into url string
+        urlresponse = urlopen(api_endpoint + '?' + urlencode(data))
+
+        # There are some weird bits passed in from the Asterix JSON. 
+        # We will remove them here before we pass the result string 
+        # back to the frontend.
+        urlresult = ""
+        CHUNK = 16 * 1024
+        while True:
+            chunk = urlresponse.read(CHUNK)
+            if not chunk: break
+            urlresult += chunk
+        urlresult = ','.join(urlresult.split(']}{"results":['))
+
+        # Create JSON dump of resulting response 
+        return loads(urlresult)
+
+    except ValueError, e:
+        pass
+
+    except URLError, e:
+
+        # Here we report possible errors in request fulfillment.
+        if hasattr(e, 'reason'):
+            print 'Failed to reach a server.'
+            print 'Reason: ', e.reason
+
+        elif hasattr(e, 'code'):
+            print 'The server couldn\'t fulfill the request.'
+            print 'Error code: ', e.code
 
 # API Endpoints    
 @route('/query')
@@ -45,4 +71,4 @@
     return (build_response("update", dict(request.query)))
     
 res = black_cherry_bootstrap.bootstrap()
-run(host='localhost', port=8080, debug=True)
+run(host='localhost', port=8080, debug=True)
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/black-cherry/static/js/cherry.js b/asterix-examples/src/main/resources/black-cherry/static/js/cherry.js
index aa7a3d1..b187d38 100755
--- a/asterix-examples/src/main/resources/black-cherry/static/js/cherry.js
+++ b/asterix-examples/src/main/resources/black-cherry/static/js/cherry.js
@@ -530,29 +530,39 @@
     var minWeight = Number.MAX_VALUE;
 
     // Parse resulting JSON objects. Here is an example record:
-    // { "cell": { rectangle: [{ point: [22.5, 64.5]}, { point: [24.5, 66.5]}]}, "count": { int64: 5 }}
+    // { "cell": rectangle("21.5,-98.5 24.5,-95.5"), "count": 78i64 }
     $.each(res.results, function(i, data) {
-        
-        // First, parse a JSON object from a cleaned up string.
-        var record = $.parseJSON(cleanJSON(data));
-        
-        // Parse Coordinates and Weights into a record
-        var sw = record.cell.rectangle[0].point;
-        var ne = record.cell.rectangle[1].point;
-                
+
+        // We need to clean the JSON a bit to parse it properly in javascript
+        var cleanRecord = $.parseJSON(data
+                            .replace('rectangle(', '')
+                            .replace(')', '')
+                            .replace('i64', ''));
+
+        var recordCount = cleanRecord["count"];
+        var rectangle = cleanRecord["cell"]
+                            .replace(' ', ',')
+                            .split(',')
+                            .map( parseFloat );
+
+        // Now, using the record count and coordinates, we can create a 
+        // coordinate system for this spatial cell.
         var coordinate = {
-            "latSW"     : sw[0],
-            "lngSW"     : sw[1],
-            "latNE"     : ne[0],
-            "lngNE"     : ne[1],
-            "weight"    : record.count.int64
-        }
+            "latSW"     : rectangle[0],
+            "lngSW"     : rectangle[1],
+            "latNE"     : rectangle[2],
+            "lngNE"     : rectangle[3],
+            "weight"    : recordCount
+        };
         
+        // We track the minimum and maximum weight to support our legend.
         maxWeight = Math.max(coordinate["weight"], maxWeight);
         minWeight = Math.min(coordinate["weight"], minWeight);
+
+        // Save completed coordinate and move to next one.
         coordinates.push(coordinate);
     });
-    
+
     triggerUIUpdate(coordinates, maxWeight, minWeight);
 }
 
@@ -877,8 +887,8 @@
         .ReturnClause({
             "tweetId" : "$m.tweetid",
             "tweetText" : "$t.message-text",
-            "tweetLoc" : "$t.sender-location",
-            "tweetCom" : "$m.comment-text"
+            "tweetCom" : "$m.comment-text",
+            "tweetLoc" : "$t.sender-location"
         });
           
     APIqueryTracker = {
@@ -894,44 +904,46 @@
 
     // Parse out tweet Ids, texts, and locations
     var tweets = [];
-    al = 1;
+    var al = 1;
+
     $.each(res.results, function(i, data) {
 
-        var json = $.parseJSON(cleanJSON(data));
+        // First, clean up the data
+        //{ "tweetId": "100293", "tweetText": " like at&t the touch-screen is amazing", "tweetLoc": point("31.59,-84.23") }
+        // We need to turn the point object at the end into a string
+        var json = $.parseJSON(data
+                                .replace(': point(',': ')
+                                .replace(') }', ' }'));
 
+        // Now, we construct a tweet object
         var tweetData = {
-            "tweetEntryId" : json["tweetId"],
-            "tweetText" : json["tweetText"],
-            "tweetLat" : json["tweetLoc"]["point"][0],
-            "tweetLng" : json["tweetLoc"]["point"][1]
+            "tweetEntryId" : parseInt(json.tweetId),
+            "tweetText" : json.tweetText,
+            "tweetLat" : json.tweetLoc.split(",")[0],
+            "tweetLng" : json.tweetLoc.split(",")[1]
         };
 
         // If we are parsing out tweetbook data with comments, we need to check
         // for those here as well.
         if (json.hasOwnProperty("tweetCom")) {
-            tweetData["tweetComment"] = json["tweetCom"];
+            tweetData["tweetComment"] = json.tweetCom;
         }
 
         tweets.push(tweetData)
     });
 
-    // Prepare to map the tweets
-    var micon = APIqueryTracker["marker_path"];
-    APIqueryTracker["markers_data"] = [];
-
     // Create a marker for each tweet
     $.each(tweets, function(i, t) {
         // Create a phone marker at tweet's position
         var map_tweet_m = new google.maps.Marker({
             position: new google.maps.LatLng(tweets[i]["tweetLat"], tweets[i]["tweetLng"]),
             map: map,
-            icon: micon,
+            icon: APIqueryTracker["marker_path"],
             clickable: true,
         });
         map_tweet_m["test"] = t;
 
         // Open Tweet exploration window on click
-        APIqueryTracker["markers_data"].push(tweets[i]);
         google.maps.event.addListener(map_tweet_m, 'click', function (event) {
             onClickTweetbookMapMarker(map_tweet_markers[i]["test"]);
         });