diff --git a/asterix-examples/src/main/resources/tweetbook-demo/README.md b/asterix-examples/src/main/resources/tweetbook-demo/README.md
new file mode 100755
index 0000000..2b490e0
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/README.md
@@ -0,0 +1,14 @@
+# Tweetbook Demo
+Author: Eugenia Gabrielova (genia.likes.science@gmail.com)
+
+## Dependencies
+1. Python Requests library: [http://docs.python-requests.org/en/latest/user/install/](http://docs.python-requests.org/en/latest/user/install/)
+2. A local, running AsterixDB instance: [http://asterix.ics.uci.edu/documentation/install.html](http://asterix.ics.uci.edu/documentation/install.html)
+
+## Steps
+
+0. With your current working directory as the top level of this demo's hierarchy, execute:
+
+        $ python run_tweetbook_demo.py
+
+1. Visit http://localhost:8080/ in your browser.
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/bottle.py b/asterix-examples/src/main/resources/tweetbook-demo/bottle.py
new file mode 100755
index 0000000..cc3d1f5
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/bottle.py
@@ -0,0 +1,3256 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+Bottle is a fast and simple micro-framework for small web applications. It
+offers request dispatching (Routes) with url parameter support, templates,
+a built-in HTTP Server and adapters for many third party WSGI/HTTP-server and
+template engines - all in a single file and with no dependencies other than the
+Python Standard Library.
+
+Homepage and documentation: http://bottlepy.org/
+
+Copyright (c) 2012, Marcel Hellkamp.
+License: MIT (see LICENSE for details)
+"""
+
+from __future__ import with_statement
+
+__author__ = 'Marcel Hellkamp'
+__version__ = '0.11.6'
+__license__ = 'MIT'
+
+# The gevent server adapter needs to patch some modules before they are imported
+# This is why we parse the commandline parameters here but handle them later
+if __name__ == '__main__':
+    from optparse import OptionParser
+    _cmd_parser = OptionParser(usage="usage: %prog [options] package.module:app")
+    _opt = _cmd_parser.add_option
+    _opt("--version", action="store_true", help="show version number.")
+    _opt("-b", "--bind", metavar="ADDRESS", help="bind socket to ADDRESS.")
+    _opt("-s", "--server", default='wsgiref', help="use SERVER as backend.")
+    _opt("-p", "--plugin", action="append", help="install additional plugin/s.")
+    _opt("--debug", action="store_true", help="start server in debug mode.")
+    _opt("--reload", action="store_true", help="auto-reload on file changes.")
+    _cmd_options, _cmd_args = _cmd_parser.parse_args()
+    if _cmd_options.server and _cmd_options.server.startswith('gevent'):
+        import gevent.monkey; gevent.monkey.patch_all()
+
+import base64, cgi, email.utils, functools, hmac, imp, itertools, mimetypes,\
+        os, re, subprocess, sys, tempfile, threading, time, urllib, warnings
+
+from datetime import date as datedate, datetime, timedelta
+from tempfile import TemporaryFile
+from traceback import format_exc, print_exc
+
+try: from json import dumps as json_dumps, loads as json_lds
+except ImportError: # pragma: no cover
+    try: from simplejson import dumps as json_dumps, loads as json_lds
+    except ImportError:
+        try: from django.utils.simplejson import dumps as json_dumps, loads as json_lds
+        except ImportError:
+            def json_dumps(data):
+                raise ImportError("JSON support requires Python 2.6 or simplejson.")
+            json_lds = json_dumps
+
+
+
+# We now try to fix 2.5/2.6/3.1/3.2 incompatibilities.
+# It ain't pretty but it works... Sorry for the mess.
+
+py   = sys.version_info
+py3k = py >= (3,0,0)
+py25 = py <  (2,6,0)
+py31 = (3,1,0) <= py < (3,2,0)
+
+# Workaround for the missing "as" keyword in py3k.
+def _e(): return sys.exc_info()[1]
+
+# Workaround for the "print is a keyword/function" Python 2/3 dilemma
+# and a fallback for mod_wsgi (resticts stdout/err attribute access)
+try:
+    _stdout, _stderr = sys.stdout.write, sys.stderr.write
+except IOError:
+    _stdout = lambda x: sys.stdout.write(x)
+    _stderr = lambda x: sys.stderr.write(x)
+
+# Lots of stdlib and builtin differences.
+if py3k:
+    import http.client as httplib
+    import _thread as thread
+    from urllib.parse import urljoin, SplitResult as UrlSplitResult
+    from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
+    urlunquote = functools.partial(urlunquote, encoding='latin1')
+    from http.cookies import SimpleCookie
+    from collections import MutableMapping as DictMixin
+    import pickle
+    from io import BytesIO
+    basestring = str
+    unicode = str
+    json_loads = lambda s: json_lds(touni(s))
+    callable = lambda x: hasattr(x, '__call__')
+    imap = map
+else: # 2.x
+    import httplib
+    import thread
+    from urlparse import urljoin, SplitResult as UrlSplitResult
+    from urllib import urlencode, quote as urlquote, unquote as urlunquote
+    from Cookie import SimpleCookie
+    from itertools import imap
+    import cPickle as pickle
+    from StringIO import StringIO as BytesIO
+    if py25:
+        msg = "Python 2.5 support may be dropped in future versions of Bottle."
+        warnings.warn(msg, DeprecationWarning)
+        from UserDict import DictMixin
+        def next(it): return it.next()
+        bytes = str
+    else: # 2.6, 2.7
+        from collections import MutableMapping as DictMixin
+    json_loads = json_lds
+
+# Some helpers for string/byte handling
+def tob(s, enc='utf8'):
+    return s.encode(enc) if isinstance(s, unicode) else bytes(s)
+def touni(s, enc='utf8', err='strict'):
+    return s.decode(enc, err) if isinstance(s, bytes) else unicode(s)
+tonat = touni if py3k else tob
+
+# 3.2 fixes cgi.FieldStorage to accept bytes (which makes a lot of sense).
+# 3.1 needs a workaround.
+if py31:
+    from io import TextIOWrapper
+    class NCTextIOWrapper(TextIOWrapper):
+        def close(self): pass # Keep wrapped buffer open.
+
+# File uploads (which are implemented as empty FiledStorage instances...)
+# have a negative truth value. That makes no sense, here is a fix.
+class FieldStorage(cgi.FieldStorage):
+    def __nonzero__(self): return bool(self.list or self.file)
+    if py3k: __bool__ = __nonzero__
+
+# A bug in functools causes it to break if the wrapper is an instance method
+def update_wrapper(wrapper, wrapped, *a, **ka):
+    try: functools.update_wrapper(wrapper, wrapped, *a, **ka)
+    except AttributeError: pass
+
+
+
+# These helpers are used at module level and need to be defined first.
+# And yes, I know PEP-8, but sometimes a lower-case classname makes more sense.
+
+def depr(message):
+    warnings.warn(message, DeprecationWarning, stacklevel=3)
+
+def makelist(data): # This is just to handy
+    if isinstance(data, (tuple, list, set, dict)): return list(data)
+    elif data: return [data]
+    else: return []
+
+
+class DictProperty(object):
+    ''' Property that maps to a key in a local dict-like attribute. '''
+    def __init__(self, attr, key=None, read_only=False):
+        self.attr, self.key, self.read_only = attr, key, read_only
+
+    def __call__(self, func):
+        functools.update_wrapper(self, func, updated=[])
+        self.getter, self.key = func, self.key or func.__name__
+        return self
+
+    def __get__(self, obj, cls):
+        if obj is None: return self
+        key, storage = self.key, getattr(obj, self.attr)
+        if key not in storage: storage[key] = self.getter(obj)
+        return storage[key]
+
+    def __set__(self, obj, value):
+        if self.read_only: raise AttributeError("Read-Only property.")
+        getattr(obj, self.attr)[self.key] = value
+
+    def __delete__(self, obj):
+        if self.read_only: raise AttributeError("Read-Only property.")
+        del getattr(obj, self.attr)[self.key]
+
+
+class cached_property(object):
+    ''' A property that is only computed once per instance and then replaces
+        itself with an ordinary attribute. Deleting the attribute resets the
+        property. '''
+
+    def __init__(self, func):
+        self.func = func
+
+    def __get__(self, obj, cls):
+        if obj is None: return self
+        value = obj.__dict__[self.func.__name__] = self.func(obj)
+        return value
+
+
+class lazy_attribute(object):
+    ''' A property that caches itself to the class object. '''
+    def __init__(self, func):
+        functools.update_wrapper(self, func, updated=[])
+        self.getter = func
+
+    def __get__(self, obj, cls):
+        value = self.getter(cls)
+        setattr(cls, self.__name__, value)
+        return value
+
+
+
+
+
+
+###############################################################################
+# Exceptions and Events ########################################################
+###############################################################################
+
+
+class BottleException(Exception):
+    """ A base class for exceptions used by bottle. """
+    pass
+
+
+
+
+
+
+###############################################################################
+# Routing ######################################################################
+###############################################################################
+
+
+class RouteError(BottleException):
+    """ This is a base class for all routing related exceptions """
+
+
+class RouteReset(BottleException):
+    """ If raised by a plugin or request handler, the route is reset and all
+        plugins are re-applied. """
+
+class RouterUnknownModeError(RouteError): pass
+
+
+class RouteSyntaxError(RouteError):
+    """ The route parser found something not supported by this router """
+
+
+class RouteBuildError(RouteError):
+    """ The route could not been built """
+
+
+class Router(object):
+    ''' A Router is an ordered collection of route->target pairs. It is used to
+        efficiently match WSGI requests against a number of routes and return
+        the first target that satisfies the request. The target may be anything,
+        usually a string, ID or callable object. A route consists of a path-rule
+        and a HTTP method.
+
+        The path-rule is either a static path (e.g. `/contact`) or a dynamic
+        path that contains wildcards (e.g. `/wiki/<page>`). The wildcard syntax
+        and details on the matching order are described in docs:`routing`.
+    '''
+
+    default_pattern = '[^/]+'
+    default_filter   = 're'
+    #: Sorry for the mess. It works. Trust me.
+    rule_syntax = re.compile('(\\\\*)'\
+        '(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)'\
+          '|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)'\
+            '(?::((?:\\\\.|[^\\\\>]+)+)?)?)?>))')
+
+    def __init__(self, strict=False):
+        self.rules    = {} # A {rule: Rule} mapping
+        self.builder  = {} # A rule/name->build_info mapping
+        self.static   = {} # Cache for static routes: {path: {method: target}}
+        self.dynamic  = [] # Cache for dynamic routes. See _compile()
+        #: If true, static routes are no longer checked first.
+        self.strict_order = strict
+        self.filters = {'re': self.re_filter, 'int': self.int_filter,
+                        'float': self.float_filter, 'path': self.path_filter}
+
+    def re_filter(self, conf):
+        return conf or self.default_pattern, None, None
+
+    def int_filter(self, conf):
+        return r'-?\d+', int, lambda x: str(int(x))
+
+    def float_filter(self, conf):
+        return r'-?[\d.]+', float, lambda x: str(float(x))
+
+    def path_filter(self, conf):
+        return r'.+?', None, None
+
+    def add_filter(self, name, func):
+        ''' Add a filter. The provided function is called with the configuration
+        string as parameter and must return a (regexp, to_python, to_url) tuple.
+        The first element is a string, the last two are callables or None. '''
+        self.filters[name] = func
+
+    def parse_rule(self, rule):
+        ''' Parses a rule into a (name, filter, conf) token stream. If mode is
+            None, name contains a static rule part. '''
+        offset, prefix = 0, ''
+        for match in self.rule_syntax.finditer(rule):
+            prefix += rule[offset:match.start()]
+            g = match.groups()
+            if len(g[0])%2: # Escaped wildcard
+                prefix += match.group(0)[len(g[0]):]
+                offset = match.end()
+                continue
+            if prefix: yield prefix, None, None
+            name, filtr, conf = g[1:4] if not g[2] is None else g[4:7]
+            if not filtr: filtr = self.default_filter
+            yield name, filtr, conf or None
+            offset, prefix = match.end(), ''
+        if offset <= len(rule) or prefix:
+            yield prefix+rule[offset:], None, None
+
+    def add(self, rule, method, target, name=None):
+        ''' Add a new route or replace the target for an existing route. '''
+        if rule in self.rules:
+            self.rules[rule][method] = target
+            if name: self.builder[name] = self.builder[rule]
+            return
+
+        target = self.rules[rule] = {method: target}
+
+        # Build pattern and other structures for dynamic routes
+        anons = 0      # Number of anonymous wildcards
+        pattern = ''   # Regular expression  pattern
+        filters = []   # Lists of wildcard input filters
+        builder = []   # Data structure for the URL builder
+        is_static = True
+        for key, mode, conf in self.parse_rule(rule):
+            if mode:
+                is_static = False
+                mask, in_filter, out_filter = self.filters[mode](conf)
+                if key:
+                    pattern += '(?P<%s>%s)' % (key, mask)
+                else:
+                    pattern += '(?:%s)' % mask
+                    key = 'anon%d' % anons; anons += 1
+                if in_filter: filters.append((key, in_filter))
+                builder.append((key, out_filter or str))
+            elif key:
+                pattern += re.escape(key)
+                builder.append((None, key))
+        self.builder[rule] = builder
+        if name: self.builder[name] = builder
+
+        if is_static and not self.strict_order:
+            self.static[self.build(rule)] = target
+            return
+
+        def fpat_sub(m):
+            return m.group(0) if len(m.group(1)) % 2 else m.group(1) + '(?:'
+        flat_pattern = re.sub(r'(\\*)(\(\?P<[^>]*>|\((?!\?))', fpat_sub, pattern)
+
+        try:
+            re_match = re.compile('^(%s)$' % pattern).match
+        except re.error:
+            raise RouteSyntaxError("Could not add Route: %s (%s)" % (rule, _e()))
+
+        def match(path):
+            """ Return an url-argument dictionary. """
+            url_args = re_match(path).groupdict()
+            for name, wildcard_filter in filters:
+                try:
+                    url_args[name] = wildcard_filter(url_args[name])
+                except ValueError:
+                    raise HTTPError(400, 'Path has wrong format.')
+            return url_args
+
+        try:
+            combined = '%s|(^%s$)' % (self.dynamic[-1][0].pattern, flat_pattern)
+            self.dynamic[-1] = (re.compile(combined), self.dynamic[-1][1])
+            self.dynamic[-1][1].append((match, target))
+        except (AssertionError, IndexError): # AssertionError: Too many groups
+            self.dynamic.append((re.compile('(^%s$)' % flat_pattern),
+                                [(match, target)]))
+        return match
+
+    def build(self, _name, *anons, **query):
+        ''' Build an URL by filling the wildcards in a rule. '''
+        builder = self.builder.get(_name)
+        if not builder: raise RouteBuildError("No route with that name.", _name)
+        try:
+            for i, value in enumerate(anons): query['anon%d'%i] = value
+            url = ''.join([f(query.pop(n)) if n else f for (n,f) in builder])
+            return url if not query else url+'?'+urlencode(query)
+        except KeyError:
+            raise RouteBuildError('Missing URL argument: %r' % _e().args[0])
+
+    def match(self, environ):
+        ''' Return a (target, url_agrs) tuple or raise HTTPError(400/404/405). '''
+        path, targets, urlargs = environ['PATH_INFO'] or '/', None, {}
+        if path in self.static:
+            targets = self.static[path]
+        else:
+            for combined, rules in self.dynamic:
+                match = combined.match(path)
+                if not match: continue
+                getargs, targets = rules[match.lastindex - 1]
+                urlargs = getargs(path) if getargs else {}
+                break
+
+        if not targets:
+            raise HTTPError(404, "Not found: " + repr(environ['PATH_INFO']))
+        method = environ['REQUEST_METHOD'].upper()
+        if method in targets:
+            return targets[method], urlargs
+        if method == 'HEAD' and 'GET' in targets:
+            return targets['GET'], urlargs
+        if 'ANY' in targets:
+            return targets['ANY'], urlargs
+        allowed = [verb for verb in targets if verb != 'ANY']
+        if 'GET' in allowed and 'HEAD' not in allowed:
+            allowed.append('HEAD')
+        raise HTTPError(405, "Method not allowed.", Allow=",".join(allowed))
+
+
+class Route(object):
+    ''' This class wraps a route callback along with route specific metadata and
+        configuration and applies Plugins on demand. It is also responsible for
+        turing an URL path rule into a regular expression usable by the Router.
+    '''
+
+    def __init__(self, app, rule, method, callback, name=None,
+                 plugins=None, skiplist=None, **config):
+        #: The application this route is installed to.
+        self.app = app
+        #: The path-rule string (e.g. ``/wiki/:page``).
+        self.rule = rule
+        #: The HTTP method as a string (e.g. ``GET``).
+        self.method = method
+        #: The original callback with no plugins applied. Useful for introspection.
+        self.callback = callback
+        #: The name of the route (if specified) or ``None``.
+        self.name = name or None
+        #: A list of route-specific plugins (see :meth:`Bottle.route`).
+        self.plugins = plugins or []
+        #: A list of plugins to not apply to this route (see :meth:`Bottle.route`).
+        self.skiplist = skiplist or []
+        #: Additional keyword arguments passed to the :meth:`Bottle.route`
+        #: decorator are stored in this dictionary. Used for route-specific
+        #: plugin configuration and meta-data.
+        self.config = ConfigDict(config)
+
+    def __call__(self, *a, **ka):
+        depr("Some APIs changed to return Route() instances instead of"\
+             " callables. Make sure to use the Route.call method and not to"\
+             " call Route instances directly.")
+        return self.call(*a, **ka)
+
+    @cached_property
+    def call(self):
+        ''' The route callback with all plugins applied. This property is
+            created on demand and then cached to speed up subsequent requests.'''
+        return self._make_callback()
+
+    def reset(self):
+        ''' Forget any cached values. The next time :attr:`call` is accessed,
+            all plugins are re-applied. '''
+        self.__dict__.pop('call', None)
+
+    def prepare(self):
+        ''' Do all on-demand work immediately (useful for debugging).'''
+        self.call
+
+    @property
+    def _context(self):
+        depr('Switch to Plugin API v2 and access the Route object directly.')
+        return dict(rule=self.rule, method=self.method, callback=self.callback,
+                    name=self.name, app=self.app, config=self.config,
+                    apply=self.plugins, skip=self.skiplist)
+
+    def all_plugins(self):
+        ''' Yield all Plugins affecting this route. '''
+        unique = set()
+        for p in reversed(self.app.plugins + self.plugins):
+            if True in self.skiplist: break
+            name = getattr(p, 'name', False)
+            if name and (name in self.skiplist or name in unique): continue
+            if p in self.skiplist or type(p) in self.skiplist: continue
+            if name: unique.add(name)
+            yield p
+
+    def _make_callback(self):
+        callback = self.callback
+        for plugin in self.all_plugins():
+            try:
+                if hasattr(plugin, 'apply'):
+                    api = getattr(plugin, 'api', 1)
+                    context = self if api > 1 else self._context
+                    callback = plugin.apply(callback, context)
+                else:
+                    callback = plugin(callback)
+            except RouteReset: # Try again with changed configuration.
+                return self._make_callback()
+            if not callback is self.callback:
+                update_wrapper(callback, self.callback)
+        return callback
+
+    def __repr__(self):
+        return '<%s %r %r>' % (self.method, self.rule, self.callback)
+
+
+
+
+
+
+###############################################################################
+# Application Object ###########################################################
+###############################################################################
+
+
+class Bottle(object):
+    """ Each Bottle object represents a single, distinct web application and
+        consists of routes, callbacks, plugins, resources and configuration.
+        Instances are callable WSGI applications.
+
+        :param catchall: If true (default), handle all exceptions. Turn off to
+                         let debugging middleware handle exceptions.
+    """
+
+    def __init__(self, catchall=True, autojson=True):
+        #: If true, most exceptions are caught and returned as :exc:`HTTPError`
+        self.catchall = catchall
+
+        #: A :class:`ResourceManager` for application files
+        self.resources = ResourceManager()
+
+        #: A :class:`ConfigDict` for app specific configuration.
+        self.config = ConfigDict()
+        self.config.autojson = autojson
+
+        self.routes = [] # List of installed :class:`Route` instances.
+        self.router = Router() # Maps requests to :class:`Route` instances.
+        self.error_handler = {}
+
+        # Core plugins
+        self.plugins = [] # List of installed plugins.
+        self.hooks = HooksPlugin()
+        self.install(self.hooks)
+        if self.config.autojson:
+            self.install(JSONPlugin())
+        self.install(TemplatePlugin())
+
+
+    def mount(self, prefix, app, **options):
+        ''' Mount an application (:class:`Bottle` or plain WSGI) to a specific
+            URL prefix. Example::
+
+                root_app.mount('/admin/', admin_app)
+
+            :param prefix: path prefix or `mount-point`. If it ends in a slash,
+                that slash is mandatory.
+            :param app: an instance of :class:`Bottle` or a WSGI application.
+
+            All other parameters are passed to the underlying :meth:`route` call.
+        '''
+        if isinstance(app, basestring):
+            prefix, app = app, prefix
+            depr('Parameter order of Bottle.mount() changed.') # 0.10
+
+        segments = [p for p in prefix.split('/') if p]
+        if not segments: raise ValueError('Empty path prefix.')
+        path_depth = len(segments)
+
+        def mountpoint_wrapper():
+            try:
+                request.path_shift(path_depth)
+                rs = HTTPResponse([])
+                def start_response(status, headerlist):
+                    rs.status = status
+                    for name, value in headerlist: rs.add_header(name, value)
+                    return rs.body.append
+                body = app(request.environ, start_response)
+                if body and rs.body: body = itertools.chain(rs.body, body)
+                rs.body = body or rs.body
+                return rs
+            finally:
+                request.path_shift(-path_depth)
+
+        options.setdefault('skip', True)
+        options.setdefault('method', 'ANY')
+        options.setdefault('mountpoint', {'prefix': prefix, 'target': app})
+        options['callback'] = mountpoint_wrapper
+
+        self.route('/%s/<:re:.*>' % '/'.join(segments), **options)
+        if not prefix.endswith('/'):
+            self.route('/' + '/'.join(segments), **options)
+
+    def merge(self, routes):
+        ''' Merge the routes of another :class:`Bottle` application or a list of
+            :class:`Route` objects into this application. The routes keep their
+            'owner', meaning that the :data:`Route.app` attribute is not
+            changed. '''
+        if isinstance(routes, Bottle):
+            routes = routes.routes
+        for route in routes:
+            self.add_route(route)
+
+    def install(self, plugin):
+        ''' Add a plugin to the list of plugins and prepare it for being
+            applied to all routes of this application. A plugin may be a simple
+            decorator or an object that implements the :class:`Plugin` API.
+        '''
+        if hasattr(plugin, 'setup'): plugin.setup(self)
+        if not callable(plugin) and not hasattr(plugin, 'apply'):
+            raise TypeError("Plugins must be callable or implement .apply()")
+        self.plugins.append(plugin)
+        self.reset()
+        return plugin
+
+    def uninstall(self, plugin):
+        ''' Uninstall plugins. Pass an instance to remove a specific plugin, a type
+            object to remove all plugins that match that type, a string to remove
+            all plugins with a matching ``name`` attribute or ``True`` to remove all
+            plugins. Return the list of removed plugins. '''
+        removed, remove = [], plugin
+        for i, plugin in list(enumerate(self.plugins))[::-1]:
+            if remove is True or remove is plugin or remove is type(plugin) \
+            or getattr(plugin, 'name', True) == remove:
+                removed.append(plugin)
+                del self.plugins[i]
+                if hasattr(plugin, 'close'): plugin.close()
+        if removed: self.reset()
+        return removed
+
+    def run(self, **kwargs):
+        ''' Calls :func:`run` with the same parameters. '''
+        run(self, **kwargs)
+
+    def reset(self, route=None):
+        ''' Reset all routes (force plugins to be re-applied) and clear all
+            caches. If an ID or route object is given, only that specific route
+            is affected. '''
+        if route is None: routes = self.routes
+        elif isinstance(route, Route): routes = [route]
+        else: routes = [self.routes[route]]
+        for route in routes: route.reset()
+        if DEBUG:
+            for route in routes: route.prepare()
+        self.hooks.trigger('app_reset')
+
+    def close(self):
+        ''' Close the application and all installed plugins. '''
+        for plugin in self.plugins:
+            if hasattr(plugin, 'close'): plugin.close()
+        self.stopped = True
+
+    def match(self, environ):
+        """ Search for a matching route and return a (:class:`Route` , urlargs)
+            tuple. The second value is a dictionary with parameters extracted
+            from the URL. Raise :exc:`HTTPError` (404/405) on a non-match."""
+        return self.router.match(environ)
+
+    def get_url(self, routename, **kargs):
+        """ Return a string that matches a named route """
+        scriptname = request.environ.get('SCRIPT_NAME', '').strip('/') + '/'
+        location = self.router.build(routename, **kargs).lstrip('/')
+        return urljoin(urljoin('/', scriptname), location)
+
+    def add_route(self, route):
+        ''' Add a route object, but do not change the :data:`Route.app`
+            attribute.'''
+        self.routes.append(route)
+        self.router.add(route.rule, route.method, route, name=route.name)
+        if DEBUG: route.prepare()
+
+    def route(self, path=None, method='GET', callback=None, name=None,
+              apply=None, skip=None, **config):
+        """ A decorator to bind a function to a request URL. Example::
+
+                @app.route('/hello/:name')
+                def hello(name):
+                    return 'Hello %s' % name
+
+            The ``:name`` part is a wildcard. See :class:`Router` for syntax
+            details.
+
+            :param path: Request path or a list of paths to listen to. If no
+              path is specified, it is automatically generated from the
+              signature of the function.
+            :param method: HTTP method (`GET`, `POST`, `PUT`, ...) or a list of
+              methods to listen to. (default: `GET`)
+            :param callback: An optional shortcut to avoid the decorator
+              syntax. ``route(..., callback=func)`` equals ``route(...)(func)``
+            :param name: The name for this route. (default: None)
+            :param apply: A decorator or plugin or a list of plugins. These are
+              applied to the route callback in addition to installed plugins.
+            :param skip: A list of plugins, plugin classes or names. Matching
+              plugins are not installed to this route. ``True`` skips all.
+
+            Any additional keyword arguments are stored as route-specific
+            configuration and passed to plugins (see :meth:`Plugin.apply`).
+        """
+        if callable(path): path, callback = None, path
+        plugins = makelist(apply)
+        skiplist = makelist(skip)
+        def decorator(callback):
+            # TODO: Documentation and tests
+            if isinstance(callback, basestring): callback = load(callback)
+            for rule in makelist(path) or yieldroutes(callback):
+                for verb in makelist(method):
+                    verb = verb.upper()
+                    route = Route(self, rule, verb, callback, name=name,
+                                  plugins=plugins, skiplist=skiplist, **config)
+                    self.add_route(route)
+            return callback
+        return decorator(callback) if callback else decorator
+
+    def get(self, path=None, method='GET', **options):
+        """ Equals :meth:`route`. """
+        return self.route(path, method, **options)
+
+    def post(self, path=None, method='POST', **options):
+        """ Equals :meth:`route` with a ``POST`` method parameter. """
+        return self.route(path, method, **options)
+
+    def put(self, path=None, method='PUT', **options):
+        """ Equals :meth:`route` with a ``PUT`` method parameter. """
+        return self.route(path, method, **options)
+
+    def delete(self, path=None, method='DELETE', **options):
+        """ Equals :meth:`route` with a ``DELETE`` method parameter. """
+        return self.route(path, method, **options)
+
+    def error(self, code=500):
+        """ Decorator: Register an output handler for a HTTP error code"""
+        def wrapper(handler):
+            self.error_handler[int(code)] = handler
+            return handler
+        return wrapper
+
+    def hook(self, name):
+        """ Return a decorator that attaches a callback to a hook. Three hooks
+            are currently implemented:
+
+            - before_request: Executed once before each request
+            - after_request: Executed once after each request
+            - app_reset: Called whenever :meth:`reset` is called.
+        """
+        def wrapper(func):
+            self.hooks.add(name, func)
+            return func
+        return wrapper
+
+    def handle(self, path, method='GET'):
+        """ (deprecated) Execute the first matching route callback and return
+            the result. :exc:`HTTPResponse` exceptions are caught and returned.
+            If :attr:`Bottle.catchall` is true, other exceptions are caught as
+            well and returned as :exc:`HTTPError` instances (500).
+        """
+        depr("This method will change semantics in 0.10. Try to avoid it.")
+        if isinstance(path, dict):
+            return self._handle(path)
+        return self._handle({'PATH_INFO': path, 'REQUEST_METHOD': method.upper()})
+
+    def default_error_handler(self, res):
+        return tob(template(ERROR_PAGE_TEMPLATE, e=res))
+
+    def _handle(self, environ):
+        try:
+            environ['bottle.app'] = self
+            request.bind(environ)
+            response.bind()
+            route, args = self.router.match(environ)
+            environ['route.handle'] = route
+            environ['bottle.route'] = route
+            environ['route.url_args'] = args
+            return route.call(**args)
+        except HTTPResponse:
+            return _e()
+        except RouteReset:
+            route.reset()
+            return self._handle(environ)
+        except (KeyboardInterrupt, SystemExit, MemoryError):
+            raise
+        except Exception:
+            if not self.catchall: raise
+            stacktrace = format_exc()
+            environ['wsgi.errors'].write(stacktrace)
+            return HTTPError(500, "Internal Server Error", _e(), stacktrace)
+
+    def _cast(self, out, peek=None):
+        """ Try to convert the parameter into something WSGI compatible and set
+        correct HTTP headers when possible.
+        Support: False, str, unicode, dict, HTTPResponse, HTTPError, file-like,
+        iterable of strings and iterable of unicodes
+        """
+
+        # Empty output is done here
+        if not out:
+            if 'Content-Length' not in response:
+                response['Content-Length'] = 0
+            return []
+        # Join lists of byte or unicode strings. Mixed lists are NOT supported
+        if isinstance(out, (tuple, list))\
+        and isinstance(out[0], (bytes, unicode)):
+            out = out[0][0:0].join(out) # b'abc'[0:0] -> b''
+        # Encode unicode strings
+        if isinstance(out, unicode):
+            out = out.encode(response.charset)
+        # Byte Strings are just returned
+        if isinstance(out, bytes):
+            if 'Content-Length' not in response:
+                response['Content-Length'] = len(out)
+            return [out]
+        # HTTPError or HTTPException (recursive, because they may wrap anything)
+        # TODO: Handle these explicitly in handle() or make them iterable.
+        if isinstance(out, HTTPError):
+            out.apply(response)
+            out = self.error_handler.get(out.status_code, self.default_error_handler)(out)
+            return self._cast(out)
+        if isinstance(out, HTTPResponse):
+            out.apply(response)
+            return self._cast(out.body)
+
+        # File-like objects.
+        if hasattr(out, 'read'):
+            if 'wsgi.file_wrapper' in request.environ:
+                return request.environ['wsgi.file_wrapper'](out)
+            elif hasattr(out, 'close') or not hasattr(out, '__iter__'):
+                return WSGIFileWrapper(out)
+
+        # Handle Iterables. We peek into them to detect their inner type.
+        try:
+            out = iter(out)
+            first = next(out)
+            while not first:
+                first = next(out)
+        except StopIteration:
+            return self._cast('')
+        except HTTPResponse:
+            first = _e()
+        except (KeyboardInterrupt, SystemExit, MemoryError):
+            raise
+        except Exception:
+            if not self.catchall: raise
+            first = HTTPError(500, 'Unhandled exception', _e(), format_exc())
+
+        # These are the inner types allowed in iterator or generator objects.
+        if isinstance(first, HTTPResponse):
+            return self._cast(first)
+        if isinstance(first, bytes):
+            return itertools.chain([first], out)
+        if isinstance(first, unicode):
+            return imap(lambda x: x.encode(response.charset),
+                                  itertools.chain([first], out))
+        return self._cast(HTTPError(500, 'Unsupported response type: %s'\
+                                         % type(first)))
+
+    def wsgi(self, environ, start_response):
+        """ The bottle WSGI-interface. """
+        try:
+            out = self._cast(self._handle(environ))
+            # rfc2616 section 4.3
+            if response._status_code in (100, 101, 204, 304)\
+            or environ['REQUEST_METHOD'] == 'HEAD':
+                if hasattr(out, 'close'): out.close()
+                out = []
+            start_response(response._status_line, response.headerlist)
+            return out
+        except (KeyboardInterrupt, SystemExit, MemoryError):
+            raise
+        except Exception:
+            if not self.catchall: raise
+            err = '<h1>Critical error while processing request: %s</h1>' \
+                  % html_escape(environ.get('PATH_INFO', '/'))
+            if DEBUG:
+                err += '<h2>Error:</h2>\n<pre>\n%s\n</pre>\n' \
+                       '<h2>Traceback:</h2>\n<pre>\n%s\n</pre>\n' \
+                       % (html_escape(repr(_e())), html_escape(format_exc()))
+            environ['wsgi.errors'].write(err)
+            headers = [('Content-Type', 'text/html; charset=UTF-8')]
+            start_response('500 INTERNAL SERVER ERROR', headers)
+            return [tob(err)]
+
+    def __call__(self, environ, start_response):
+        ''' Each instance of :class:'Bottle' is a WSGI application. '''
+        return self.wsgi(environ, start_response)
+
+
+
+
+
+
+###############################################################################
+# HTTP and WSGI Tools ##########################################################
+###############################################################################
+
+
+class BaseRequest(object):
+    """ A wrapper for WSGI environment dictionaries that adds a lot of
+        convenient access methods and properties. Most of them are read-only.
+
+        Adding new attributes to a request actually adds them to the environ
+        dictionary (as 'bottle.request.ext.<name>'). This is the recommended
+        way to store and access request-specific data.
+    """
+
+    __slots__ = ('environ')
+
+    #: Maximum size of memory buffer for :attr:`body` in bytes.
+    MEMFILE_MAX = 2000000000
+    #: Maximum number pr GET or POST parameters per request
+    MAX_PARAMS  = 100
+
+    def __init__(self, environ=None):
+        """ Wrap a WSGI environ dictionary. """
+        #: The wrapped WSGI environ dictionary. This is the only real attribute.
+        #: All other attributes actually are read-only properties.
+        self.environ = {} if environ is None else environ
+        self.environ['bottle.request'] = self
+
+    @DictProperty('environ', 'bottle.app', read_only=True)
+    def app(self):
+        ''' Bottle application handling this request. '''
+        raise RuntimeError('This request is not connected to an application.')
+
+    @property
+    def path(self):
+        ''' The value of ``PATH_INFO`` with exactly one prefixed slash (to fix
+            broken clients and avoid the "empty path" edge case). '''
+        return '/' + self.environ.get('PATH_INFO','').lstrip('/')
+
+    @property
+    def method(self):
+        ''' The ``REQUEST_METHOD`` value as an uppercase string. '''
+        return self.environ.get('REQUEST_METHOD', 'GET').upper()
+
+    @DictProperty('environ', 'bottle.request.headers', read_only=True)
+    def headers(self):
+        ''' A :class:`WSGIHeaderDict` that provides case-insensitive access to
+            HTTP request headers. '''
+        return WSGIHeaderDict(self.environ)
+
+    def get_header(self, name, default=None):
+        ''' Return the value of a request header, or a given default value. '''
+        return self.headers.get(name, default)
+
+    @DictProperty('environ', 'bottle.request.cookies', read_only=True)
+    def cookies(self):
+        """ Cookies parsed into a :class:`FormsDict`. Signed cookies are NOT
+            decoded. Use :meth:`get_cookie` if you expect signed cookies. """
+        cookies = SimpleCookie(self.environ.get('HTTP_COOKIE',''))
+        cookies = list(cookies.values())[:self.MAX_PARAMS]
+        return FormsDict((c.key, c.value) for c in cookies)
+
+    def get_cookie(self, key, default=None, secret=None):
+        """ Return the content of a cookie. To read a `Signed Cookie`, the
+            `secret` must match the one used to create the cookie (see
+            :meth:`BaseResponse.set_cookie`). If anything goes wrong (missing
+            cookie or wrong signature), return a default value. """
+        value = self.cookies.get(key)
+        if secret and value:
+            dec = cookie_decode(value, secret) # (key, value) tuple or None
+            return dec[1] if dec and dec[0] == key else default
+        return value or default
+
+    @DictProperty('environ', 'bottle.request.query', read_only=True)
+    def query(self):
+        ''' The :attr:`query_string` parsed into a :class:`FormsDict`. These
+            values are sometimes called "URL arguments" or "GET parameters", but
+            not to be confused with "URL wildcards" as they are provided by the
+            :class:`Router`. '''
+        get = self.environ['bottle.get'] = FormsDict()
+        pairs = _parse_qsl(self.environ.get('QUERY_STRING', ''))
+        for key, value in pairs[:self.MAX_PARAMS]:
+            get[key] = value
+        return get
+
+    @DictProperty('environ', 'bottle.request.forms', read_only=True)
+    def forms(self):
+        """ Form values parsed from an `url-encoded` or `multipart/form-data`
+            encoded POST or PUT request body. The result is retuned as a
+            :class:`FormsDict`. All keys and values are strings. File uploads
+            are stored separately in :attr:`files`. """
+        forms = FormsDict()
+        for name, item in self.POST.allitems():
+            if not hasattr(item, 'filename'):
+                forms[name] = item
+        return forms
+
+    @DictProperty('environ', 'bottle.request.params', read_only=True)
+    def params(self):
+        """ A :class:`FormsDict` with the combined values of :attr:`query` and
+            :attr:`forms`. File uploads are stored in :attr:`files`. """
+        params = FormsDict()
+        for key, value in self.query.allitems():
+            params[key] = value
+        for key, value in self.forms.allitems():
+            params[key] = value
+        return params
+
+    @DictProperty('environ', 'bottle.request.files', read_only=True)
+    def files(self):
+        """ File uploads parsed from an `url-encoded` or `multipart/form-data`
+            encoded POST or PUT request body. The values are instances of
+            :class:`cgi.FieldStorage`. The most important attributes are:
+
+            filename
+                The filename, if specified; otherwise None; this is the client
+                side filename, *not* the file name on which it is stored (that's
+                a temporary file you don't deal with)
+            file
+                The file(-like) object from which you can read the data.
+            value
+                The value as a *string*; for file uploads, this transparently
+                reads the file every time you request the value. Do not do this
+                on big files.
+        """
+        files = FormsDict()
+        for name, item in self.POST.allitems():
+            if hasattr(item, 'filename'):
+                files[name] = item
+        return files
+
+    @DictProperty('environ', 'bottle.request.json', read_only=True)
+    def json(self):
+        ''' If the ``Content-Type`` header is ``application/json``, this
+            property holds the parsed content of the request body. Only requests
+            smaller than :attr:`MEMFILE_MAX` are processed to avoid memory
+            exhaustion. '''
+        if 'application/json' in self.environ.get('CONTENT_TYPE', '') \
+        and 0 < self.content_length < self.MEMFILE_MAX:
+            return json_loads(self.body.read(self.MEMFILE_MAX))
+        return None
+
+    @DictProperty('environ', 'bottle.request.body', read_only=True)
+    def _body(self):
+        maxread = max(0, self.content_length)
+        stream = self.environ['wsgi.input']
+        body = BytesIO() if maxread < self.MEMFILE_MAX else TemporaryFile(mode='w+b')
+        while maxread > 0:
+            part = stream.read(min(maxread, self.MEMFILE_MAX))
+            if not part: break
+            body.write(part)
+            maxread -= len(part)
+        self.environ['wsgi.input'] = body
+        body.seek(0)
+        return body
+
+    @property
+    def body(self):
+        """ The HTTP request body as a seek-able file-like object. Depending on
+            :attr:`MEMFILE_MAX`, this is either a temporary file or a
+            :class:`io.BytesIO` instance. Accessing this property for the first
+            time reads and replaces the ``wsgi.input`` environ variable.
+            Subsequent accesses just do a `seek(0)` on the file object. """
+        self._body.seek(0)
+        return self._body
+
+    #: An alias for :attr:`query`.
+    GET = query
+
+    @DictProperty('environ', 'bottle.request.post', read_only=True)
+    def POST(self):
+        """ The values of :attr:`forms` and :attr:`files` combined into a single
+            :class:`FormsDict`. Values are either strings (form values) or
+            instances of :class:`cgi.FieldStorage` (file uploads).
+        """
+        post = FormsDict()
+        # We default to application/x-www-form-urlencoded for everything that
+        # is not multipart and take the fast path (also: 3.1 workaround)
+        if not self.content_type.startswith('multipart/'):
+            maxlen = max(0, min(self.content_length, self.MEMFILE_MAX))
+            pairs = _parse_qsl(tonat(self.body.read(maxlen), 'latin1'))
+            for key, value in pairs[:self.MAX_PARAMS]:
+                post[key] = value
+            return post
+
+        safe_env = {'QUERY_STRING':''} # Build a safe environment for cgi
+        for key in ('REQUEST_METHOD', 'CONTENT_TYPE', 'CONTENT_LENGTH'):
+            if key in self.environ: safe_env[key] = self.environ[key]
+        args = dict(fp=self.body, environ=safe_env, keep_blank_values=True)
+        if py31:
+            args['fp'] = NCTextIOWrapper(args['fp'], encoding='ISO-8859-1',
+                                         newline='\n')
+        elif py3k:
+            args['encoding'] = 'ISO-8859-1'
+        data = FieldStorage(**args)
+        for item in (data.list or [])[:self.MAX_PARAMS]:
+            post[item.name] = item if item.filename else item.value
+        return post
+
+    @property
+    def COOKIES(self):
+        ''' Alias for :attr:`cookies` (deprecated). '''
+        depr('BaseRequest.COOKIES was renamed to BaseRequest.cookies (lowercase).')
+        return self.cookies
+
+    @property
+    def url(self):
+        """ The full request URI including hostname and scheme. If your app
+            lives behind a reverse proxy or load balancer and you get confusing
+            results, make sure that the ``X-Forwarded-Host`` header is set
+            correctly. """
+        return self.urlparts.geturl()
+
+    @DictProperty('environ', 'bottle.request.urlparts', read_only=True)
+    def urlparts(self):
+        ''' The :attr:`url` string as an :class:`urlparse.SplitResult` tuple.
+            The tuple contains (scheme, host, path, query_string and fragment),
+            but the fragment is always empty because it is not visible to the
+            server. '''
+        env = self.environ
+        http = env.get('HTTP_X_FORWARDED_PROTO') or env.get('wsgi.url_scheme', 'http')
+        host = env.get('HTTP_X_FORWARDED_HOST') or env.get('HTTP_HOST')
+        if not host:
+            # HTTP 1.1 requires a Host-header. This is for HTTP/1.0 clients.
+            host = env.get('SERVER_NAME', '127.0.0.1')
+            port = env.get('SERVER_PORT')
+            if port and port != ('80' if http == 'http' else '443'):
+                host += ':' + port
+        path = urlquote(self.fullpath)
+        return UrlSplitResult(http, host, path, env.get('QUERY_STRING'), '')
+
+    @property
+    def fullpath(self):
+        """ Request path including :attr:`script_name` (if present). """
+        return urljoin(self.script_name, self.path.lstrip('/'))
+
+    @property
+    def query_string(self):
+        """ The raw :attr:`query` part of the URL (everything in between ``?``
+            and ``#``) as a string. """
+        return self.environ.get('QUERY_STRING', '')
+
+    @property
+    def script_name(self):
+        ''' The initial portion of the URL's `path` that was removed by a higher
+            level (server or routing middleware) before the application was
+            called. This script path is returned with leading and tailing
+            slashes. '''
+        script_name = self.environ.get('SCRIPT_NAME', '').strip('/')
+        return '/' + script_name + '/' if script_name else '/'
+
+    def path_shift(self, shift=1):
+        ''' Shift path segments from :attr:`path` to :attr:`script_name` and
+            vice versa.
+
+           :param shift: The number of path segments to shift. May be negative
+                         to change the shift direction. (default: 1)
+        '''
+        script = self.environ.get('SCRIPT_NAME','/')
+        self['SCRIPT_NAME'], self['PATH_INFO'] = path_shift(script, self.path, shift)
+
+    @property
+    def content_length(self):
+        ''' The request body length as an integer. The client is responsible to
+            set this header. Otherwise, the real length of the body is unknown
+            and -1 is returned. In this case, :attr:`body` will be empty. '''
+        return int(self.environ.get('CONTENT_LENGTH') or -1)
+
+    @property
+    def content_type(self):
+        ''' The Content-Type header as a lowercase-string (default: empty). '''
+        return self.environ.get('CONTENT_TYPE', '').lower()
+
+    @property
+    def is_xhr(self):
+        ''' True if the request was triggered by a XMLHttpRequest. This only
+            works with JavaScript libraries that support the `X-Requested-With`
+            header (most of the popular libraries do). '''
+        requested_with = self.environ.get('HTTP_X_REQUESTED_WITH','')
+        return requested_with.lower() == 'xmlhttprequest'
+
+    @property
+    def is_ajax(self):
+        ''' Alias for :attr:`is_xhr`. "Ajax" is not the right term. '''
+        return self.is_xhr
+
+    @property
+    def auth(self):
+        """ HTTP authentication data as a (user, password) tuple. This
+            implementation currently supports basic (not digest) authentication
+            only. If the authentication happened at a higher level (e.g. in the
+            front web-server or a middleware), the password field is None, but
+            the user field is looked up from the ``REMOTE_USER`` environ
+            variable. On any errors, None is returned. """
+        basic = parse_auth(self.environ.get('HTTP_AUTHORIZATION',''))
+        if basic: return basic
+        ruser = self.environ.get('REMOTE_USER')
+        if ruser: return (ruser, None)
+        return None
+
+    @property
+    def remote_route(self):
+        """ A list of all IPs that were involved in this request, starting with
+            the client IP and followed by zero or more proxies. This does only
+            work if all proxies support the ```X-Forwarded-For`` header. Note
+            that this information can be forged by malicious clients. """
+        proxy = self.environ.get('HTTP_X_FORWARDED_FOR')
+        if proxy: return [ip.strip() for ip in proxy.split(',')]
+        remote = self.environ.get('REMOTE_ADDR')
+        return [remote] if remote else []
+
+    @property
+    def remote_addr(self):
+        """ The client IP as a string. Note that this information can be forged
+            by malicious clients. """
+        route = self.remote_route
+        return route[0] if route else None
+
+    def copy(self):
+        """ Return a new :class:`Request` with a shallow :attr:`environ` copy. """
+        return Request(self.environ.copy())
+
+    def get(self, value, default=None): return self.environ.get(value, default)
+    def __getitem__(self, key): return self.environ[key]
+    def __delitem__(self, key): self[key] = ""; del(self.environ[key])
+    def __iter__(self): return iter(self.environ)
+    def __len__(self): return len(self.environ)
+    def keys(self): return self.environ.keys()
+    def __setitem__(self, key, value):
+        """ Change an environ value and clear all caches that depend on it. """
+
+        if self.environ.get('bottle.request.readonly'):
+            raise KeyError('The environ dictionary is read-only.')
+
+        self.environ[key] = value
+        todelete = ()
+
+        if key == 'wsgi.input':
+            todelete = ('body', 'forms', 'files', 'params', 'post', 'json')
+        elif key == 'QUERY_STRING':
+            todelete = ('query', 'params')
+        elif key.startswith('HTTP_'):
+            todelete = ('headers', 'cookies')
+
+        for key in todelete:
+            self.environ.pop('bottle.request.'+key, None)
+
+    def __repr__(self):
+        return '<%s: %s %s>' % (self.__class__.__name__, self.method, self.url)
+
+    def __getattr__(self, name):
+        ''' Search in self.environ for additional user defined attributes. '''
+        try:
+            var = self.environ['bottle.request.ext.%s'%name]
+            return var.__get__(self) if hasattr(var, '__get__') else var
+        except KeyError:
+            raise AttributeError('Attribute %r not defined.' % name)
+
+    def __setattr__(self, name, value):
+        if name == 'environ': return object.__setattr__(self, name, value)
+        self.environ['bottle.request.ext.%s'%name] = value
+
+
+
+
+def _hkey(s):
+    return s.title().replace('_','-')
+
+
+class HeaderProperty(object):
+    def __init__(self, name, reader=None, writer=str, default=''):
+        self.name, self.default = name, default
+        self.reader, self.writer = reader, writer
+        self.__doc__ = 'Current value of the %r header.' % name.title()
+
+    def __get__(self, obj, cls):
+        if obj is None: return self
+        value = obj.headers.get(self.name, self.default)
+        return self.reader(value) if self.reader else value
+
+    def __set__(self, obj, value):
+        obj.headers[self.name] = self.writer(value)
+
+    def __delete__(self, obj):
+        del obj.headers[self.name]
+
+
+class BaseResponse(object):
+    """ Storage class for a response body as well as headers and cookies.
+
+        This class does support dict-like case-insensitive item-access to
+        headers, but is NOT a dict. Most notably, iterating over a response
+        yields parts of the body and not the headers.
+    """
+
+    default_status = 200
+    default_content_type = 'text/html; charset=UTF-8'
+
+    # Header blacklist for specific response codes
+    # (rfc2616 section 10.2.3 and 10.3.5)
+    bad_headers = {
+        204: set(('Content-Type',)),
+        304: set(('Allow', 'Content-Encoding', 'Content-Language',
+                  'Content-Length', 'Content-Range', 'Content-Type',
+                  'Content-Md5', 'Last-Modified'))}
+
+    def __init__(self, body='', status=None, **headers):
+        self._cookies = None
+        self._headers = {}
+        self.body = body
+        self.status = status or self.default_status
+        if headers:
+            for name, value in headers.items():
+                self[name] = value
+
+    def copy(self):
+        ''' Returns a copy of self. '''
+        copy = Response()
+        copy.status = self.status
+        copy._headers = dict((k, v[:]) for (k, v) in self._headers.items())
+        return copy
+
+    def __iter__(self):
+        return iter(self.body)
+
+    def close(self):
+        if hasattr(self.body, 'close'):
+            self.body.close()
+
+    @property
+    def status_line(self):
+        ''' The HTTP status line as a string (e.g. ``404 Not Found``).'''
+        return self._status_line
+
+    @property
+    def status_code(self):
+        ''' The HTTP status code as an integer (e.g. 404).'''
+        return self._status_code
+
+    def _set_status(self, status):
+        if isinstance(status, int):
+            code, status = status, _HTTP_STATUS_LINES.get(status)
+        elif ' ' in status:
+            status = status.strip()
+            code   = int(status.split()[0])
+        else:
+            raise ValueError('String status line without a reason phrase.')
+        if not 100 <= code <= 999: raise ValueError('Status code out of range.')
+        self._status_code = code
+        self._status_line = str(status or ('%d Unknown' % code))
+
+    def _get_status(self):
+        return self._status_line
+
+    status = property(_get_status, _set_status, None,
+        ''' A writeable property to change the HTTP response status. It accepts
+            either a numeric code (100-999) or a string with a custom reason
+            phrase (e.g. "404 Brain not found"). Both :data:`status_line` and
+            :data:`status_code` are updated accordingly. The return value is
+            always a status string. ''')
+    del _get_status, _set_status
+
+    @property
+    def headers(self):
+        ''' An instance of :class:`HeaderDict`, a case-insensitive dict-like
+            view on the response headers. '''
+        hdict = HeaderDict()
+        hdict.dict = self._headers
+        return hdict
+
+    def __contains__(self, name): return _hkey(name) in self._headers
+    def __delitem__(self, name):  del self._headers[_hkey(name)]
+    def __getitem__(self, name):  return self._headers[_hkey(name)][-1]
+    def __setitem__(self, name, value): self._headers[_hkey(name)] = [str(value)]
+
+    def get_header(self, name, default=None):
+        ''' Return the value of a previously defined header. If there is no
+            header with that name, return a default value. '''
+        return self._headers.get(_hkey(name), [default])[-1]
+
+    def set_header(self, name, value):
+        ''' Create a new response header, replacing any previously defined
+            headers with the same name. '''
+        self._headers[_hkey(name)] = [str(value)]
+
+    def add_header(self, name, value):
+        ''' Add an additional response header, not removing duplicates. '''
+        self._headers.setdefault(_hkey(name), []).append(str(value))
+
+    def iter_headers(self):
+        ''' Yield (header, value) tuples, skipping headers that are not
+            allowed with the current response status code. '''
+        return self.headerlist
+
+    def wsgiheader(self):
+        depr('The wsgiheader method is deprecated. See headerlist.') #0.10
+        return self.headerlist
+
+    @property
+    def headerlist(self):
+        ''' WSGI conform list of (header, value) tuples. '''
+        out = []
+        headers = list(self._headers.items())
+        if 'Content-Type' not in self._headers:
+            headers.append(('Content-Type', [self.default_content_type]))
+        if self._status_code in self.bad_headers:
+            bad_headers = self.bad_headers[self._status_code]
+            headers = [h for h in headers if h[0] not in bad_headers]
+        out += [(name, val) for name, vals in headers for val in vals]
+        if self._cookies:
+            for c in self._cookies.values():
+                out.append(('Set-Cookie', c.OutputString()))
+        return out
+
+    content_type = HeaderProperty('Content-Type')
+    content_length = HeaderProperty('Content-Length', reader=int)
+
+    @property
+    def charset(self):
+        """ Return the charset specified in the content-type header (default: utf8). """
+        if 'charset=' in self.content_type:
+            return self.content_type.split('charset=')[-1].split(';')[0].strip()
+        return 'UTF-8'
+
+    @property
+    def COOKIES(self):
+        """ A dict-like SimpleCookie instance. This should not be used directly.
+            See :meth:`set_cookie`. """
+        depr('The COOKIES dict is deprecated. Use `set_cookie()` instead.') # 0.10
+        if not self._cookies:
+            self._cookies = SimpleCookie()
+        return self._cookies
+
+    def set_cookie(self, name, value, secret=None, **options):
+        ''' Create a new cookie or replace an old one. If the `secret` parameter is
+            set, create a `Signed Cookie` (described below).
+
+            :param name: the name of the cookie.
+            :param value: the value of the cookie.
+            :param secret: a signature key required for signed cookies.
+
+            Additionally, this method accepts all RFC 2109 attributes that are
+            supported by :class:`cookie.Morsel`, including:
+
+            :param max_age: maximum age in seconds. (default: None)
+            :param expires: a datetime object or UNIX timestamp. (default: None)
+            :param domain: the domain that is allowed to read the cookie.
+              (default: current domain)
+            :param path: limits the cookie to a given path (default: current path)
+            :param secure: limit the cookie to HTTPS connections (default: off).
+            :param httponly: prevents client-side javascript to read this cookie
+              (default: off, requires Python 2.6 or newer).
+
+            If neither `expires` nor `max_age` is set (default), the cookie will
+            expire at the end of the browser session (as soon as the browser
+            window is closed).
+
+            Signed cookies may store any pickle-able object and are
+            cryptographically signed to prevent manipulation. Keep in mind that
+            cookies are limited to 4kb in most browsers.
+
+            Warning: Signed cookies are not encrypted (the client can still see
+            the content) and not copy-protected (the client can restore an old
+            cookie). The main intention is to make pickling and unpickling
+            save, not to store secret information at client side.
+        '''
+        if not self._cookies:
+            self._cookies = SimpleCookie()
+
+        if secret:
+            value = touni(cookie_encode((name, value), secret))
+        elif not isinstance(value, basestring):
+            raise TypeError('Secret key missing for non-string Cookie.')
+
+        if len(value) > 4096: raise ValueError('Cookie value to long.')
+        self._cookies[name] = value
+
+        for key, value in options.items():
+            if key == 'max_age':
+                if isinstance(value, timedelta):
+                    value = value.seconds + value.days * 24 * 3600
+            if key == 'expires':
+                if isinstance(value, (datedate, datetime)):
+                    value = value.timetuple()
+                elif isinstance(value, (int, float)):
+                    value = time.gmtime(value)
+                value = time.strftime("%a, %d %b %Y %H:%M:%S GMT", value)
+            self._cookies[name][key.replace('_', '-')] = value
+
+    def delete_cookie(self, key, **kwargs):
+        ''' Delete a cookie. Be sure to use the same `domain` and `path`
+            settings as used to create the cookie. '''
+        kwargs['max_age'] = -1
+        kwargs['expires'] = 0
+        self.set_cookie(key, '', **kwargs)
+
+    def __repr__(self):
+        out = ''
+        for name, value in self.headerlist:
+            out += '%s: %s\n' % (name.title(), value.strip())
+        return out
+
+#: Thread-local storage for :class:`LocalRequest` and :class:`LocalResponse`
+#: attributes.
+_lctx = threading.local()
+
+def local_property(name):
+    def fget(self):
+        try:
+            return getattr(_lctx, name)
+        except AttributeError:
+            raise RuntimeError("Request context not initialized.")
+    def fset(self, value): setattr(_lctx, name, value)
+    def fdel(self): delattr(_lctx, name)
+    return property(fget, fset, fdel,
+        'Thread-local property stored in :data:`_lctx.%s`' % name)
+
+
+class LocalRequest(BaseRequest):
+    ''' A thread-local subclass of :class:`BaseRequest` with a different
+        set of attribues for each thread. There is usually only one global
+        instance of this class (:data:`request`). If accessed during a
+        request/response cycle, this instance always refers to the *current*
+        request (even on a multithreaded server). '''
+    bind = BaseRequest.__init__
+    environ = local_property('request_environ')
+
+
+class LocalResponse(BaseResponse):
+    ''' A thread-local subclass of :class:`BaseResponse` with a different
+        set of attribues for each thread. There is usually only one global
+        instance of this class (:data:`response`). Its attributes are used
+        to build the HTTP response at the end of the request/response cycle.
+    '''
+    bind = BaseResponse.__init__
+    _status_line = local_property('response_status_line')
+    _status_code = local_property('response_status_code')
+    _cookies     = local_property('response_cookies')
+    _headers     = local_property('response_headers')
+    body         = local_property('response_body')
+
+Request = BaseRequest
+Response = BaseResponse
+
+class HTTPResponse(Response, BottleException):
+    def __init__(self, body='', status=None, header=None, **headers):
+        if header or 'output' in headers:
+            depr('Call signature changed (for the better)')
+            if header: headers.update(header)
+            if 'output' in headers: body = headers.pop('output')
+        super(HTTPResponse, self).__init__(body, status, **headers)
+
+    def apply(self, response):
+        response._status_code = self._status_code
+        response._status_line = self._status_line
+        response._headers = self._headers
+        response._cookies = self._cookies
+        response.body = self.body
+
+    def _output(self, value=None):
+        depr('Use HTTPResponse.body instead of HTTPResponse.output')
+        if value is None: return self.body
+        self.body = value
+
+    output = property(_output, _output, doc='Alias for .body')
+
+class HTTPError(HTTPResponse):
+    default_status = 500
+    def __init__(self, status=None, body=None, exception=None, traceback=None, header=None, **headers):
+        self.exception = exception
+        self.traceback = traceback
+        super(HTTPError, self).__init__(body, status, header, **headers)
+
+
+
+
+
+###############################################################################
+# Plugins ######################################################################
+###############################################################################
+
+class PluginError(BottleException): pass
+
+class JSONPlugin(object):
+    name = 'json'
+    api  = 2
+
+    def __init__(self, json_dumps=json_dumps):
+        self.json_dumps = json_dumps
+
+    def apply(self, callback, route):
+        dumps = self.json_dumps
+        if not dumps: return callback
+        def wrapper(*a, **ka):
+            rv = callback(*a, **ka)
+            if isinstance(rv, dict):
+                #Attempt to serialize, raises exception on failure
+                json_response = dumps(rv)
+                #Set content type only if serialization succesful
+                response.content_type = 'application/json'
+                return json_response
+            return rv
+        return wrapper
+
+
+class HooksPlugin(object):
+    name = 'hooks'
+    api  = 2
+
+    _names = 'before_request', 'after_request', 'app_reset'
+
+    def __init__(self):
+        self.hooks = dict((name, []) for name in self._names)
+        self.app = None
+
+    def _empty(self):
+        return not (self.hooks['before_request'] or self.hooks['after_request'])
+
+    def setup(self, app):
+        self.app = app
+
+    def add(self, name, func):
+        ''' Attach a callback to a hook. '''
+        was_empty = self._empty()
+        self.hooks.setdefault(name, []).append(func)
+        if self.app and was_empty and not self._empty(): self.app.reset()
+
+    def remove(self, name, func):
+        ''' Remove a callback from a hook. '''
+        was_empty = self._empty()
+        if name in self.hooks and func in self.hooks[name]:
+            self.hooks[name].remove(func)
+        if self.app and not was_empty and self._empty(): self.app.reset()
+
+    def trigger(self, name, *a, **ka):
+        ''' Trigger a hook and return a list of results. '''
+        hooks = self.hooks[name]
+        if ka.pop('reversed', False): hooks = hooks[::-1]
+        return [hook(*a, **ka) for hook in hooks]
+
+    def apply(self, callback, route):
+        if self._empty(): return callback
+        def wrapper(*a, **ka):
+            self.trigger('before_request')
+            rv = callback(*a, **ka)
+            self.trigger('after_request', reversed=True)
+            return rv
+        return wrapper
+
+
+class TemplatePlugin(object):
+    ''' This plugin applies the :func:`view` decorator to all routes with a
+        `template` config parameter. If the parameter is a tuple, the second
+        element must be a dict with additional options (e.g. `template_engine`)
+        or default variables for the template. '''
+    name = 'template'
+    api  = 2
+
+    def apply(self, callback, route):
+        conf = route.config.get('template')
+        if isinstance(conf, (tuple, list)) and len(conf) == 2:
+            return view(conf[0], **conf[1])(callback)
+        elif isinstance(conf, str) and 'template_opts' in route.config:
+            depr('The `template_opts` parameter is deprecated.') #0.9
+            return view(conf, **route.config['template_opts'])(callback)
+        elif isinstance(conf, str):
+            return view(conf)(callback)
+        else:
+            return callback
+
+
+#: Not a plugin, but part of the plugin API. TODO: Find a better place.
+class _ImportRedirect(object):
+    def __init__(self, name, impmask):
+        ''' Create a virtual package that redirects imports (see PEP 302). '''
+        self.name = name
+        self.impmask = impmask
+        self.module = sys.modules.setdefault(name, imp.new_module(name))
+        self.module.__dict__.update({'__file__': __file__, '__path__': [],
+                                    '__all__': [], '__loader__': self})
+        sys.meta_path.append(self)
+
+    def find_module(self, fullname, path=None):
+        if '.' not in fullname: return
+        packname, modname = fullname.rsplit('.', 1)
+        if packname != self.name: return
+        return self
+
+    def load_module(self, fullname):
+        if fullname in sys.modules: return sys.modules[fullname]
+        packname, modname = fullname.rsplit('.', 1)
+        realname = self.impmask % modname
+        __import__(realname)
+        module = sys.modules[fullname] = sys.modules[realname]
+        setattr(self.module, modname, module)
+        module.__loader__ = self
+        return module
+
+
+
+
+
+
+###############################################################################
+# Common Utilities #############################################################
+###############################################################################
+
+
+class MultiDict(DictMixin):
+    """ This dict stores multiple values per key, but behaves exactly like a
+        normal dict in that it returns only the newest value for any given key.
+        There are special methods available to access the full list of values.
+    """
+
+    def __init__(self, *a, **k):
+        self.dict = dict((k, [v]) for (k, v) in dict(*a, **k).items())
+
+    def __len__(self): return len(self.dict)
+    def __iter__(self): return iter(self.dict)
+    def __contains__(self, key): return key in self.dict
+    def __delitem__(self, key): del self.dict[key]
+    def __getitem__(self, key): return self.dict[key][-1]
+    def __setitem__(self, key, value): self.append(key, value)
+    def keys(self): return self.dict.keys()
+
+    if py3k:
+        def values(self): return (v[-1] for v in self.dict.values())
+        def items(self): return ((k, v[-1]) for k, v in self.dict.items())
+        def allitems(self):
+            return ((k, v) for k, vl in self.dict.items() for v in vl)
+        iterkeys = keys
+        itervalues = values
+        iteritems = items
+        iterallitems = allitems
+
+    else:
+        def values(self): return [v[-1] for v in self.dict.values()]
+        def items(self): return [(k, v[-1]) for k, v in self.dict.items()]
+        def iterkeys(self): return self.dict.iterkeys()
+        def itervalues(self): return (v[-1] for v in self.dict.itervalues())
+        def iteritems(self):
+            return ((k, v[-1]) for k, v in self.dict.iteritems())
+        def iterallitems(self):
+            return ((k, v) for k, vl in self.dict.iteritems() for v in vl)
+        def allitems(self):
+            return [(k, v) for k, vl in self.dict.iteritems() for v in vl]
+
+    def get(self, key, default=None, index=-1, type=None):
+        ''' Return the most recent value for a key.
+
+            :param default: The default value to be returned if the key is not
+                   present or the type conversion fails.
+            :param index: An index for the list of available values.
+            :param type: If defined, this callable is used to cast the value
+                    into a specific type. Exception are suppressed and result in
+                    the default value to be returned.
+        '''
+        try:
+            val = self.dict[key][index]
+            return type(val) if type else val
+        except Exception:
+            pass
+        return default
+
+    def append(self, key, value):
+        ''' Add a new value to the list of values for this key. '''
+        self.dict.setdefault(key, []).append(value)
+
+    def replace(self, key, value):
+        ''' Replace the list of values with a single value. '''
+        self.dict[key] = [value]
+
+    def getall(self, key):
+        ''' Return a (possibly empty) list of values for a key. '''
+        return self.dict.get(key) or []
+
+    #: Aliases for WTForms to mimic other multi-dict APIs (Django)
+    getone = get
+    getlist = getall
+
+
+
+class FormsDict(MultiDict):
+    ''' This :class:`MultiDict` subclass is used to store request form data.
+        Additionally to the normal dict-like item access methods (which return
+        unmodified data as native strings), this container also supports
+        attribute-like access to its values. Attributes are automatically de-
+        or recoded to match :attr:`input_encoding` (default: 'utf8'). Missing
+        attributes default to an empty string. '''
+
+    #: Encoding used for attribute values.
+    input_encoding = 'utf8'
+    #: If true (default), unicode strings are first encoded with `latin1`
+    #: and then decoded to match :attr:`input_encoding`.
+    recode_unicode = True
+
+    def _fix(self, s, encoding=None):
+        if isinstance(s, unicode) and self.recode_unicode: # Python 3 WSGI
+            s = s.encode('latin1')
+        if isinstance(s, bytes): # Python 2 WSGI
+            return s.decode(encoding or self.input_encoding)
+        return s
+
+    def decode(self, encoding=None):
+        ''' Returns a copy with all keys and values de- or recoded to match
+            :attr:`input_encoding`. Some libraries (e.g. WTForms) want a
+            unicode dictionary. '''
+        copy = FormsDict()
+        enc = copy.input_encoding = encoding or self.input_encoding
+        copy.recode_unicode = False
+        for key, value in self.allitems():
+            copy.append(self._fix(key, enc), self._fix(value, enc))
+        return copy
+
+    def getunicode(self, name, default=None, encoding=None):
+        try:
+            return self._fix(self[name], encoding)
+        except (UnicodeError, KeyError):
+            return default
+
+    def __getattr__(self, name, default=unicode()):
+        # Without this guard, pickle generates a cryptic TypeError:
+        if name.startswith('__') and name.endswith('__'):
+            return super(FormsDict, self).__getattr__(name)
+        return self.getunicode(name, default=default)
+
+
+class HeaderDict(MultiDict):
+    """ A case-insensitive version of :class:`MultiDict` that defaults to
+        replace the old value instead of appending it. """
+
+    def __init__(self, *a, **ka):
+        self.dict = {}
+        if a or ka: self.update(*a, **ka)
+
+    def __contains__(self, key): return _hkey(key) in self.dict
+    def __delitem__(self, key): del self.dict[_hkey(key)]
+    def __getitem__(self, key): return self.dict[_hkey(key)][-1]
+    def __setitem__(self, key, value): self.dict[_hkey(key)] = [str(value)]
+    def append(self, key, value):
+        self.dict.setdefault(_hkey(key), []).append(str(value))
+    def replace(self, key, value): self.dict[_hkey(key)] = [str(value)]
+    def getall(self, key): return self.dict.get(_hkey(key)) or []
+    def get(self, key, default=None, index=-1):
+        return MultiDict.get(self, _hkey(key), default, index)
+    def filter(self, names):
+        for name in [_hkey(n) for n in names]:
+            if name in self.dict:
+                del self.dict[name]
+
+
+class WSGIHeaderDict(DictMixin):
+    ''' This dict-like class wraps a WSGI environ dict and provides convenient
+        access to HTTP_* fields. Keys and values are native strings
+        (2.x bytes or 3.x unicode) and keys are case-insensitive. If the WSGI
+        environment contains non-native string values, these are de- or encoded
+        using a lossless 'latin1' character set.
+
+        The API will remain stable even on changes to the relevant PEPs.
+        Currently PEP 333, 444 and 3333 are supported. (PEP 444 is the only one
+        that uses non-native strings.)
+    '''
+    #: List of keys that do not have a ``HTTP_`` prefix.
+    cgikeys = ('CONTENT_TYPE', 'CONTENT_LENGTH')
+
+    def __init__(self, environ):
+        self.environ = environ
+
+    def _ekey(self, key):
+        ''' Translate header field name to CGI/WSGI environ key. '''
+        key = key.replace('-','_').upper()
+        if key in self.cgikeys:
+            return key
+        return 'HTTP_' + key
+
+    def raw(self, key, default=None):
+        ''' Return the header value as is (may be bytes or unicode). '''
+        return self.environ.get(self._ekey(key), default)
+
+    def __getitem__(self, key):
+        return tonat(self.environ[self._ekey(key)], 'latin1')
+
+    def __setitem__(self, key, value):
+        raise TypeError("%s is read-only." % self.__class__)
+
+    def __delitem__(self, key):
+        raise TypeError("%s is read-only." % self.__class__)
+
+    def __iter__(self):
+        for key in self.environ:
+            if key[:5] == 'HTTP_':
+                yield key[5:].replace('_', '-').title()
+            elif key in self.cgikeys:
+                yield key.replace('_', '-').title()
+
+    def keys(self): return [x for x in self]
+    def __len__(self): return len(self.keys())
+    def __contains__(self, key): return self._ekey(key) in self.environ
+
+
+class ConfigDict(dict):
+    ''' A dict-subclass with some extras: You can access keys like attributes.
+        Uppercase attributes create new ConfigDicts and act as name-spaces.
+        Other missing attributes return None. Calling a ConfigDict updates its
+        values and returns itself.
+
+        >>> cfg = ConfigDict()
+        >>> cfg.Namespace.value = 5
+        >>> cfg.OtherNamespace(a=1, b=2)
+        >>> cfg
+        {'Namespace': {'value': 5}, 'OtherNamespace': {'a': 1, 'b': 2}}
+    '''
+
+    def __getattr__(self, key):
+        if key not in self and key[0].isupper():
+            self[key] = ConfigDict()
+        return self.get(key)
+
+    def __setattr__(self, key, value):
+        if hasattr(dict, key):
+            raise AttributeError('Read-only attribute.')
+        if key in self and self[key] and isinstance(self[key], ConfigDict):
+            raise AttributeError('Non-empty namespace attribute.')
+        self[key] = value
+
+    def __delattr__(self, key):
+        if key in self: del self[key]
+
+    def __call__(self, *a, **ka):
+        for key, value in dict(*a, **ka).items(): setattr(self, key, value)
+        return self
+
+
+class AppStack(list):
+    """ A stack-like list. Calling it returns the head of the stack. """
+
+    def __call__(self):
+        """ Return the current default application. """
+        return self[-1]
+
+    def push(self, value=None):
+        """ Add a new :class:`Bottle` instance to the stack """
+        if not isinstance(value, Bottle):
+            value = Bottle()
+        self.append(value)
+        return value
+
+
+class WSGIFileWrapper(object):
+
+    def __init__(self, fp, buffer_size=1024*64):
+        self.fp, self.buffer_size = fp, buffer_size
+        for attr in ('fileno', 'close', 'read', 'readlines', 'tell', 'seek'):
+            if hasattr(fp, attr): setattr(self, attr, getattr(fp, attr))
+
+    def __iter__(self):
+        buff, read = self.buffer_size, self.read
+        while True:
+            part = read(buff)
+            if not part: return
+            yield part
+
+
+class ResourceManager(object):
+    ''' This class manages a list of search paths and helps to find and open
+        application-bound resources (files).
+
+        :param base: default value for :meth:`add_path` calls.
+        :param opener: callable used to open resources.
+        :param cachemode: controls which lookups are cached. One of 'all',
+                         'found' or 'none'.
+    '''
+
+    def __init__(self, base='./', opener=open, cachemode='all'):
+        self.opener = open
+        self.base = base
+        self.cachemode = cachemode
+
+        #: A list of search paths. See :meth:`add_path` for details.
+        self.path = []
+        #: A cache for resolved paths. ``res.cache.clear()`` clears the cache.
+        self.cache = {}
+
+    def add_path(self, path, base=None, index=None, create=False):
+        ''' Add a new path to the list of search paths. Return False if the
+            path does not exist.
+
+            :param path: The new search path. Relative paths are turned into
+                an absolute and normalized form. If the path looks like a file
+                (not ending in `/`), the filename is stripped off.
+            :param base: Path used to absolutize relative search paths.
+                Defaults to :attr:`base` which defaults to ``os.getcwd()``.
+            :param index: Position within the list of search paths. Defaults
+                to last index (appends to the list).
+
+            The `base` parameter makes it easy to reference files installed
+            along with a python module or package::
+
+                res.add_path('./resources/', __file__)
+        '''
+        base = os.path.abspath(os.path.dirname(base or self.base))
+        path = os.path.abspath(os.path.join(base, os.path.dirname(path)))
+        path += os.sep
+        if path in self.path:
+            self.path.remove(path)
+        if create and not os.path.isdir(path):
+            os.makedirs(path)
+        if index is None:
+            self.path.append(path)
+        else:
+            self.path.insert(index, path)
+        self.cache.clear()
+        return os.path.exists(path)
+
+    def __iter__(self):
+        ''' Iterate over all existing files in all registered paths. '''
+        search = self.path[:]
+        while search:
+            path = search.pop()
+            if not os.path.isdir(path): continue
+            for name in os.listdir(path):
+                full = os.path.join(path, name)
+                if os.path.isdir(full): search.append(full)
+                else: yield full
+
+    def lookup(self, name):
+        ''' Search for a resource and return an absolute file path, or `None`.
+
+            The :attr:`path` list is searched in order. The first match is
+            returend. Symlinks are followed. The result is cached to speed up
+            future lookups. '''
+        if name not in self.cache or DEBUG:
+            for path in self.path:
+                fpath = os.path.join(path, name)
+                if os.path.isfile(fpath):
+                    if self.cachemode in ('all', 'found'):
+                        self.cache[name] = fpath
+                    return fpath
+            if self.cachemode == 'all':
+                self.cache[name] = None
+        return self.cache[name]
+
+    def open(self, name, mode='r', *args, **kwargs):
+        ''' Find a resource and return a file object, or raise IOError. '''
+        fname = self.lookup(name)
+        if not fname: raise IOError("Resource %r not found." % name)
+        return self.opener(name, mode=mode, *args, **kwargs)
+
+
+
+
+
+
+###############################################################################
+# Application Helper ###########################################################
+###############################################################################
+
+
+def abort(code=500, text='Unknown Error: Application stopped.'):
+    """ Aborts execution and causes a HTTP error. """
+    raise HTTPError(code, text)
+
+
+def redirect(url, code=None):
+    """ Aborts execution and causes a 303 or 302 redirect, depending on
+        the HTTP protocol version. """
+    if code is None:
+        code = 303 if request.get('SERVER_PROTOCOL') == "HTTP/1.1" else 302
+    location = urljoin(request.url, url)
+    res = HTTPResponse("", status=code, Location=location)
+    if response._cookies:
+        res._cookies = response._cookies
+    raise res
+
+
+def _file_iter_range(fp, offset, bytes, maxread=1024*1024):
+    ''' Yield chunks from a range in a file. No chunk is bigger than maxread.'''
+    fp.seek(offset)
+    while bytes > 0:
+        part = fp.read(min(bytes, maxread))
+        if not part: break
+        bytes -= len(part)
+        yield part
+
+
+def static_file(filename, root, mimetype='auto', download=False):
+    """ Open a file in a safe way and return :exc:`HTTPResponse` with status
+        code 200, 305, 401 or 404. Set Content-Type, Content-Encoding,
+        Content-Length and Last-Modified header. Obey If-Modified-Since header
+        and HEAD requests.
+    """
+    root = os.path.abspath(root) + os.sep
+    filename = os.path.abspath(os.path.join(root, filename.strip('/\\')))
+    headers = dict()
+
+    if not filename.startswith(root):
+        return HTTPError(403, "Access denied.")
+    if not os.path.exists(filename) or not os.path.isfile(filename):
+        return HTTPError(404, "File does not exist.")
+    if not os.access(filename, os.R_OK):
+        return HTTPError(403, "You do not have permission to access this file.")
+
+    if mimetype == 'auto':
+        mimetype, encoding = mimetypes.guess_type(filename)
+        if mimetype: headers['Content-Type'] = mimetype
+        if encoding: headers['Content-Encoding'] = encoding
+    elif mimetype:
+        headers['Content-Type'] = mimetype
+
+    if download:
+        download = os.path.basename(filename if download == True else download)
+        headers['Content-Disposition'] = 'attachment; filename="%s"' % download
+
+    stats = os.stat(filename)
+    headers['Content-Length'] = clen = stats.st_size
+    lm = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(stats.st_mtime))
+    headers['Last-Modified'] = lm
+
+    ims = request.environ.get('HTTP_IF_MODIFIED_SINCE')
+    if ims:
+        ims = parse_date(ims.split(";")[0].strip())
+    if ims is not None and ims >= int(stats.st_mtime):
+        headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
+        return HTTPResponse(status=304, **headers)
+
+    body = '' if request.method == 'HEAD' else open(filename, 'rb')
+
+    headers["Accept-Ranges"] = "bytes"
+    ranges = request.environ.get('HTTP_RANGE')
+    if 'HTTP_RANGE' in request.environ:
+        ranges = list(parse_range_header(request.environ['HTTP_RANGE'], clen))
+        if not ranges:
+            return HTTPError(416, "Requested Range Not Satisfiable")
+        offset, end = ranges[0]
+        headers["Content-Range"] = "bytes %d-%d/%d" % (offset, end-1, clen)
+        headers["Content-Length"] = str(end-offset)
+        if body: body = _file_iter_range(body, offset, end-offset)
+        return HTTPResponse(body, status=206, **headers)
+    return HTTPResponse(body, **headers)
+
+
+
+
+
+
+###############################################################################
+# HTTP Utilities and MISC (TODO) ###############################################
+###############################################################################
+
+
+def debug(mode=True):
+    """ Change the debug level.
+    There is only one debug level supported at the moment."""
+    global DEBUG
+    DEBUG = bool(mode)
+
+
+def parse_date(ims):
+    """ Parse rfc1123, rfc850 and asctime timestamps and return UTC epoch. """
+    try:
+        ts = email.utils.parsedate_tz(ims)
+        return time.mktime(ts[:8] + (0,)) - (ts[9] or 0) - time.timezone
+    except (TypeError, ValueError, IndexError, OverflowError):
+        return None
+
+
+def parse_auth(header):
+    """ Parse rfc2617 HTTP authentication header string (basic) and return (user,pass) tuple or None"""
+    try:
+        method, data = header.split(None, 1)
+        if method.lower() == 'basic':
+            user, pwd = touni(base64.b64decode(tob(data))).split(':',1)
+            return user, pwd
+    except (KeyError, ValueError):
+        return None
+
+def parse_range_header(header, maxlen=0):
+    ''' Yield (start, end) ranges parsed from a HTTP Range header. Skip
+        unsatisfiable ranges. The end index is non-inclusive.'''
+    if not header or header[:6] != 'bytes=': return
+    ranges = [r.split('-', 1) for r in header[6:].split(',') if '-' in r]
+    for start, end in ranges:
+        try:
+            if not start:  # bytes=-100    -> last 100 bytes
+                start, end = max(0, maxlen-int(end)), maxlen
+            elif not end:  # bytes=100-    -> all but the first 99 bytes
+                start, end = int(start), maxlen
+            else:          # bytes=100-200 -> bytes 100-200 (inclusive)
+                start, end = int(start), min(int(end)+1, maxlen)
+            if 0 <= start < end <= maxlen:
+                yield start, end
+        except ValueError:
+            pass
+
+def _parse_qsl(qs):
+    r = []
+    for pair in qs.replace(';','&').split('&'):
+        if not pair: continue
+        nv = pair.split('=', 1)
+        if len(nv) != 2: nv.append('')
+        key = urlunquote(nv[0].replace('+', ' '))
+        value = urlunquote(nv[1].replace('+', ' '))
+        r.append((key, value))
+    return r
+
+def _lscmp(a, b):
+    ''' Compares two strings in a cryptographically safe way:
+        Runtime is not affected by length of common prefix. '''
+    return not sum(0 if x==y else 1 for x, y in zip(a, b)) and len(a) == len(b)
+
+
+def cookie_encode(data, key):
+    ''' Encode and sign a pickle-able object. Return a (byte) string '''
+    msg = base64.b64encode(pickle.dumps(data, -1))
+    sig = base64.b64encode(hmac.new(tob(key), msg).digest())
+    return tob('!') + sig + tob('?') + msg
+
+
+def cookie_decode(data, key):
+    ''' Verify and decode an encoded string. Return an object or None.'''
+    data = tob(data)
+    if cookie_is_encoded(data):
+        sig, msg = data.split(tob('?'), 1)
+        if _lscmp(sig[1:], base64.b64encode(hmac.new(tob(key), msg).digest())):
+            return pickle.loads(base64.b64decode(msg))
+    return None
+
+
+def cookie_is_encoded(data):
+    ''' Return True if the argument looks like a encoded cookie.'''
+    return bool(data.startswith(tob('!')) and tob('?') in data)
+
+
+def html_escape(string):
+    ''' Escape HTML special characters ``&<>`` and quotes ``'"``. '''
+    return string.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')\
+                 .replace('"','&quot;').replace("'",'&#039;')
+
+
+def html_quote(string):
+    ''' Escape and quote a string to be used as an HTTP attribute.'''
+    return '"%s"' % html_escape(string).replace('\n','%#10;')\
+                    .replace('\r','&#13;').replace('\t','&#9;')
+
+
+def yieldroutes(func):
+    """ Return a generator for routes that match the signature (name, args)
+    of the func parameter. This may yield more than one route if the function
+    takes optional keyword arguments. The output is best described by example::
+
+        a()         -> '/a'
+        b(x, y)     -> '/b/:x/:y'
+        c(x, y=5)   -> '/c/:x' and '/c/:x/:y'
+        d(x=5, y=6) -> '/d' and '/d/:x' and '/d/:x/:y'
+    """
+    import inspect # Expensive module. Only import if necessary.
+    path = '/' + func.__name__.replace('__','/').lstrip('/')
+    spec = inspect.getargspec(func)
+    argc = len(spec[0]) - len(spec[3] or [])
+    path += ('/:%s' * argc) % tuple(spec[0][:argc])
+    yield path
+    for arg in spec[0][argc:]:
+        path += '/:%s' % arg
+        yield path
+
+
+def path_shift(script_name, path_info, shift=1):
+    ''' Shift path fragments from PATH_INFO to SCRIPT_NAME and vice versa.
+
+        :return: The modified paths.
+        :param script_name: The SCRIPT_NAME path.
+        :param script_name: The PATH_INFO path.
+        :param shift: The number of path fragments to shift. May be negative to
+          change the shift direction. (default: 1)
+    '''
+    if shift == 0: return script_name, path_info
+    pathlist = path_info.strip('/').split('/')
+    scriptlist = script_name.strip('/').split('/')
+    if pathlist and pathlist[0] == '': pathlist = []
+    if scriptlist and scriptlist[0] == '': scriptlist = []
+    if shift > 0 and shift <= len(pathlist):
+        moved = pathlist[:shift]
+        scriptlist = scriptlist + moved
+        pathlist = pathlist[shift:]
+    elif shift < 0 and shift >= -len(scriptlist):
+        moved = scriptlist[shift:]
+        pathlist = moved + pathlist
+        scriptlist = scriptlist[:shift]
+    else:
+        empty = 'SCRIPT_NAME' if shift < 0 else 'PATH_INFO'
+        raise AssertionError("Cannot shift. Nothing left from %s" % empty)
+    new_script_name = '/' + '/'.join(scriptlist)
+    new_path_info = '/' + '/'.join(pathlist)
+    if path_info.endswith('/') and pathlist: new_path_info += '/'
+    return new_script_name, new_path_info
+
+
+def validate(**vkargs):
+    """
+    Validates and manipulates keyword arguments by user defined callables.
+    Handles ValueError and missing arguments by raising HTTPError(403).
+    """
+    depr('Use route wildcard filters instead.')
+    def decorator(func):
+        @functools.wraps(func)
+        def wrapper(*args, **kargs):
+            for key, value in vkargs.items():
+                if key not in kargs:
+                    abort(403, 'Missing parameter: %s' % key)
+                try:
+                    kargs[key] = value(kargs[key])
+                except ValueError:
+                    abort(403, 'Wrong parameter format for: %s' % key)
+            return func(*args, **kargs)
+        return wrapper
+    return decorator
+
+
+def auth_basic(check, realm="private", text="Access denied"):
+    ''' Callback decorator to require HTTP auth (basic).
+        TODO: Add route(check_auth=...) parameter. '''
+    def decorator(func):
+      def wrapper(*a, **ka):
+        user, password = request.auth or (None, None)
+        if user is None or not check(user, password):
+          response.headers['WWW-Authenticate'] = 'Basic realm="%s"' % realm
+          return HTTPError(401, text)
+        return func(*a, **ka)
+      return wrapper
+    return decorator
+
+
+# Shortcuts for common Bottle methods.
+# They all refer to the current default application.
+
+def make_default_app_wrapper(name):
+    ''' Return a callable that relays calls to the current default app. '''
+    @functools.wraps(getattr(Bottle, name))
+    def wrapper(*a, **ka):
+        return getattr(app(), name)(*a, **ka)
+    return wrapper
+
+route     = make_default_app_wrapper('route')
+get       = make_default_app_wrapper('get')
+post      = make_default_app_wrapper('post')
+put       = make_default_app_wrapper('put')
+delete    = make_default_app_wrapper('delete')
+error     = make_default_app_wrapper('error')
+mount     = make_default_app_wrapper('mount')
+hook      = make_default_app_wrapper('hook')
+install   = make_default_app_wrapper('install')
+uninstall = make_default_app_wrapper('uninstall')
+url       = make_default_app_wrapper('get_url')
+
+
+
+
+
+
+
+###############################################################################
+# Server Adapter ###############################################################
+###############################################################################
+
+
+class ServerAdapter(object):
+    quiet = False
+    def __init__(self, host='127.0.0.1', port=8080, **config):
+        self.options = config
+        self.host = host
+        self.port = int(port)
+
+    def run(self, handler): # pragma: no cover
+        pass
+
+    def __repr__(self):
+        args = ', '.join(['%s=%s'%(k,repr(v)) for k, v in self.options.items()])
+        return "%s(%s)" % (self.__class__.__name__, args)
+
+
+class CGIServer(ServerAdapter):
+    quiet = True
+    def run(self, handler): # pragma: no cover
+        from wsgiref.handlers import CGIHandler
+        def fixed_environ(environ, start_response):
+            environ.setdefault('PATH_INFO', '')
+            return handler(environ, start_response)
+        CGIHandler().run(fixed_environ)
+
+
+class FlupFCGIServer(ServerAdapter):
+    def run(self, handler): # pragma: no cover
+        import flup.server.fcgi
+        self.options.setdefault('bindAddress', (self.host, self.port))
+        flup.server.fcgi.WSGIServer(handler, **self.options).run()
+
+
+class WSGIRefServer(ServerAdapter):
+    def run(self, handler): # pragma: no cover
+        from wsgiref.simple_server import make_server, WSGIRequestHandler
+        if self.quiet:
+            class QuietHandler(WSGIRequestHandler):
+                def log_request(*args, **kw): pass
+            self.options['handler_class'] = QuietHandler
+        srv = make_server(self.host, self.port, handler, **self.options)
+        srv.serve_forever()
+
+
+class CherryPyServer(ServerAdapter):
+    def run(self, handler): # pragma: no cover
+        from cherrypy import wsgiserver
+        server = wsgiserver.CherryPyWSGIServer((self.host, self.port), handler)
+        try:
+            server.start()
+        finally:
+            server.stop()
+
+
+class WaitressServer(ServerAdapter):
+    def run(self, handler):
+        from waitress import serve
+        serve(handler, host=self.host, port=self.port)
+
+
+class PasteServer(ServerAdapter):
+    def run(self, handler): # pragma: no cover
+        from paste import httpserver
+        if not self.quiet:
+            from paste.translogger import TransLogger
+            handler = TransLogger(handler)
+        httpserver.serve(handler, host=self.host, port=str(self.port),
+                         **self.options)
+
+
+class MeinheldServer(ServerAdapter):
+    def run(self, handler):
+        from meinheld import server
+        server.listen((self.host, self.port))
+        server.run(handler)
+
+
+class FapwsServer(ServerAdapter):
+    """ Extremely fast webserver using libev. See http://www.fapws.org/ """
+    def run(self, handler): # pragma: no cover
+        import fapws._evwsgi as evwsgi
+        from fapws import base, config
+        port = self.port
+        if float(config.SERVER_IDENT[-2:]) > 0.4:
+            # fapws3 silently changed its API in 0.5
+            port = str(port)
+        evwsgi.start(self.host, port)
+        # fapws3 never releases the GIL. Complain upstream. I tried. No luck.
+        if 'BOTTLE_CHILD' in os.environ and not self.quiet:
+            _stderr("WARNING: Auto-reloading does not work with Fapws3.\n")
+            _stderr("         (Fapws3 breaks python thread support)\n")
+        evwsgi.set_base_module(base)
+        def app(environ, start_response):
+            environ['wsgi.multiprocess'] = False
+            return handler(environ, start_response)
+        evwsgi.wsgi_cb(('', app))
+        evwsgi.run()
+
+
+class TornadoServer(ServerAdapter):
+    """ The super hyped asynchronous server by facebook. Untested. """
+    def run(self, handler): # pragma: no cover
+        import tornado.wsgi, tornado.httpserver, tornado.ioloop
+        container = tornado.wsgi.WSGIContainer(handler)
+        server = tornado.httpserver.HTTPServer(container)
+        server.listen(port=self.port)
+        tornado.ioloop.IOLoop.instance().start()
+
+
+class AppEngineServer(ServerAdapter):
+    """ Adapter for Google App Engine. """
+    quiet = True
+    def run(self, handler):
+        from google.appengine.ext.webapp import util
+        # A main() function in the handler script enables 'App Caching'.
+        # Lets makes sure it is there. This _really_ improves performance.
+        module = sys.modules.get('__main__')
+        if module and not hasattr(module, 'main'):
+            module.main = lambda: util.run_wsgi_app(handler)
+        util.run_wsgi_app(handler)
+
+
+class TwistedServer(ServerAdapter):
+    """ Untested. """
+    def run(self, handler):
+        from twisted.web import server, wsgi
+        from twisted.python.threadpool import ThreadPool
+        from twisted.internet import reactor
+        thread_pool = ThreadPool()
+        thread_pool.start()
+        reactor.addSystemEventTrigger('after', 'shutdown', thread_pool.stop)
+        factory = server.Site(wsgi.WSGIResource(reactor, thread_pool, handler))
+        reactor.listenTCP(self.port, factory, interface=self.host)
+        reactor.run()
+
+
+class DieselServer(ServerAdapter):
+    """ Untested. """
+    def run(self, handler):
+        from diesel.protocols.wsgi import WSGIApplication
+        app = WSGIApplication(handler, port=self.port)
+        app.run()
+
+
+class GeventServer(ServerAdapter):
+    """ Untested. Options:
+
+        * `fast` (default: False) uses libevent's http server, but has some
+          issues: No streaming, no pipelining, no SSL.
+    """
+    def run(self, handler):
+        from gevent import wsgi, pywsgi, local
+        if not isinstance(_lctx, local.local):
+            msg = "Bottle requires gevent.monkey.patch_all() (before import)"
+            raise RuntimeError(msg)
+        if not self.options.get('fast'): wsgi = pywsgi
+        log = None if self.quiet else 'default'
+        wsgi.WSGIServer((self.host, self.port), handler, log=log).serve_forever()
+
+
+class GunicornServer(ServerAdapter):
+    """ Untested. See http://gunicorn.org/configure.html for options. """
+    def run(self, handler):
+        from gunicorn.app.base import Application
+
+        config = {'bind': "%s:%d" % (self.host, int(self.port))}
+        config.update(self.options)
+
+        class GunicornApplication(Application):
+            def init(self, parser, opts, args):
+                return config
+
+            def load(self):
+                return handler
+
+        GunicornApplication().run()
+
+
+class EventletServer(ServerAdapter):
+    """ Untested """
+    def run(self, handler):
+        from eventlet import wsgi, listen
+        try:
+            wsgi.server(listen((self.host, self.port)), handler,
+                        log_output=(not self.quiet))
+        except TypeError:
+            # Fallback, if we have old version of eventlet
+            wsgi.server(listen((self.host, self.port)), handler)
+
+
+class RocketServer(ServerAdapter):
+    """ Untested. """
+    def run(self, handler):
+        from rocket import Rocket
+        server = Rocket((self.host, self.port), 'wsgi', { 'wsgi_app' : handler })
+        server.start()
+
+
+class BjoernServer(ServerAdapter):
+    """ Fast server written in C: https://github.com/jonashaag/bjoern """
+    def run(self, handler):
+        from bjoern import run
+        run(handler, self.host, self.port)
+
+
+class AutoServer(ServerAdapter):
+    """ Untested. """
+    adapters = [WaitressServer, PasteServer, TwistedServer, CherryPyServer, WSGIRefServer]
+    def run(self, handler):
+        for sa in self.adapters:
+            try:
+                return sa(self.host, self.port, **self.options).run(handler)
+            except ImportError:
+                pass
+
+server_names = {
+    'cgi': CGIServer,
+    'flup': FlupFCGIServer,
+    'wsgiref': WSGIRefServer,
+    'waitress': WaitressServer,
+    'cherrypy': CherryPyServer,
+    'paste': PasteServer,
+    'fapws3': FapwsServer,
+    'tornado': TornadoServer,
+    'gae': AppEngineServer,
+    'twisted': TwistedServer,
+    'diesel': DieselServer,
+    'meinheld': MeinheldServer,
+    'gunicorn': GunicornServer,
+    'eventlet': EventletServer,
+    'gevent': GeventServer,
+    'rocket': RocketServer,
+    'bjoern' : BjoernServer,
+    'auto': AutoServer,
+}
+
+
+
+
+
+
+###############################################################################
+# Application Control ##########################################################
+###############################################################################
+
+
+def load(target, **namespace):
+    """ Import a module or fetch an object from a module.
+
+        * ``package.module`` returns `module` as a module object.
+        * ``pack.mod:name`` returns the module variable `name` from `pack.mod`.
+        * ``pack.mod:func()`` calls `pack.mod.func()` and returns the result.
+
+        The last form accepts not only function calls, but any type of
+        expression. Keyword arguments passed to this function are available as
+        local variables. Example: ``import_string('re:compile(x)', x='[a-z]')``
+    """
+    module, target = target.split(":", 1) if ':' in target else (target, None)
+    if module not in sys.modules: __import__(module)
+    if not target: return sys.modules[module]
+    if target.isalnum(): return getattr(sys.modules[module], target)
+    package_name = module.split('.')[0]
+    namespace[package_name] = sys.modules[package_name]
+    return eval('%s.%s' % (module, target), namespace)
+
+
+def load_app(target):
+    """ Load a bottle application from a module and make sure that the import
+        does not affect the current default application, but returns a separate
+        application object. See :func:`load` for the target parameter. """
+    global NORUN; NORUN, nr_old = True, NORUN
+    try:
+        tmp = default_app.push() # Create a new "default application"
+        rv = load(target) # Import the target module
+        return rv if callable(rv) else tmp
+    finally:
+        default_app.remove(tmp) # Remove the temporary added default application
+        NORUN = nr_old
+
+_debug = debug
+def run(app=None, server='wsgiref', host='127.0.0.1', port=8080,
+        interval=1, reloader=False, quiet=False, plugins=None,
+        debug=False, **kargs):
+    """ Start a server instance. This method blocks until the server terminates.
+
+        :param app: WSGI application or target string supported by
+               :func:`load_app`. (default: :func:`default_app`)
+        :param server: Server adapter to use. See :data:`server_names` keys
+               for valid names or pass a :class:`ServerAdapter` subclass.
+               (default: `wsgiref`)
+        :param host: Server address to bind to. Pass ``0.0.0.0`` to listens on
+               all interfaces including the external one. (default: 127.0.0.1)
+        :param port: Server port to bind to. Values below 1024 require root
+               privileges. (default: 8080)
+        :param reloader: Start auto-reloading server? (default: False)
+        :param interval: Auto-reloader interval in seconds (default: 1)
+        :param quiet: Suppress output to stdout and stderr? (default: False)
+        :param options: Options passed to the server adapter.
+     """
+    if NORUN: return
+    if reloader and not os.environ.get('BOTTLE_CHILD'):
+        try:
+            lockfile = None
+            fd, lockfile = tempfile.mkstemp(prefix='bottle.', suffix='.lock')
+            os.close(fd) # We only need this file to exist. We never write to it
+            while os.path.exists(lockfile):
+                args = [sys.executable] + sys.argv
+                environ = os.environ.copy()
+                environ['BOTTLE_CHILD'] = 'true'
+                environ['BOTTLE_LOCKFILE'] = lockfile
+                p = subprocess.Popen(args, env=environ)
+                while p.poll() is None: # Busy wait...
+                    os.utime(lockfile, None) # I am alive!
+                    time.sleep(interval)
+                if p.poll() != 3:
+                    if os.path.exists(lockfile): os.unlink(lockfile)
+                    sys.exit(p.poll())
+        except KeyboardInterrupt:
+            pass
+        finally:
+            if os.path.exists(lockfile):
+                os.unlink(lockfile)
+        return
+
+    try:
+        _debug(debug)
+        app = app or default_app()
+        if isinstance(app, basestring):
+            app = load_app(app)
+        if not callable(app):
+            raise ValueError("Application is not callable: %r" % app)
+
+        for plugin in plugins or []:
+            app.install(plugin)
+
+        if server in server_names:
+            server = server_names.get(server)
+        if isinstance(server, basestring):
+            server = load(server)
+        if isinstance(server, type):
+            server = server(host=host, port=port, **kargs)
+        if not isinstance(server, ServerAdapter):
+            raise ValueError("Unknown or unsupported server: %r" % server)
+
+        server.quiet = server.quiet or quiet
+        if not server.quiet:
+            _stderr("Bottle v%s server starting up (using %s)...\n" % (__version__, repr(server)))
+            _stderr("Listening on http://%s:%d/\n" % (server.host, server.port))
+            _stderr("Hit Ctrl-C to quit.\n\n")
+
+        if reloader:
+            lockfile = os.environ.get('BOTTLE_LOCKFILE')
+            bgcheck = FileCheckerThread(lockfile, interval)
+            with bgcheck:
+                server.run(app)
+            if bgcheck.status == 'reload':
+                sys.exit(3)
+        else:
+            server.run(app)
+    except KeyboardInterrupt:
+        pass
+    except (SystemExit, MemoryError):
+        raise
+    except:
+        if not reloader: raise
+        if not getattr(server, 'quiet', quiet):
+            print_exc()
+        time.sleep(interval)
+        sys.exit(3)
+
+
+
+class FileCheckerThread(threading.Thread):
+    ''' Interrupt main-thread as soon as a changed module file is detected,
+        the lockfile gets deleted or gets to old. '''
+
+    def __init__(self, lockfile, interval):
+        threading.Thread.__init__(self)
+        self.lockfile, self.interval = lockfile, interval
+        #: Is one of 'reload', 'error' or 'exit'
+        self.status = None
+
+    def run(self):
+        exists = os.path.exists
+        mtime = lambda path: os.stat(path).st_mtime
+        files = dict()
+
+        for module in list(sys.modules.values()):
+            path = getattr(module, '__file__', '')
+            if path[-4:] in ('.pyo', '.pyc'): path = path[:-1]
+            if path and exists(path): files[path] = mtime(path)
+
+        while not self.status:
+            if not exists(self.lockfile)\
+            or mtime(self.lockfile) < time.time() - self.interval - 5:
+                self.status = 'error'
+                thread.interrupt_main()
+            for path, lmtime in list(files.items()):
+                if not exists(path) or mtime(path) > lmtime:
+                    self.status = 'reload'
+                    thread.interrupt_main()
+                    break
+            time.sleep(self.interval)
+
+    def __enter__(self):
+        self.start()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        if not self.status: self.status = 'exit' # silent exit
+        self.join()
+        return exc_type is not None and issubclass(exc_type, KeyboardInterrupt)
+
+
+
+
+
+###############################################################################
+# Template Adapters ############################################################
+###############################################################################
+
+
+class TemplateError(HTTPError):
+    def __init__(self, message):
+        HTTPError.__init__(self, 500, message)
+
+
+class BaseTemplate(object):
+    """ Base class and minimal API for template adapters """
+    extensions = ['tpl','html','thtml','stpl']
+    settings = {} #used in prepare()
+    defaults = {} #used in render()
+
+    def __init__(self, source=None, name=None, lookup=[], encoding='utf8', **settings):
+        """ Create a new template.
+        If the source parameter (str or buffer) is missing, the name argument
+        is used to guess a template filename. Subclasses can assume that
+        self.source and/or self.filename are set. Both are strings.
+        The lookup, encoding and settings parameters are stored as instance
+        variables.
+        The lookup parameter stores a list containing directory paths.
+        The encoding parameter should be used to decode byte strings or files.
+        The settings parameter contains a dict for engine-specific settings.
+        """
+        self.name = name
+        self.source = source.read() if hasattr(source, 'read') else source
+        self.filename = source.filename if hasattr(source, 'filename') else None
+        self.lookup = [os.path.abspath(x) for x in lookup]
+        self.encoding = encoding
+        self.settings = self.settings.copy() # Copy from class variable
+        self.settings.update(settings) # Apply
+        if not self.source and self.name:
+            self.filename = self.search(self.name, self.lookup)
+            if not self.filename:
+                raise TemplateError('Template %s not found.' % repr(name))
+        if not self.source and not self.filename:
+            raise TemplateError('No template specified.')
+        self.prepare(**self.settings)
+
+    @classmethod
+    def search(cls, name, lookup=[]):
+        """ Search name in all directories specified in lookup.
+        First without, then with common extensions. Return first hit. """
+        if not lookup:
+            depr('The template lookup path list should not be empty.')
+            lookup = ['.']
+
+        if os.path.isabs(name) and os.path.isfile(name):
+            depr('Absolute template path names are deprecated.')
+            return os.path.abspath(name)
+
+        for spath in lookup:
+            spath = os.path.abspath(spath) + os.sep
+            fname = os.path.abspath(os.path.join(spath, name))
+            if not fname.startswith(spath): continue
+            if os.path.isfile(fname): return fname
+            for ext in cls.extensions:
+                if os.path.isfile('%s.%s' % (fname, ext)):
+                    return '%s.%s' % (fname, ext)
+
+    @classmethod
+    def global_config(cls, key, *args):
+        ''' This reads or sets the global settings stored in class.settings. '''
+        if args:
+            cls.settings = cls.settings.copy() # Make settings local to class
+            cls.settings[key] = args[0]
+        else:
+            return cls.settings[key]
+
+    def prepare(self, **options):
+        """ Run preparations (parsing, caching, ...).
+        It should be possible to call this again to refresh a template or to
+        update settings.
+        """
+        raise NotImplementedError
+
+    def render(self, *args, **kwargs):
+        """ Render the template with the specified local variables and return
+        a single byte or unicode string. If it is a byte string, the encoding
+        must match self.encoding. This method must be thread-safe!
+        Local variables may be provided in dictionaries (*args)
+        or directly, as keywords (**kwargs).
+        """
+        raise NotImplementedError
+
+
+class MakoTemplate(BaseTemplate):
+    def prepare(self, **options):
+        from mako.template import Template
+        from mako.lookup import TemplateLookup
+        options.update({'input_encoding':self.encoding})
+        options.setdefault('format_exceptions', bool(DEBUG))
+        lookup = TemplateLookup(directories=self.lookup, **options)
+        if self.source:
+            self.tpl = Template(self.source, lookup=lookup, **options)
+        else:
+            self.tpl = Template(uri=self.name, filename=self.filename, lookup=lookup, **options)
+
+    def render(self, *args, **kwargs):
+        for dictarg in args: kwargs.update(dictarg)
+        _defaults = self.defaults.copy()
+        _defaults.update(kwargs)
+        return self.tpl.render(**_defaults)
+
+
+class CheetahTemplate(BaseTemplate):
+    def prepare(self, **options):
+        from Cheetah.Template import Template
+        self.context = threading.local()
+        self.context.vars = {}
+        options['searchList'] = [self.context.vars]
+        if self.source:
+            self.tpl = Template(source=self.source, **options)
+        else:
+            self.tpl = Template(file=self.filename, **options)
+
+    def render(self, *args, **kwargs):
+        for dictarg in args: kwargs.update(dictarg)
+        self.context.vars.update(self.defaults)
+        self.context.vars.update(kwargs)
+        out = str(self.tpl)
+        self.context.vars.clear()
+        return out
+
+
+class Jinja2Template(BaseTemplate):
+    def prepare(self, filters=None, tests=None, **kwargs):
+        from jinja2 import Environment, FunctionLoader
+        if 'prefix' in kwargs: # TODO: to be removed after a while
+            raise RuntimeError('The keyword argument `prefix` has been removed. '
+                'Use the full jinja2 environment name line_statement_prefix instead.')
+        self.env = Environment(loader=FunctionLoader(self.loader), **kwargs)
+        if filters: self.env.filters.update(filters)
+        if tests: self.env.tests.update(tests)
+        if self.source:
+            self.tpl = self.env.from_string(self.source)
+        else:
+            self.tpl = self.env.get_template(self.filename)
+
+    def render(self, *args, **kwargs):
+        for dictarg in args: kwargs.update(dictarg)
+        _defaults = self.defaults.copy()
+        _defaults.update(kwargs)
+        return self.tpl.render(**_defaults)
+
+    def loader(self, name):
+        fname = self.search(name, self.lookup)
+        if not fname: return
+        with open(fname, "rb") as f:
+            return f.read().decode(self.encoding)
+
+
+class SimpleTALTemplate(BaseTemplate):
+    ''' Deprecated, do not use. '''
+    def prepare(self, **options):
+        depr('The SimpleTAL template handler is deprecated'\
+             ' and will be removed in 0.12')
+        from simpletal import simpleTAL
+        if self.source:
+            self.tpl = simpleTAL.compileHTMLTemplate(self.source)
+        else:
+            with open(self.filename, 'rb') as fp:
+                self.tpl = simpleTAL.compileHTMLTemplate(tonat(fp.read()))
+
+    def render(self, *args, **kwargs):
+        from simpletal import simpleTALES
+        for dictarg in args: kwargs.update(dictarg)
+        context = simpleTALES.Context()
+        for k,v in self.defaults.items():
+            context.addGlobal(k, v)
+        for k,v in kwargs.items():
+            context.addGlobal(k, v)
+        output = StringIO()
+        self.tpl.expand(context, output)
+        return output.getvalue()
+
+
+class SimpleTemplate(BaseTemplate):
+    blocks = ('if', 'elif', 'else', 'try', 'except', 'finally', 'for', 'while',
+              'with', 'def', 'class')
+    dedent_blocks = ('elif', 'else', 'except', 'finally')
+
+    @lazy_attribute
+    def re_pytokens(cls):
+        ''' This matches comments and all kinds of quoted strings but does
+            NOT match comments (#...) within quoted strings. (trust me) '''
+        return re.compile(r'''
+            (''(?!')|""(?!")|'{6}|"{6}    # Empty strings (all 4 types)
+             |'(?:[^\\']|\\.)+?'          # Single quotes (')
+             |"(?:[^\\"]|\\.)+?"          # Double quotes (")
+             |'{3}(?:[^\\]|\\.|\n)+?'{3}  # Triple-quoted strings (')
+             |"{3}(?:[^\\]|\\.|\n)+?"{3}  # Triple-quoted strings (")
+             |\#.*                        # Comments
+            )''', re.VERBOSE)
+
+    def prepare(self, escape_func=html_escape, noescape=False, **kwargs):
+        self.cache = {}
+        enc = self.encoding
+        self._str = lambda x: touni(x, enc)
+        self._escape = lambda x: escape_func(touni(x, enc))
+        if noescape:
+            self._str, self._escape = self._escape, self._str
+
+    @classmethod
+    def split_comment(cls, code):
+        """ Removes comments (#...) from python code. """
+        if '#' not in code: return code
+        #: Remove comments only (leave quoted strings as they are)
+        subf = lambda m: '' if m.group(0)[0]=='#' else m.group(0)
+        return re.sub(cls.re_pytokens, subf, code)
+
+    @cached_property
+    def co(self):
+        return compile(self.code, self.filename or '<string>', 'exec')
+
+    @cached_property
+    def code(self):
+        stack = [] # Current Code indentation
+        lineno = 0 # Current line of code
+        ptrbuffer = [] # Buffer for printable strings and token tuple instances
+        codebuffer = [] # Buffer for generated python code
+        multiline = dedent = oneline = False
+        template = self.source or open(self.filename, 'rb').read()
+
+        def yield_tokens(line):
+            for i, part in enumerate(re.split(r'\{\{(.*?)\}\}', line)):
+                if i % 2:
+                    if part.startswith('!'): yield 'RAW', part[1:]
+                    else: yield 'CMD', part
+                else: yield 'TXT', part
+
+        def flush(): # Flush the ptrbuffer
+            if not ptrbuffer: return
+            cline = ''
+            for line in ptrbuffer:
+                for token, value in line:
+                    if token == 'TXT': cline += repr(value)
+                    elif token == 'RAW': cline += '_str(%s)' % value
+                    elif token == 'CMD': cline += '_escape(%s)' % value
+                    cline +=  ', '
+                cline = cline[:-2] + '\\\n'
+            cline = cline[:-2]
+            if cline[:-1].endswith('\\\\\\\\\\n'):
+                cline = cline[:-7] + cline[-1] # 'nobr\\\\\n' --> 'nobr'
+            cline = '_printlist([' + cline + '])'
+            del ptrbuffer[:] # Do this before calling code() again
+            code(cline)
+
+        def code(stmt):
+            for line in stmt.splitlines():
+                codebuffer.append('  ' * len(stack) + line.strip())
+
+        for line in template.splitlines(True):
+            lineno += 1
+            line = touni(line, self.encoding)
+            sline = line.lstrip()
+            if lineno <= 2:
+                m = re.match(r"%\s*#.*coding[:=]\s*([-\w.]+)", sline)
+                if m: self.encoding = m.group(1)
+                if m: line = line.replace('coding','coding (removed)')
+            if sline and sline[0] == '%' and sline[:2] != '%%':
+                line = line.split('%',1)[1].lstrip() # Full line following the %
+                cline = self.split_comment(line).strip()
+                cmd = re.split(r'[^a-zA-Z0-9_]', cline)[0]
+                flush() # You are actually reading this? Good luck, it's a mess :)
+                if cmd in self.blocks or multiline:
+                    cmd = multiline or cmd
+                    dedent = cmd in self.dedent_blocks # "else:"
+                    if dedent and not oneline and not multiline:
+                        cmd = stack.pop()
+                    code(line)
+                    oneline = not cline.endswith(':') # "if 1: pass"
+                    multiline = cmd if cline.endswith('\\') else False
+                    if not oneline and not multiline:
+                        stack.append(cmd)
+                elif cmd == 'end' and stack:
+                    code('#end(%s) %s' % (stack.pop(), line.strip()[3:]))
+                elif cmd == 'include':
+                    p = cline.split(None, 2)[1:]
+                    if len(p) == 2:
+                        code("_=_include(%s, _stdout, %s)" % (repr(p[0]), p[1]))
+                    elif p:
+                        code("_=_include(%s, _stdout)" % repr(p[0]))
+                    else: # Empty %include -> reverse of %rebase
+                        code("_printlist(_base)")
+                elif cmd == 'rebase':
+                    p = cline.split(None, 2)[1:]
+                    if len(p) == 2:
+                        code("globals()['_rebase']=(%s, dict(%s))" % (repr(p[0]), p[1]))
+                    elif p:
+                        code("globals()['_rebase']=(%s, {})" % repr(p[0]))
+                else:
+                    code(line)
+            else: # Line starting with text (not '%') or '%%' (escaped)
+                if line.strip().startswith('%%'):
+                    line = line.replace('%%', '%', 1)
+                ptrbuffer.append(yield_tokens(line))
+        flush()
+        return '\n'.join(codebuffer) + '\n'
+
+    def subtemplate(self, _name, _stdout, *args, **kwargs):
+        for dictarg in args: kwargs.update(dictarg)
+        if _name not in self.cache:
+            self.cache[_name] = self.__class__(name=_name, lookup=self.lookup)
+        return self.cache[_name].execute(_stdout, kwargs)
+
+    def execute(self, _stdout, *args, **kwargs):
+        for dictarg in args: kwargs.update(dictarg)
+        env = self.defaults.copy()
+        env.update({'_stdout': _stdout, '_printlist': _stdout.extend,
+               '_include': self.subtemplate, '_str': self._str,
+               '_escape': self._escape, 'get': env.get,
+               'setdefault': env.setdefault, 'defined': env.__contains__})
+        env.update(kwargs)
+        eval(self.co, env)
+        if '_rebase' in env:
+            subtpl, rargs = env['_rebase']
+            rargs['_base'] = _stdout[:] #copy stdout
+            del _stdout[:] # clear stdout
+            return self.subtemplate(subtpl,_stdout,rargs)
+        return env
+
+    def render(self, *args, **kwargs):
+        """ Render the template using keyword arguments as local variables. """
+        for dictarg in args: kwargs.update(dictarg)
+        stdout = []
+        self.execute(stdout, kwargs)
+        return ''.join(stdout)
+
+
+def template(*args, **kwargs):
+    '''
+    Get a rendered template as a string iterator.
+    You can use a name, a filename or a template string as first parameter.
+    Template rendering arguments can be passed as dictionaries
+    or directly (as keyword arguments).
+    '''
+    tpl = args[0] if args else None
+    adapter = kwargs.pop('template_adapter', SimpleTemplate)
+    lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)
+    tplid = (id(lookup), tpl)
+    if tplid not in TEMPLATES or DEBUG:
+        settings = kwargs.pop('template_settings', {})
+        if isinstance(tpl, adapter):
+            TEMPLATES[tplid] = tpl
+            if settings: TEMPLATES[tplid].prepare(**settings)
+        elif "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl:
+            TEMPLATES[tplid] = adapter(source=tpl, lookup=lookup, **settings)
+        else:
+            TEMPLATES[tplid] = adapter(name=tpl, lookup=lookup, **settings)
+    if not TEMPLATES[tplid]:
+        abort(500, 'Template (%s) not found' % tpl)
+    for dictarg in args[1:]: kwargs.update(dictarg)
+    return TEMPLATES[tplid].render(kwargs)
+
+mako_template = functools.partial(template, template_adapter=MakoTemplate)
+cheetah_template = functools.partial(template, template_adapter=CheetahTemplate)
+jinja2_template = functools.partial(template, template_adapter=Jinja2Template)
+simpletal_template = functools.partial(template, template_adapter=SimpleTALTemplate)
+
+
+def view(tpl_name, **defaults):
+    ''' Decorator: renders a template for a handler.
+        The handler can control its behavior like that:
+
+          - return a dict of template vars to fill out the template
+          - return something other than a dict and the view decorator will not
+            process the template, but return the handler result as is.
+            This includes returning a HTTPResponse(dict) to get,
+            for instance, JSON with autojson or other castfilters.
+    '''
+    def decorator(func):
+        @functools.wraps(func)
+        def wrapper(*args, **kwargs):
+            result = func(*args, **kwargs)
+            if isinstance(result, (dict, DictMixin)):
+                tplvars = defaults.copy()
+                tplvars.update(result)
+                return template(tpl_name, **tplvars)
+            return result
+        return wrapper
+    return decorator
+
+mako_view = functools.partial(view, template_adapter=MakoTemplate)
+cheetah_view = functools.partial(view, template_adapter=CheetahTemplate)
+jinja2_view = functools.partial(view, template_adapter=Jinja2Template)
+simpletal_view = functools.partial(view, template_adapter=SimpleTALTemplate)
+
+
+
+
+
+
+###############################################################################
+# Constants and Globals ########################################################
+###############################################################################
+
+
+TEMPLATE_PATH = ['./', './views/']
+TEMPLATES = {}
+DEBUG = False
+NORUN = False # If set, run() does nothing. Used by load_app()
+
+#: A dict to map HTTP status codes (e.g. 404) to phrases (e.g. 'Not Found')
+HTTP_CODES = httplib.responses
+HTTP_CODES[418] = "I'm a teapot" # RFC 2324
+HTTP_CODES[428] = "Precondition Required"
+HTTP_CODES[429] = "Too Many Requests"
+HTTP_CODES[431] = "Request Header Fields Too Large"
+HTTP_CODES[511] = "Network Authentication Required"
+_HTTP_STATUS_LINES = dict((k, '%d %s'%(k,v)) for (k,v) in HTTP_CODES.items())
+
+#: The default template used for error pages. Override with @error()
+ERROR_PAGE_TEMPLATE = """
+%%try:
+    %%from %s import DEBUG, HTTP_CODES, request, touni
+    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+    <html>
+        <head>
+            <title>Error: {{e.status}}</title>
+            <style type="text/css">
+              html {background-color: #eee; font-family: sans;}
+              body {background-color: #fff; border: 1px solid #ddd;
+                    padding: 15px; margin: 15px;}
+              pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
+            </style>
+        </head>
+        <body>
+            <h1>Error: {{e.status}}</h1>
+            <p>Sorry, the requested URL <tt>{{repr(request.url)}}</tt>
+               caused an error:</p>
+            <pre>{{e.body}}</pre>
+            %%if DEBUG and e.exception:
+              <h2>Exception:</h2>
+              <pre>{{repr(e.exception)}}</pre>
+            %%end
+            %%if DEBUG and e.traceback:
+              <h2>Traceback:</h2>
+              <pre>{{e.traceback}}</pre>
+            %%end
+        </body>
+    </html>
+%%except ImportError:
+    <b>ImportError:</b> Could not generate the error page. Please add bottle to
+    the import path.
+%%end
+""" % __name__
+
+#: A thread-safe instance of :class:`LocalRequest`. If accessed from within a
+#: request callback, this instance always refers to the *current* request
+#: (even on a multithreaded server).
+request = LocalRequest()
+
+#: A thread-safe instance of :class:`LocalResponse`. It is used to change the
+#: HTTP response for the *current* request.
+response = LocalResponse()
+
+#: A thread-safe namespace. Not used by Bottle.
+local = threading.local()
+
+# Initialize app stack (create first empty Bottle app)
+# BC: 0.6.4 and needed for run()
+app = default_app = AppStack()
+app.push()
+
+#: A virtual package that redirects import statements.
+#: Example: ``import bottle.ext.sqlite`` actually imports `bottle_sqlite`.
+ext = _ImportRedirect('bottle.ext' if __name__ == '__main__' else __name__+".ext", 'bottle_%s').module
+
+if __name__ == '__main__':
+    opt, args, parser = _cmd_options, _cmd_args, _cmd_parser
+    if opt.version:
+        _stdout('Bottle %s\n'%__version__)
+        sys.exit(0)
+    if not args:
+        parser.print_help()
+        _stderr('\nError: No application specified.\n')
+        sys.exit(1)
+
+    sys.path.insert(0, '.')
+    sys.modules.setdefault('bottle', sys.modules['__main__'])
+
+    host, port = (opt.bind or 'localhost'), 8080
+    if ':' in host:
+        host, port = host.rsplit(':', 1)
+
+    run(args[0], host=host, port=port, server=opt.server,
+        reloader=opt.reload, plugins=opt.plugin, debug=opt.debug)
+
+
+
+
+# THE END
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/run_tweetbook_demo.py b/asterix-examples/src/main/resources/tweetbook-demo/run_tweetbook_demo.py
new file mode 100755
index 0000000..5307192
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/run_tweetbook_demo.py
@@ -0,0 +1,73 @@
+import tweetbook_bootstrap
+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('/')
+def jsontest():
+    return template('tweetbook')
+
+@route('/static/<filename:path>')
+def send_static(filename):
+    return static_file(filename, root='static')
+
+# API Helpers
+def build_response(endpoint, data):
+    api_endpoint = "http://localhost:19002/" + endpoint
+
+    try:
+        # 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
+
+        # 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')
+def run_asterix_query():
+    return (build_response("query", dict(request.query)))
+    
+@route('/query/status')
+def run_asterix_query_status():
+    return (build_response("query/status", dict(request.query)))
+
+@route('/query/result')
+def run_asterix_query_result():
+    return (build_response("query/result", dict(request.query)))
+
+@route('/ddl')
+def run_asterix_ddl():
+    return (build_response("ddl", dict(request.query)))
+
+@route('/update')
+def run_asterix_update():
+    return (build_response("update", dict(request.query)))
+    
+res = tweetbook_bootstrap.bootstrap()
+run(host='localhost', port=8080, debug=True)
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/data/query.txt b/asterix-examples/src/main/resources/tweetbook-demo/static/data/query.txt
new file mode 100755
index 0000000..f577c52
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/data/query.txt
@@ -0,0 +1,47 @@
+drop dataverse twitter if exists;
+create dataverse twitter;
+use dataverse twitter;
+
+create type TweetbookEntry as open {
+    tweetid: string,
+    comment-text: string                
+}
+
+create type TwitterUserType as open {
+    screen-name: string,
+    lang: string,
+    friends_count: int32,
+    statuses_count: int32,
+    name: string,
+    followers_count: int32
+}
+
+create type TweetMessageType as closed {
+    tweetid: string,
+    user: TwitterUserType,
+    sender-location: point?,
+    send-time: datetime,
+    referred-topics: {{ string }},
+    message-text: string
+}
+
+create dataset TweetMessages(TweetMessageType)
+primary key tweetid;
+
+create dataset TweetMessagesShifted(TweetMessageType)
+primary key tweetid;
+
+load dataset TweetMessages using localfs
+(("path"="localhost://FULL_PATH/twm.adm"),("format"="adm"));
+
+insert into dataset TweetMessagesShifted
+(
+for $t in dataset TweetMessages return {
+    "tweetid" : $t.tweetid,
+    "user" : $t.user,
+    "sender-location" : create-point(get-x($t.sender-location), -1*get-y($t.sender-location)),
+    "send-time" : $t.send-time,
+    "referred-topics": $t.referred-topics,
+    "message-text": $t.message-text
+}
+);
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/data/twm.adm b/asterix-examples/src/main/resources/tweetbook-demo/static/data/twm.adm
new file mode 100755
index 0000000..8fb899f
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/data/twm.adm
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial1.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial1.png
new file mode 100644
index 0000000..c59b133
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial1.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial2.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial2.png
new file mode 100644
index 0000000..33a7ed7
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial2.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial3.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial3.png
new file mode 100644
index 0000000..4a207af
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial3.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial4.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial4.png
new file mode 100644
index 0000000..72a1bc7
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/Tutorial4.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/finalasterixlogo.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/finalasterixlogo.png
new file mode 100755
index 0000000..8ace2c8
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/finalasterixlogo.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings-white.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings-white.png
new file mode 100755
index 0000000..3bf6484
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings-white.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings.png
new file mode 100755
index 0000000..a996999
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/glyphicons-halflings.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/hyrax.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/hyrax.png
new file mode 100755
index 0000000..645b7c1
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/hyrax.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/markers.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/markers.png
new file mode 100755
index 0000000..b983f9f
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/markers.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile2.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile2.png
new file mode 100755
index 0000000..42b567b
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile2.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile_green2.png b/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile_green2.png
new file mode 100755
index 0000000..d590461
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/img/mobile_green2.png
Binary files differ
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/js/asterix-sdk-stable.js b/asterix-examples/src/main/resources/tweetbook-demo/static/js/asterix-sdk-stable.js
new file mode 100755
index 0000000..3e5aa8d
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/js/asterix-sdk-stable.js
@@ -0,0 +1,1045 @@
+/**
+* Asterix SDK - Beta Version
+* @author Eugenia Gabrielov <genia.likes.science@gmail.com>
+* 
+* This is a Javascript helper file for generating AQL queries for AsterixDB (https://code.google.com/p/asterixdb/) 
+*/
+
+/**
+* AsterixDBConnection
+* 
+* This is a handler for connections to a local AsterixDB REST API Endpoint. 
+* This initialization takes as input a configuraiton object, and initializes
+* same basic functionality. 
+*/
+function AsterixDBConnection(configuration) {
+    // Initialize AsterixDBConnection properties
+    this._properties = {};
+    
+    // Set dataverse as null for now, this needs to be set by the user.
+    this._properties["dataverse"] = "";
+    
+    // By default, we will wait for calls to the REST API to complete. The query method
+    // sends a different setting when executed asynchronously. Calls that do not specify a mode
+    // will be executed synchronously.
+    this._properties["mode"] = "synchronous";
+    
+    // These are the default error behaviors for Asterix and ajax errors, respectively. 
+    // They can be overridden by calling initializing your AsterixDBConnection like so:
+    // adb = new AsterixDBConnection({
+    //                                  "error" : function(data) {
+    //                                              // override here...
+    //                                  });
+    // and similarly for ajax_error, just pass in the configuration as a json object.
+    this._properties["error"] = function(data) {
+        alert("Asterix REST API Error:\n" + data["error-code"][0] + "\n" + data["error-code"][1]);
+    };
+    
+    this._properties["ajax_error"] = function(message) {
+        alert("[Ajax Error]\n" + message);
+    };
+
+    // This is the default path to the local Asterix REST API. Can be overwritten for remote configurations
+    // or for demo setup purposes (such as with a proxy handler with Python or PHP.
+    this._properties["endpoint_root"] = "http://localhost:19002/";
+    
+    // If we have passed in a configuration, we will update the internal properties
+    // using that configuration. You can do things such as include a new endpoint_root,
+    // a new error function, a new dataverse, etc. You can even store extra info.
+    //
+    // NOTE Long-term, this should have more strict limits.
+    var configuration = configuration || {};
+
+    for (var key in configuration) {
+        this._properties[key] = configuration[key];
+    }
+    
+    return this;
+}
+
+
+/**
+* dataverse
+*
+* Sets dataverse for execution for the AsterixDBConnection.
+*/
+AsterixDBConnection.prototype.dataverse = function(dataverseName) {
+    this._properties["dataverse"] = dataverseName;
+    
+    return this;
+};
+
+
+/**
+* query (http://asterix.ics.uci.edu/documentation/api.html#QueryApi)
+* 
+* @param statements, statements of an AQL query
+* @param successFn, a function to execute if this query is run successfully
+* @param mode, a string either "synchronous" or "asynchronous", depending on preferred
+*               execution mode. 
+*/
+AsterixDBConnection.prototype.query = function(statements, successFn, mode) {
+ 
+    if ( typeof statements === 'string') {
+        statements = [ statements ];
+    }
+    
+    var m = typeof mode ? mode : "synchronous";
+    
+    // DEBUG
+    //alert(statements.join("\n"));
+     
+    var query = "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n");
+    
+    this._api(
+        {
+            "query" : query,
+            "mode"  : m
+        },
+        successFn, 
+        "query"
+    );
+
+    return this;
+};
+
+/**
+* query_status (http://asterix.ics.uci.edu/documentation/api.html#QueryStatusApi)
+* 
+* @param handle, a json object of the form {"handle" : handleObject}, where
+*                   the handle object is an opaque handle previously returned
+*                   from an asynchronous call.
+* @param successFn, a function to call on successful execution of this API call.
+*/
+AsterixDBConnection.prototype.query_status = function(handle, successFn) {
+    this._api(
+        handle,
+        successFn,
+        "query/status"
+    );
+
+    return this;
+};
+
+
+/**
+* query_result (http://asterix.ics.uci.edu/documentation/api.html#AsynchronousResultApi)
+* 
+* handle, a json object of the form {"handle" : handleObject}, where
+*           the handle object is an opaque handle previously returned
+*           from an asynchronous call.
+* successFn, a function to call on successful execution of this API call.
+*/
+AsterixDBConnection.prototype.query_result = function(handle, successFn) {
+    this._api(
+        handle,
+        successFn,
+        "query/result"
+    ); 
+
+    return this;
+};
+
+
+/**
+* ddl (http://asterix.ics.uci.edu/documentation/api.html#DdlApi)
+* 
+* @param statements, statements to run through ddl api
+* @param successFn, a function to execute if they are successful
+*/
+AsterixDBConnection.prototype.ddl = function(statements, successFn) {
+    if ( typeof statements === 'string') {
+        statements = [ statements ];
+    }
+    
+    this._api(
+        {
+            "ddl" :  "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
+        },
+        successFn,
+        "ddl"
+    );
+}
+
+
+/**
+* update (http://asterix.ics.uci.edu/documentation/api.html#UpdateApi)
+*
+* @param statements, statement(s) for an update API call
+* @param successFn, a function to run if this is executed successfully.
+* 
+* This is an AsterixDBConnection handler for the update API. It passes statements provided
+* to the internal API endpoint handler.
+*/
+AsterixDBConnection.prototype.update = function(statements, successFn) {
+    if ( typeof statements === 'string') {
+        statements = [ statements ];
+    }
+    
+    // DEBUG
+    // alert(statements.join("\n"));
+    
+    this._api(
+        {
+            "statements" : "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
+        },
+        successFn,
+        "update"
+    );
+}
+
+
+/**
+* meta
+* @param statements, a string or a list of strings representing an Asterix query object
+* @param successFn, a function to execute if call succeeds
+*
+* Queries without a dataverse. This is a work-around for an Asterix REST API behavior
+* that sometiems throws an error. This is handy for Asterix Metadata queries.
+*/
+AsterixDBConnection.prototype.meta = function(statements, successFn) {
+
+    if ( typeof statements === 'string') {
+        statements = [ statements ];
+    }
+    
+    var query = statements.join("\n");
+    
+    this._api(
+        {
+            "query" : query,
+            "mode"  : "synchronous"
+        },
+        successFn, 
+        "query"
+    );
+
+    return this;
+}
+
+
+/**
+* _api
+*
+* @param json, the data to be passed with the request
+* @param onSuccess, the success function to be run if this succeeds
+* @param endpoint, a string representing one of the Asterix API endpoints 
+* 
+* Documentation of endpoints is here:
+* http://asterix.ics.uci.edu/documentation/api.html
+*
+* This is treated as an internal method for making the actual call to the API.
+*/
+AsterixDBConnection.prototype._api = function(json, onSuccess, endpoint) {
+
+    // The success function is called if the response is successful and returns data,
+    // or is just OK.
+    var success_fn = onSuccess;
+    
+    // This is the error function. Called if something breaks either on the Asterix side
+    // or in the Ajax call.
+    var error_fn = this._properties["error"];
+    var ajax_error_fn = this._properties["ajax_error"];
+    
+    // This is the target endpoint from the REST api, called as a string.
+    var endpoint_url = this._properties["endpoint_root"] + endpoint;    
+
+    // This SDK does not rely on jQuery, but utilizes its Ajax capabilities when present.
+    if (window.jQuery) {
+        $.ajax({
+        
+            // The Asterix API does not accept post requests.
+            type        : 'GET',
+            
+            // This is the endpoint url provided by combining the default
+            // or reconfigured endpoint root along with the appropriate api endpoint
+            // such as "query" or "update".
+            url         : endpoint_url,
+            
+            // This is the data in the format specified on the API documentation.
+            data        : json,
+            
+            // We send out the json datatype to make sure our data is parsed correctly. 
+            dataType    : "json",
+            
+            // The success option calls a function on success, which in this case means
+            // something was returned from the API. However, this does not mean the call succeeded
+            // on the REST API side, it just means we got something back. This also contains the
+            // error return codes, which need to be handled before we call th success function.
+            success     : function(data) {
+
+                // Check Asterix Response for errors
+                // See http://asterix.ics.uci.edu/documentation/api.html#ErrorCodes
+                if (data["error-code"]) { 
+                    error_fn(data);
+                    
+                // Otherwise, run our provided success function
+                } else {
+                    success_fn(data);
+                }
+            },
+            
+            // This is the function that gets called if there is an ajax-related (non-Asterix)
+            // error. Network errors, empty response bodies, syntax errors, and a number of others
+            // can pop up. 
+            error       : function(data) {
+
+                // Some of the Asterix API endpoints return empty responses on success.
+                // However, the ajax function treats these as errors while reporting a
+                // 200 OK code with no payload. So we will check for that, otherwise 
+                // alert of an error. An example response is as follows:
+                // {"readyState":4,"responseText":"","status":200,"statusText":"OK"}
+                if (data["status"] == 200 && data["responseText"] == "") {
+                    success_fn(data);
+                } else {
+                    alert("[Ajax Error]\n" + JSON.stringify(data));
+                }
+            }
+        });
+        
+    } else {
+    
+        // NOTE: This section is in progress; currently API requires jQuery.
+    
+        // First, we encode the parameters of the query to create a new url.
+        api_endpoint = endpoint_url + "?" + Object.keys(json).map(function(k) {
+            return encodeURIComponent(k) + '=' + encodeURIComponent(json[k])
+        }).join('&');
+       
+        // Now, create an XMLHttp object to carry our request. We will call the
+        // UI callback function on ready.
+        var xmlhttp;
+        xmlhttp = new XMLHttpRequest();
+        xmlhttp.open("GET", endpoint_url, true);
+        xmlhttp.send(null);
+        
+        xmlhttp.onreadystatechange = function(){
+            if (xmlhttp.readyState == 4) {
+                if (xmlhttp.status === 200) {
+                    alert(xmlhttp.responseText);
+                    //success.call(null, xmlHttp.responseText);
+                } else {
+                    //error.call(null, xmlHttp.responseText);
+                }
+            } else {
+                // Still processing
+            }
+        };
+    }
+    return this;
+};
+
+// Asterix Expressions - Base
+function AExpression () {
+
+    this._properties = {};
+    this._success = function() {};
+
+    if (arguments.length == 1) {
+        this._properties["value"] = arguments[0];    
+    }
+
+    return this;
+}
+
+
+AExpression.prototype.bind = function(options) {
+    var options = options || {};
+
+    if (options.hasOwnProperty("success")) {
+        this._success = options["success"];
+    }
+
+    if (options.hasOwnProperty("return")) {
+        this._properties["return"] = " return " + options["return"].val();
+    }
+};
+
+
+AExpression.prototype.run = function(successFn) {
+    return this;
+};
+
+
+AExpression.prototype.val = function() { 
+
+    var value = "";
+
+    // If there is a dataverse defined, provide it.
+    if (this._properties.hasOwnProperty("dataverse")) {
+        value += "use dataverse " + this._properties["dataverse"] + ";\n";
+    };
+
+    if (this._properties.hasOwnProperty("value")) {
+        value += this._properties["value"].toString();
+    }
+
+    return value;
+};
+
+
+// @param expressionValue [String]
+AExpression.prototype.set = function(expressionValue) {
+    this._properties["value"] = expressionValue; 
+    return this;
+};
+
+
+// AQL Statements
+// SingleStatement ::= DataverseDeclaration
+//                  | FunctionDeclaration
+//                  | CreateStatement
+//                  | DropStatement
+//                  | LoadStatement
+//                  | SetStatement
+//                  | InsertStatement
+//                  | DeleteStatement
+//                  | Query
+function InsertStatement(quantifiedName, query) {
+    AExpression.call(this);
+    
+    var innerQuery = "";
+    if (query instanceof AExpression) {
+        innerQuery = query.val();
+    } else if (typeof query == "object" && Object.getPrototypeOf( query ) === Object.prototype ) {
+        
+        var insertStatements = [];
+        for (querykey in query) {
+            if (query[querykey] instanceof AExpression) {
+                insertStatements.push('"' + querykey + '" : ' + query[querykey].val());
+            } else if (typeof query[querykey] == "string") {
+                insertStatements.push('"' + querykey + '" : ' + query[querykey]);
+            } else {
+                insertStatements.push('"' + querykey + '" : ' + query[querykey].toString());
+            }
+        }
+        
+        innerQuery = "{" + insertStatements.join(', ') + "}";
+    }
+    
+    var statement = "insert into dataset " + quantifiedName + "(" + innerQuery + ");";
+    
+    AExpression.prototype.set.call(this, statement);
+
+    return this;
+}
+
+InsertStatement.prototype = Object.create(AExpression.prototype);
+InsertStatement.prototype.constructor = InsertStatement;
+
+
+// Delete Statement
+// DeleteStatement ::= "delete" Variable "from" "dataset" QualifiedName ( "where" Expression )?
+function DeleteStatement (variable, quantifiedName, whereExpression) {
+    AExpression.call(this);
+    
+    var statement = "delete " + variable + " from dataset " + quantifiedName;
+    
+    if (whereExpression instanceof AExpression) {
+        statement += " where " + whereExpression.val();
+    }
+    
+    AExpression.prototype.set.call(this, statement);
+    
+    return this;
+}
+
+DeleteStatement.prototype = Object.create(AExpression.prototype);
+DeleteStatement.prototype.constructor = DeleteStatement;
+
+// SetStatement
+//
+// Grammar
+// "set" Identifier StringLiteral
+function SetStatement (identifier, stringLiteral) {
+    AExpression.call(this);
+
+    var statement = "set " + identifier + ' "' + stringLiteral + '";';
+
+    AExpression.prototype.set.call(this, statement);
+
+    return this;
+}
+
+SetStatement.prototype = Object.create(AExpression.prototype);
+SetStatement.prototype.constructor = SetStatement;
+
+
+// Other Expressions
+
+// FunctionExpression
+// Parent: AsterixExpression
+// 
+// @param   options [Various], 
+// @key     function [String], a function to be applid to the expression
+// @key     expression [AsterixExpression or AQLClause] an AsterixExpression/Clause to which the fn will be applied
+function FunctionExpression() {
+    
+    // Initialize superclass
+    AExpression.call(this);
+    
+    this._properties["function"] = "";
+    this._properties["expressions"] = [];
+
+    // Check for fn/expression input
+    if (arguments.length >= 2 && typeof arguments[0] == "string") {
+        
+        this._properties["function"] = arguments[0];
+
+        for (i = 1; i < arguments.length; i++) {
+            if (arguments[i] instanceof AExpression || arguments[i] instanceof AQLClause) {
+                this._properties["expressions"].push(arguments[i]);
+            } else {
+                this._properties["expressions"].push(new AExpression(arguments[i]));
+            }
+        }
+    } 
+
+    // Return FunctionCallExpression object
+    return this;
+}
+
+
+FunctionExpression.prototype = Object.create(AExpression.prototype);
+FunctionExpression.prototype.constructor = FunctionExpression;
+   
+
+FunctionExpression.prototype.val = function () {
+    var fn_args = [];
+    for (var i = 0; i < this._properties["expressions"].length; i++) {
+        fn_args.push(this._properties["expressions"][i].val());
+    }
+
+    return this._properties["function"] + "(" + fn_args.join(", ") + ")";
+};
+
+
+// FLWOGRExpression
+//
+// FLWOGRExpression ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
+function FLWOGRExpression (options) {
+    // Initialize superclass
+    AExpression.call(this);
+
+    this._properties["clauses"] = [];
+    this._properties["minSize"] = 0;
+
+    // Bind options and return
+    this.bind(options);
+    return this;
+}
+
+
+FLWOGRExpression.prototype = Object.create(AExpression.prototype);
+FLWOGRExpression.prototype.constructor = FLWOGRExpression;
+
+
+FLWOGRExpression.prototype.bind = function(options) {
+    AExpression.prototype.bind.call(this, options);
+
+    var options = options || {};
+
+    if (options instanceof SetStatement) {
+         this._properties["clauses"].push(options);
+         this._properties["minSize"] += 1;
+    }
+
+    if (this._properties["clauses"].length <= this._properties["minSize"]) {
+        // Needs to start with for or let clause
+        if (options instanceof ForClause || options instanceof LetClause) {
+            this._properties["clauses"].push(options);
+        }
+    } else {
+        if (options instanceof AQLClause) {
+            this._properties["clauses"].push(options);
+        }
+    }
+
+    return this;
+};
+
+
+FLWOGRExpression.prototype.val = function() {
+    var value = AExpression.prototype.val.call(this);
+
+    var clauseValues = [];
+    for (var c in this._properties["clauses"]) {
+        clauseValues.push(this._properties["clauses"][c].val());
+    }
+
+    return value + clauseValues.join("\n");// + ";";
+};
+
+// Pretty Expression Shorthand
+
+FLWOGRExpression.prototype.ReturnClause = function(expression) {
+    return this.bind(new ReturnClause(expression));
+};
+
+FLWOGRExpression.prototype.ForClause = function() {
+    return this.bind(new ForClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.LetClause = function() {
+    return this.bind(new LetClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.WhereClause = function() {
+    return this.bind(new WhereClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.and = function() {
+    var args = Array.prototype.slice.call(arguments);
+    args.push(true);
+    return this.bind(new WhereClause().and(args));
+};
+
+FLWOGRExpression.prototype.or = function() {
+    var args = Array.prototype.slice.call(arguments);
+    args.push(true);
+    return this.bind(new WhereClause().or(args));
+};
+
+FLWOGRExpression.prototype.OrderbyClause = function() {
+    return this.bind(new OrderbyClause(Array.prototype.slice.call(arguments)));
+};
+
+
+FLWOGRExpression.prototype.GroupClause = function() {
+    return this.bind(new GroupClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.LimitClause = function() {
+    return this.bind(new LimitClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.DistinctClause = function() {
+    return this.bind(new DistinctClause(Array.prototype.slice.call(arguments)));
+};
+
+FLWOGRExpression.prototype.AQLClause = function() {
+    return this.bind(new AQLClause(Array.prototype.slice.call(arguments)));
+};
+
+
+// AQLClause
+//
+// Base Clause  ::= ForClause | LetClause | WhereClause | OrderbyClause | GroupClause | LimitClause | DistinctClause
+function AQLClause() {
+    this._properties = {};
+    this._properties["clause"] = "";
+    this._properties["stack"] = [];
+    if (typeof arguments[0] == 'string') {
+        this._properties["clause"] = arguments[0];
+    }
+    return this;
+}
+
+AQLClause.prototype.val = function() {
+    var value = this._properties["clause"];
+ 
+    return value;
+};
+
+AQLClause.prototype.bind = function(options) {
+
+    if (options instanceof AQLClause) {
+        this._properties["clause"] += " " + options.val();
+    }
+
+    return this;
+};
+
+AQLClause.prototype.set = function(value) {
+    this._properties["clause"] = value;
+    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
+function ForClause(for_variable, at_variable, expression) {
+    AQLClause.call(this);
+  
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+  
+    this._properties["clause"] = "for " + parameters[0];
+    
+    if (parameters.length == 3) {
+        this._properties["clause"] += " at " + parameters[1];
+        this._properties["clause"] += " in " + parameters[2].val();
+    } else if (parameters.length == 2) {
+        this._properties["clause"] += " in " + parameters[1].val();
+    }
+    
+    return this;
+}
+
+ForClause.prototype = Object.create(AQLClause.prototype);
+ForClause.prototype.constructor = ForClause;
+
+
+// LetClause
+//
+// Grammar:
+// LetClause      ::= "let" Variable ":=" Expression
+//
+// @param let_variable [String]
+// @param expression [AExpression]
+function LetClause(let_variable, expression) {
+    AQLClause.call(this);
+    
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+    
+    this._properties["clause"] = "let " + parameters[0] + " := ";
+    this._properties["clause"] += parameters[1].val();
+    
+    return this; 
+}
+
+LetClause.prototype = Object.create(AQLClause.prototype);
+LetClause.prototype.constructor = LetClause;
+
+
+// ReturnClause
+//
+// Grammar:
+// return [AQLExpression]
+function ReturnClause(expression) {
+    AQLClause.call(this);
+
+    this._properties["clause"] = "return ";
+    
+    if (expression instanceof AExpression || expression instanceof AQLClause) {
+        this._properties["clause"] += expression.val();
+    
+    } else if ( typeof expression == "object" && Object.getPrototypeOf( expression ) === Object.prototype ) {
+        
+        this._properties["clause"] += "\n{\n";
+        var returnStatements = [];
+        for (returnValue in expression) {
+           
+            if (expression[returnValue] instanceof AExpression) { 
+                returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue].val());            
+            } else if (typeof expression[returnValue] == "string") {          
+                returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue]);   
+            }
+        }
+        this._properties["clause"] += returnStatements.join(",\n");
+        this._properties["clause"] += "\n}";  
+    
+    } else {
+        this._properties["clause"] += new AQLClause().set(expression).val();
+    }
+
+    return this;
+}
+
+
+ReturnClause.prototype = Object.create(AQLClause.prototype);
+ReturnClause.prototype.constructor = ReturnClause;
+
+
+// WhereClause
+//
+// Grammar: 
+// ::= "where" Expression
+// 
+// @param expression [BooleanExpression], pushes this expression onto the stack
+function WhereClause(expression) {
+    AQLClause.call(this);
+    
+    this._properties["stack"] = [];
+
+    if (expression instanceof Array) {
+        this.bind(expression[0]);
+    } else {
+        this.bind(expression);
+    }
+    
+    return this;
+}
+
+
+WhereClause.prototype = Object.create(AQLClause.prototype);
+WhereClause.prototype.constructor = WhereClause;
+
+
+WhereClause.prototype.bind = function(expression) {
+    if (expression instanceof AExpression) {
+        this._properties["stack"].push(expression);
+    }
+    return this;
+};
+
+
+WhereClause.prototype.val = function() {
+    var value = "";  
+    
+    if (this._properties["stack"].length == 0) {
+        return value;
+    }
+
+    var count = this._properties["stack"].length - 1;
+    while (count >= 0) {
+        value += this._properties["stack"][count].val() + " ";
+        count -= 1;
+    }
+    
+    return "where " + value;
+};
+
+
+WhereClause.prototype.and = function() {
+    
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+    
+    var andClauses = [];  
+    for (var expression in parameters) {
+        
+        if (parameters[expression] instanceof AExpression) {
+            andClauses.push(parameters[expression].val());
+        }
+    }
+    
+    if (andClauses.length > 0) {
+        this._properties["stack"].push(new AExpression().set(andClauses.join(" and ")));
+    }
+    
+    return this;
+};
+
+
+WhereClause.prototype.or = function() {
+
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+
+    var orClauses = [];  
+    for (var expression in parameters) {
+        
+        if (parameters[expression] instanceof AExpression) {
+            orClauses.push(parameters[expression].val());
+        }
+    }
+    
+    if (andClauses.length > 0) {
+        this._properties["stack"].push(new AExpression().set(orClauses.join(" and ")));
+    }
+    
+    return this;
+};
+
+// LimitClause
+// Grammar:
+// LimitClause    ::= "limit" Expression ( "offset" Expression )?
+// 
+// @param   limitExpression [REQUIRED, AQLExpression]
+// @param   offsetExpression [OPTIONAL, AQLExpression]
+function LimitClause(limitExpression, offsetExpression) {
+
+    AQLClause.call(this);
+    
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+  
+    // limitExpression required
+    this._properties["clause"] = "limit " + parameters[0].val();
+
+    // Optional: Offset
+    if (parameters.length == 2) {
+        this._properties["clause"] += " offset " + parameters[1].val();
+    }
+
+    return this;
+}
+
+LimitClause.prototype = Object.create(AQLClause.prototype);
+LimitClause.prototype.constructor = LimitClause;
+
+
+// OrderbyClause
+//
+// Grammar:
+// OrderbyClause  ::= "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )*
+//
+// @params AQLExpressions and asc/desc strings, in any quantity. At least one required. 
+function OrderbyClause() {
+    
+    AQLClause.call(this);
+
+    // At least one argument expression is required, and first should be expression
+    if (arguments.length == 0) {
+        this._properties["clause"] = null;
+        return this;    
+    }
+    
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+
+    var expc = 0;
+    var expressions = [];    
+
+    while (expc < parameters.length) {
+      
+        var expression = "";
+
+        if (parameters[expc] instanceof AExpression) {
+            expression += parameters[expc].val();
+        }
+
+        var next = expc + 1;
+        if (next < parameters.length && (parameters[next] == "asc" || parameters[next] == "desc")) {
+            expc++;
+            expression += " " + parameters[expc];
+        }
+        
+        expressions.push(expression);
+      
+        expc++;
+    }
+
+    this._properties["clause"] = "order by " + expressions.join(", ");
+    return this;
+}
+
+OrderbyClause.prototype = Object.create(AQLClause.prototype);
+OrderbyClause.prototype.constructor = OrderbyClause;
+
+
+// GroupClause
+//
+// Grammar:
+// GroupClause    ::= "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
+function GroupClause() {
+    AQLClause.call(this);
+
+    if (arguments.length == 0) {
+        this._properties["clause"] = null;
+        return this;    
+    } 
+    
+    var parameters = [];
+    if (arguments[0] instanceof Array) {
+        parameters = arguments[0];
+    } else {
+        parameters = arguments;
+    }
+
+    var expc = 0;
+    var expressions = [];
+    var variableRefs = [];
+    var isDecor = false;
+    
+    while (expc < parameters.length) {
+
+        if (parameters[expc] instanceof AExpression) {
+
+            isDecor = false;
+            expressions.push(parameters[expc].val());
+
+        } else if (typeof parameters[expc] == "string") {       
+            
+            // Special keywords, decor & with
+            if (parameters[expc] == "decor") {
+                isDecor = true;
+            } else if (parameters[expc] == "with") {
+                isDecor = false;
+                expc++;
+                while (expc < parameters.length) {
+                    variableRefs.push(parameters[expc]);
+                    expc++;
+                }
+            
+            // Variables and variable refs
+            } else {
+                
+                var nextc = expc + 1;
+                var expression = "";
+            
+                if (isDecor) {
+                    expression += "decor "; 
+                    isDecor = false;
+                }
+
+                expression += parameters[expc] + " := " + parameters[nextc].val();
+                expressions.push(expression);
+                expc++;
+            }
+        }
+
+        expc++;
+    }
+
+    this._properties["clause"] = "group by " + expressions.join(", ") + " with " + variableRefs.join(", ");
+    return this;
+}
+
+GroupClause.prototype = Object.create(AQLClause.prototype);
+GroupClause.prototype.constructor = GroupClause;
+
+
+// Quantified Expression
+// 
+// Grammar
+// QuantifiedExpression ::= ( ( "some" ) | ( "every" ) ) Variable "in" Expression ( "," Variable "in" Expression )* "satisfies" Expression
+// 
+// @param String some/every
+// @param [AExpression]
+// @param [Aexpression] satisfiesExpression
+function QuantifiedExpression (keyword, expressions, satisfiesExpression) {
+    AExpression.call(this);
+
+    var expression = keyword + " ";
+    var varsInExpressions = [];
+
+    for (var varInExpression in expressions) {
+        varsInExpressions.push(varInExpression + " in " + expressions[varInExpression].val()); 
+    } 
+    expression += varsInExpressions.join(", ") + " satisfies " + satisfiesExpression.val();
+    
+    AExpression.prototype.set.call(this, expression);
+
+    return this;
+}
+
+QuantifiedExpression.prototype = Object.create(AExpression.prototype);
+QuantifiedExpression.prototype.constructor = QuantifiedExpression;
+
+QuantifiedExpression.prototype.val = function() {
+    var value = AExpression.prototype.val.call(this);
+    return "(" + value + ")";    
+};
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/js/bootstrap.min.js b/asterix-examples/src/main/resources/tweetbook-demo/static/js/bootstrap.min.js
new file mode 100644
index 0000000..f0b7d68
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/js/bootstrap.min.js
@@ -0,0 +1,11 @@
+/*!
+ * Bootstrap v3.0.0
+ *
+ * Copyright 2013 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
++function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed.bs.alert").remove()}var c=a(this),d=c.attr("data-target");d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));var e=a(d);b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close.bs.alert"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.one(a.support.transition.end,f).emulateTransitionEnd(150):f()};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]');if(a.length){var b=this.$element.find("input").prop("checked",!this.$element.hasClass("active")).trigger("change");b.prop("type")==="radio"&&a.find(".active").removeClass("active")}this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f=typeof c=="object"&&c;e||d.data("bs.button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.pause=="hover"&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();if(b>this.$items.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){if(this.sliding)return;return this.slide("next")},b.prototype.prev=function(){if(this.sliding)return;return this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(e.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")}));if(a.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(j);if(j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)}).emulateTransitionEnd(600)}else{this.$element.trigger(j);if(j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),typeof c=="object"&&c),g=typeof c=="string"?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),typeof c=="number"?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),c.data()),g=c.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=c.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(window.jQuery),+function(a){function e(){a(b).remove(),a(c).each(function(b){var c=f(a(this));if(!c.hasClass("open"))return;c.trigger(b=a.Event("hide.bs.dropdown"));if(b.isDefaultPrevented())return;c.removeClass("open").trigger("hidden.bs.dropdown")})}function f(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}"use strict";var b=".dropdown-backdrop",c="[data-toggle=dropdown]",d=function(b){var c=a(b).on("click.bs.dropdown",this.toggle)};d.prototype.toggle=function(b){var c=a(this);if(c.is(".disabled, :disabled"))return;var d=f(c),g=d.hasClass("open");e();if(!g){"ontouchstart"in document.documentElement&&!d.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",e),d.trigger(b=a.Event("show.bs.dropdown"));if(b.isDefaultPrevented())return;d.toggleClass("open").trigger("shown.bs.dropdown"),c.focus()}return!1},d.prototype.keydown=function(b){if(!/(38|40|27)/.test(b.keyCode))return;var d=a(this);b.preventDefault(),b.stopPropagation();if(d.is(".disabled, :disabled"))return;var e=f(d),g=e.hasClass("open");if(!g||g&&b.keyCode==27)return b.which==27&&e.find(c).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",e);if(!h.length)return;var i=h.index(h.filter(":focus"));b.keyCode==38&&i>0&&i--,b.keyCode==40&&i<h.length-1&&i++,~i||(i=0),h.eq(i).focus()};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),e=c.data("dropdown");e||c.data("dropdown",e=new d(this)),typeof b=="string"&&e[b].call(c)})},a.fn.dropdown.Constructor=d,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",e).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",c,d.prototype.toggle).on("keydown.bs.dropdown.data-api",c+", [role=menu]",d.prototype.keydown)}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.load(this.options.remote)};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d);if(this.isShown||d.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.$element.on("click.dismiss.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show(),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)})},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal()},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]!==a.target&&!this.$element.has(a.target).length&&this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){a.which==27&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(document.body),this.$element.on("click.dismiss.modal",a.proxy(function(a){if(a.target!==a.currentTarget)return;this.options.backdrop=="static"?this.$element[0].focus.call(this.$element[0]):this.hide.call(this)},this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!b)return;e?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),typeof c=="object"&&c);f||e.data("bs.modal",f=new b(this,g)),typeof c=="string"?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(window.jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);var e=this.options.trigger.split(" ");for(var f=e.length;f--;){var g=e[f];if(g=="click")this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if(g!="manual"){var h=g=="hover"?"mouseenter":"focus",i=g=="hover"?"mouseleave":"blur";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);clearTimeout(c.timeout),c.hoverState="in";if(!c.options.delay||!c.options.delay.show)return c.show();c.timeout=setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show)},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);clearTimeout(c.timeout),c.hoverState="out";if(!c.options.delay||!c.options.delay.hide)return c.hide();c.timeout=setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide)},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);if(b.isDefaultPrevented())return;var c=this.tip();this.setContent(),this.options.animation&&c.addClass("fade");var d=typeof this.options.placement=="function"?this.options.placement.call(this,c[0],this.$element[0]):this.options.placement,e=/\s?auto?\s?/i,f=e.test(d);f&&(d=d.replace(e,"")||"top"),c.detach().css({top:0,left:0,display:"block"}).addClass(d),this.options.container?c.appendTo(this.options.container):c.insertAfter(this.$element);var g=this.getPosition(),h=c[0].offsetWidth,i=c[0].offsetHeight;if(f){var j=this.$element.parent(),k=d,l=document.documentElement.scrollTop||document.body.scrollTop,m=this.options.container=="body"?window.innerWidth:j.outerWidth(),n=this.options.container=="body"?window.innerHeight:j.outerHeight(),o=this.options.container=="body"?0:j.offset().left;d=d=="bottom"&&g.top+g.height+i-l>n?"top":d=="top"&&g.top-l-i<0?"bottom":d=="right"&&g.right+h>m?"left":d=="left"&&g.left-h<o?"right":d,c.removeClass(k).addClass(d)}var p=this.getCalculatedOffset(d,g,h,i);this.applyPlacement(p,d),this.$element.trigger("shown.bs."+this.type)}},b.prototype.applyPlacement=function(a,b){var c,d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),a.top=a.top+g,a.left=a.left+h,d.offset(a).addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;b=="top"&&j!=f&&(c=!0,a.top=a.top+f-j);if(/bottom|top/.test(b)){var k=0;a.left<0&&(k=a.left*-2,a.left=0,d.offset(a),i=d[0].offsetWidth,j=d[0].offsetHeight),this.replaceArrow(k-e+i,i,"left")}else this.replaceArrow(j-f,j,"top");c&&d.offset(a)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function e(){b.hoverState!="in"&&c.detach()}var b=this,c=this.tip(),d=a.Event("hide.bs."+this.type);this.$element.trigger(d);if(d.isDefaultPrevented())return;return c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?c.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),this.$element.trigger("hidden.bs."+this.type),this},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},typeof b.getBoundingClientRect=="function"?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return a=="bottom"?{top:b.top+b.height,left:b.left+b.width/2-c/2}:a=="top"?{top:b.top-d,left:b.left+b.width/2-c/2}:a=="left"?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f=typeof c=="object"&&c;e||d.data("bs.tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(window.jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||(typeof b.content=="function"?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f=typeof c=="object"&&c;e||d.data("bs.popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(window.jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target");d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));if(b.parent("li").hasClass("active"))return;var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});b.trigger(f);if(f.isDefaultPrevented())return;var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})},b.prototype.activate=function(b,c,d){function g(){e.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),f?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var e=c.find("> .active"),f=d&&a.support.transition&&e.hasClass("fade");f?e.one(a.support.transition.end,g).emulateTransitionEnd(150):g(),e.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),typeof c=="string"&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;typeof f!="object"&&(h=g=f),typeof g=="function"&&(g=f.top()),typeof h=="function"&&(h=f.bottom());var i=this.unpin!=null&&d+this.unpin<=e.top?!1:h!=null&&e.top+this.$element.height()>=c-h?"bottom":g!=null&&d<=g?"top":!1;if(this.affixed===i)return;this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin=i=="bottom"?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),i=="bottom"&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()})};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f=typeof c=="object"&&c;e||d.data("bs.affix",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(this.transitioning||this.$element.hasClass("in"))return;var b=a.Event("show.bs.collapse");this.$element.trigger(b);if(b.isDefaultPrevented())return;var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])},b.prototype.hide=function(){if(this.transitioning||!this.$element.hasClass("in"))return;var b=a.Event("hide.bs.collapse");this.$element.trigger(b);if(b.isDefaultPrevented())return;var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};if(!a.support.transition)return d.call(this);this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350)},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),typeof c=="object"&&c);e||d.data("bs.collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":c.data(),i=c.attr("data-parent"),j=i&&a(i);if(!g||!g.transitioning)j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(c).addClass("collapsed"),c[f.hasClass("in")?"addClass":"removeClass"]("collapsed");f.collapse(h)})}(window.jQuery),+function(a){function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}"use strict",b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this,d=this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a=this.$scrollElement.scrollTop()+this.options.offset,b=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,c=b-this.$scrollElement.height(),d=this.offsets,e=this.targets,f=this.activeTarget,g;if(a>=c)return f!=(g=e.last()[0])&&this.activate(g);for(g=d.length;g--;)f!=e[g]&&a>=d[g]&&(!d[g+1]||a<=d[g+1])&&this.activate(e[g])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f=typeof c=="object"&&c;e||d.data("bs.scrollspy",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),+function(a){function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(a.style[c]!==undefined)return{end:b[c]}}"use strict",a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(window.jQuery)
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/js/geostats.js b/asterix-examples/src/main/resources/tweetbook-demo/static/js/geostats.js
new file mode 100755
index 0000000..adc8e1d
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/js/geostats.js
@@ -0,0 +1,679 @@
+/**
+* geostats() is a tiny and standalone javascript library for classification 
+* Project page - https://github.com/simogeo/geostats
+* Copyright (c) 2011 Simon Georget, http://valums.com
+* Licensed under the MIT license
+*/
+
+var _t = function(str) {
+	return str;
+};
+
+var inArray = function(needle, haystack) {
+    for(var i = 0; i < haystack.length; i++) {
+        if(haystack[i] == needle) return true;
+    }
+    return false;
+};
+
+var geostats = function(a) {
+
+	this.separator = ' - ';
+	this.legendSeparator = this.separator;
+	this.method  = '';
+	this.roundlength 	= 2; // Number of decimals, round values
+	this.is_uniqueValues = false;
+	
+	this.bounds  = Array();
+	this.ranges  = Array();
+	this.colors  = Array();
+	this.counter = Array();
+	
+	// statistics information
+	this.stat_sorted	= null;
+	this.stat_mean 		= null;
+	this.stat_median 	= null;
+	this.stat_sum 		= null;
+	this.stat_max 		= null;
+	this.stat_min 		= null;
+	this.stat_pop 		= null;
+	this.stat_variance	= null;
+	this.stat_stddev	= null;
+	this.stat_cov		= null;
+
+	
+	if(typeof a !== 'undefined' && a.length > 0) {
+		this.serie = a;
+	} else {
+		this.serie = Array();
+	};
+	
+	/**
+	 * Set a new serie
+	 */
+	this.setSerie = function(a) {
+	
+		this.serie = Array() // init empty array to prevent bug when calling classification after another with less items (sample getQuantile(6) and getQuantile(4))
+		this.serie = a;
+		
+	};
+	
+	/**
+	 * Set colors
+	 */
+	this.setColors = function(colors) {
+		
+		this.colors = colors;
+		
+	};
+	
+	/**
+	 * Get feature count
+	 * With bounds array(0, 0.75, 1.5, 2.25, 3); 
+	 * should populate this.counter with 5 keys
+	 * and increment counters for each key
+	 */
+	this.doCount = function() {
+		
+		if (this._nodata())
+			return;
+		
+
+		var tmp = this.sorted();
+		// console.log(tmp.join(', '));
+
+		
+		// we init counter with 0 value
+		for(i = 0; i < this.bounds.length; i++) {
+			this.counter[i]= 0;
+		}
+		
+		for(j=0; j < tmp.length; j++) {
+			
+			// get current class for value to increment the counter
+			var cclass = this.getClass(tmp[j]);
+			this.counter[cclass]++;
+
+		}
+
+	};
+	
+	/**
+	 * Transform a bounds array to a range array the following array : array(0,
+	 * 0.75, 1.5, 2.25, 3); becomes : array('0-0.75', '0.75-1.5', '1.5-2.25',
+	 * '2.25-3');
+	 */
+	this.setRanges = function() {
+	
+		this.ranges = Array(); // init empty array to prevent bug when calling classification after another with less items (sample getQuantile(6) and getQuantile(4))
+		
+		for (i = 0; i < (this.bounds.length - 1); i++) {
+			this.ranges[i] = this.bounds[i] + this.separator + this.bounds[i + 1];
+		}
+	};
+
+	/** return min value */
+	this.min = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_min  == null) {
+			
+			this.stat_min = this.serie[0];
+			for (i = 0; i < this.pop(); i++) {
+				if (this.serie[i] < this.stat_min) {
+					this.stat_min = this.serie[i];
+				}
+			}
+			
+		}
+		
+		return this.stat_min;
+	};
+
+	/** return max value */
+	this.max = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_max  == null) {
+			
+			this.stat_max = this.serie[0];
+			for (i = 0; i < this.pop(); i++) {
+				if (this.serie[i] > this.stat_max) {
+					this.stat_max = this.serie[i];
+				}
+			}
+			
+		}
+		
+		return this.stat_max;
+	};
+
+	/** return sum value */
+	this.sum = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_sum  == null) {
+			
+			this.stat_sum = 0;
+			for (i = 0; i < this.pop(); i++) {
+				this.stat_sum += this.serie[i];
+			}
+			
+		}
+		
+		return this.stat_sum;
+	};
+
+	/** return population number */
+	this.pop = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_pop  == null) {
+			
+			this.stat_pop = this.serie.length;
+			
+		}
+		
+		return this.stat_pop;
+	};
+
+	/** return mean value */
+	this.mean = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_mean  == null) {
+			
+			this.stat_mean = this.sum() / this.pop();
+			
+		}
+		
+		return this.stat_mean;
+	};
+
+	/** return median value */
+	this.median = function() {
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_median  == null) {
+			
+			this.stat_median = 0;
+			var tmp = this.sorted();
+	
+			if (tmp.length % 2) {
+				this.stat_median = tmp[(Math.ceil(tmp.length / 2) - 1)];
+			} else {
+				this.stat_median = (tmp[(tmp.length / 2) - 1] + tmp[(tmp.length / 2)]) / 2;
+			}
+			
+		}
+		
+		return this.stat_median;
+	};
+
+	/** return variance value */
+	this.variance = function() {
+		
+		round = (typeof round === "undefined") ? true : false;
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_variance  == null) {
+
+			var tmp = 0;
+			for (var i = 0; i < this.pop(); i++) {
+				tmp += Math.pow( (this.serie[i] - this.mean()), 2 );
+			}
+
+			this.stat_variance =  tmp /	this.pop();
+			
+			if(round == true) {
+				this.stat_variance = Math.round(this.stat_variance * Math.pow(10,this.roundlength) )/ Math.pow(10,this.roundlength);
+			}
+			
+		}
+		
+		return this.stat_variance;
+	};
+	
+	/** return standard deviation value */
+	this.stddev = function(round) {
+		
+		round = (typeof round === "undefined") ? true : false;
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_stddev  == null) {
+			
+			this.stat_stddev = Math.sqrt(this.variance());
+			
+			if(round == true) {
+				this.stat_stddev = Math.round(this.stat_stddev * Math.pow(10,this.roundlength) )/ Math.pow(10,this.roundlength);
+			}
+			
+		}
+		
+		return this.stat_stddev;
+	};
+	
+	/** coefficient of variation - measure of dispersion */
+	this.cov = function(round) {
+		
+		round = (typeof round === "undefined") ? true : false;
+		
+		if (this._nodata())
+			return;
+		
+		if (this.stat_cov  == null) {
+			
+			this.stat_cov = this.stddev() / this.mean();
+			
+			if(round == true) {
+				this.stat_cov = Math.round(this.stat_cov * Math.pow(10,this.roundlength) )/ Math.pow(10,this.roundlength);
+			}
+			
+		}
+		
+		return this.stat_cov;
+	};
+	
+	/** data test */
+	this._nodata = function() {
+		if (this.serie.length == 0) {
+			
+			alert("Error. You should first enter a serie!");
+			return 1;
+		} else
+			return 0;
+		
+	};
+
+	/** return sorted values (as array) */
+	this.sorted = function() {
+		
+		if (this.stat_sorted  == null) {
+			
+			if(this.is_uniqueValues == false) {
+				this.stat_sorted = this.serie.sort(function(a, b) {
+					return a - b;
+				});
+			} else {
+				this.stat_sorted = this.serie.sort(function(a,b){
+					var nameA=a.toLowerCase(), nameB=b.toLowerCase()
+				    if(nameA < nameB) return -1;
+				    if(nameA > nameB) return 1;
+				    return 0;
+				})
+			}
+		}
+		
+		return this.stat_sorted;
+		
+	};
+
+	/** return all info */
+	this.info = function() {
+		
+		if (this._nodata())
+			return;
+		
+		var content = '';
+		content += _t('Population') + ' : ' + this.pop() + ' - [' + _t('Min')
+				+ ' : ' + this.min() + ' | ' + _t('Max') + ' : ' + this.max()
+				+ ']' + "\n";
+		content += _t('Mean') + ' : ' + this.mean() + ' - ' + _t('Median')	+ ' : ' + this.median() + "\n";
+		content += _t('Variance') + ' : ' + this.variance() + ' - ' + _t('Standard deviation')	+ ' : ' + this.stddev()  
+				+ ' - ' + _t('Coefficient of variation')	+ ' : ' + this.cov() + "\n";
+
+		return content;
+	};
+
+	/**
+	 * Equal intervals discretization Return an array with bounds : ie array(0,
+	 * 0.75, 1.5, 2.25, 3);
+	 */
+	this.getEqInterval = function(nbClass) {
+
+		if (this._nodata())
+			return;
+
+		this.method = _t('eq. intervals') + ' (' + nbClass + ' ' + _t('classes')
+				+ ')';
+
+		var a = Array();
+		var val = this.min();
+		var interval = (this.max() - this.min()) / nbClass;
+
+		for (i = 0; i <= nbClass; i++) {
+			a[i] = val;
+			val += interval;
+		}
+
+		this.bounds = a;
+		this.setRanges();
+		
+		return a;
+	};
+	
+
+	/**
+	 * Quantile discretization Return an array with bounds : ie array(0, 0.75,
+	 * 1.5, 2.25, 3);
+	 */
+	this.getQuantile = function(nbClass) {
+
+		if (this._nodata())
+			return;
+
+		this.method = _t('quantile') + ' (' + nbClass + ' ' + _t('classes') + ')';
+
+		var a = Array();
+		var tmp = this.sorted();
+
+		var classSize = Math.round(this.pop() / nbClass);
+		var step = classSize;
+		var i = 0;
+
+		// we set first value
+		a[0] = tmp[0];
+
+		for (i = 1; i < nbClass; i++) {
+			a[i] = tmp[step];
+			step += classSize;
+		}
+		// we set last value
+		a.push(tmp[tmp.length - 1]);
+		
+		this.bounds = a;
+		this.setRanges();
+		
+		return a;
+
+	};
+	
+	/**
+	 * Credits : Doug Curl (javascript) and Daniel J Lewis (python implementation)
+	 * http://www.arcgis.com/home/item.html?id=0b633ff2f40d412995b8be377211c47b
+	 * http://danieljlewis.org/2010/06/07/jenks-natural-breaks-algorithm-in-python/
+	 */
+	this.getJenks = function(nbClass) {
+	
+		if (this._nodata())
+			return;
+		
+		this.method = _t('Jenks') + ' (' + nbClass + ' ' + _t('classes') + ')';
+		
+		dataList = this.sorted();
+
+		// now iterate through the datalist:
+		// determine mat1 and mat2
+		// really not sure how these 2 different arrays are set - the code for
+		// each seems the same!
+		// but the effect are 2 different arrays: mat1 and mat2
+		var mat1 = []
+		for ( var x = 0, xl = dataList.length + 1; x < xl; x++) {
+			var temp = []
+			for ( var j = 0, jl = nbClass + 1; j < jl; j++) {
+				temp.push(0)
+			}
+			mat1.push(temp)
+		}
+
+		var mat2 = []
+		for ( var i = 0, il = dataList.length + 1; i < il; i++) {
+			var temp2 = []
+			for ( var c = 0, cl = nbClass + 1; c < cl; c++) {
+				temp2.push(0)
+			}
+			mat2.push(temp2)
+		}
+
+		// absolutely no idea what this does - best I can tell, it sets the 1st
+		// group in the
+		// mat1 and mat2 arrays to 1 and 0 respectively
+		for ( var y = 1, yl = nbClass + 1; y < yl; y++) {
+			mat1[0][y] = 1
+			mat2[0][y] = 0
+			for ( var t = 1, tl = dataList.length + 1; t < tl; t++) {
+				mat2[t][y] = Infinity
+			}
+			var v = 0.0
+		}
+
+		// and this part - I'm a little clueless on - but it works
+		// pretty sure it iterates across the entire dataset and compares each
+		// value to
+		// one another to and adjust the indices until you meet the rules:
+		// minimum deviation
+		// within a class and maximum separation between classes
+		for ( var l = 2, ll = dataList.length + 1; l < ll; l++) {
+			var s1 = 0.0
+			var s2 = 0.0
+			var w = 0.0
+			for ( var m = 1, ml = l + 1; m < ml; m++) {
+				var i3 = l - m + 1
+				var val = parseFloat(dataList[i3 - 1])
+				s2 += val * val
+				s1 += val
+				w += 1
+				v = s2 - (s1 * s1) / w
+				var i4 = i3 - 1
+				if (i4 != 0) {
+					for ( var p = 2, pl = nbClass + 1; p < pl; p++) {
+						if (mat2[l][p] >= (v + mat2[i4][p - 1])) {
+							mat1[l][p] = i3
+							mat2[l][p] = v + mat2[i4][p - 1]
+						}
+					}
+				}
+			}
+			mat1[l][1] = 1
+			mat2[l][1] = v
+		}
+
+		var k = dataList.length
+		var kclass = []
+
+		// fill the kclass (classification) array with zeros:
+		for (i = 0, il = nbClass + 1; i < il; i++) {
+			kclass.push(0)
+		}
+
+		// this is the last number in the array:
+		kclass[nbClass] = parseFloat(dataList[dataList.length - 1])
+		// this is the first number - can set to zero, but want to set to lowest
+		// to use for legend:
+		kclass[0] = parseFloat(dataList[0])
+		var countNum = nbClass
+		while (countNum >= 2) {
+			var id = parseInt((mat1[k][countNum]) - 2)
+			kclass[countNum - 1] = dataList[id]
+			k = parseInt((mat1[k][countNum] - 1))
+			// spits out the rank and value of the break values:
+			// console.log("id="+id,"rank = " + String(mat1[k][countNum]),"val =
+			// " + String(dataList[id]))
+			// count down:
+			countNum -= 1
+		}
+		// check to see if the 0 and 1 in the array are the same - if so, set 0
+		// to 0:
+		if (kclass[0] == kclass[1]) {
+			kclass[0] = 0
+		}
+		
+		this.bounds = kclass;
+		this.setRanges();
+
+		return kclass; //array of breaks
+	}
+	
+	
+	/**
+	 * Quantile discretization Return an array with bounds : ie array(0, 0.75,
+	 * 1.5, 2.25, 3);
+	 */
+	this.getUniqueValues = function() {
+
+		if (this._nodata())
+			return;
+
+		this.method = _t('unique values');
+		this.is_uniqueValues = true;
+		
+		var tmp = this.sorted(); // display in alphabetical order
+
+		var a = Array();
+
+		for (i = 0; i < this.pop(); i++) {
+			if(!inArray (tmp[i], a))
+				a.push(tmp[i]);
+		}
+		
+		this.bounds = a;
+		
+		return a;
+
+	};
+	
+	
+	/**
+	 * Return the class of a given value.
+	 * For example value : 6
+	 * and bounds array = (0, 4, 8, 12);
+	 * Return 2
+	 */
+	this.getClass = function(value) {
+
+		for(i = 0; i < this.bounds.length; i++) {
+			
+			
+			if(this.is_uniqueValues == true) {
+				if(value == this.bounds[i])
+					return i;
+			} else {
+				if(value <= this.bounds[i + 1]) {
+					return i;
+				}
+			}
+		}
+		
+		return _t("Unable to get value's class.");
+		
+	};
+
+	/**
+	 * Return the ranges array : array('0-0.75', '0.75-1.5', '1.5-2.25',
+	 * '2.25-3');
+	 */
+	this.getRanges = function() {
+		
+		return this.ranges;
+		
+	};
+
+	/**
+	 * Returns the number/index of this.ranges that value falls into
+	 */
+	this.getRangeNum = function(value) {
+		var bounds, i;
+
+		for (i = 0; i < this.ranges.length; i++) {
+			bounds = this.ranges[i].split(/ - /);
+			if (value <= parseFloat(bounds[1])) {
+				return i;
+			}
+		}
+	}
+	
+	/**
+	 * Return an html legend
+	 * 
+	 */
+	this.getHtmlLegend = function(colors, legend, counter, callback) {
+		
+		var cnt= '';
+		
+		if(colors != null) {
+			ccolors = colors;
+		}
+		else {
+			ccolors = this.colors;
+		}
+		
+		if(legend != null) {
+			lg = legend;
+		}
+		else {
+			lg =  'Legend';
+		}
+		
+		if(counter != null) {
+			this.doCount();
+			getcounter = true;
+		}
+		else {
+			getcounter = false;
+		}
+		
+		if(callback != null) {
+			fn = callback;
+		}
+		else {
+			fn = function(o) {return o;};
+		}
+		
+		
+		if(ccolors.length < this.ranges.length) {
+			alert(_t('The number of colors should fit the number of ranges. Exit!'));
+			return;
+		}
+		
+		var content  = '<div class="geostats-legend"><div class="geostats-legend-title">' + _t(lg) + '</div>';
+		
+		if(this.is_uniqueValues == false) {
+			for (i = 0; i < (this.ranges.length); i++) {
+				if(getcounter===true) {
+					cnt = ' <span class="geostats-legend-counter">(' + this.counter[i] + ')</span>';
+				}
+	
+				// check if it has separator or not
+				if(this.ranges[i].indexOf(this.separator) != -1) {
+					var tmp = this.ranges[i].split(this.separator);
+					var el = fn(tmp[0]) + this.legendSeparator + fn(tmp[1]);
+				} else {
+					var el = fn(this.ranges[i]);
+				}
+				content += '<div><div class="geostats-legend-block" style="background-color:' + ccolors[i] + '"></div> ' + el + cnt + '</div>';
+			}
+		} else {
+			// only if classification is done on unique values
+			for (i = 0; i < (this.bounds.length); i++) {
+				if(getcounter===true) {
+					cnt = ' <span class="geostats-legend-counter">(' + this.counter[i] + ')</span>';
+				}
+				var el = fn(this.bounds[i]);
+				content += '<div><div class="geostats-legend-block" style="background-color:' + ccolors[i] + '"></div> ' + el + cnt + '</div>';
+			}
+		}
+    content += '</div>';
+		return content;
+	};
+
+	this.getSortedlist = function() {
+		return this.sorted().join(', ');
+	};
+
+};
\ No newline at end of file
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/js/rainbowvis.js b/asterix-examples/src/main/resources/tweetbook-demo/static/js/rainbowvis.js
new file mode 100644
index 0000000..1f444dc
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/js/rainbowvis.js
@@ -0,0 +1,178 @@
+/*
+RainbowVis-JS 
+Released under MIT License
+
+Source: https://github.com/anomal/RainbowVis-JS
+*/
+
+function Rainbow()
+{
+	var gradients = null;
+	var minNum = 0;
+	var maxNum = 100;
+	var colours = ['ff0000', 'ffff00', '00ff00', '0000ff']; 
+	setColours(colours);
+	
+	function setColours (spectrum) 
+	{
+		if (spectrum.length < 2) {
+			throw new Error('Rainbow must have two or more colours.');
+		} else {
+			var increment = (maxNum - minNum)/(spectrum.length - 1);
+			var firstGradient = new ColourGradient();
+			firstGradient.setGradient(spectrum[0], spectrum[1]);
+			firstGradient.setNumberRange(minNum, minNum + increment);
+			gradients = [ firstGradient ];
+			
+			for (var i = 1; i < spectrum.length - 1; i++) {
+				var colourGradient = new ColourGradient();
+				colourGradient.setGradient(spectrum[i], spectrum[i + 1]);
+				colourGradient.setNumberRange(minNum + increment * i, minNum + increment * (i + 1)); 
+				gradients[i] = colourGradient; 
+			}
+
+			colours = spectrum;
+			return this;
+		}
+	}
+
+	this.setColors = this.setColours;
+
+	this.setSpectrum = function () 
+	{
+		setColours(arguments);
+		return this;
+	}
+
+	this.setSpectrumByArray = function (array)
+	{
+		setColours(array);
+        return this;
+	}
+
+	this.colourAt = function (number)
+	{
+		if (isNaN(number)) {
+			throw new TypeError(number + ' is not a number');
+		} else if (gradients.length === 1) {
+			return gradients[0].colourAt(number);
+		} else {
+			var segment = (maxNum - minNum)/(gradients.length);
+			var index = Math.min(Math.floor((Math.max(number, minNum) - minNum)/segment), gradients.length - 1);
+			return gradients[index].colourAt(number);
+		}
+	}
+
+	this.colorAt = this.colourAt;
+
+	this.setNumberRange = function (minNumber, maxNumber)
+	{
+		if (maxNumber > minNumber) {
+			minNum = minNumber;
+			maxNum = maxNumber;
+			setColours(colours);
+		} else {
+			throw new RangeError('maxNumber (' + maxNumber + ') is not greater than minNumber (' + minNumber + ')');
+		}
+		return this;
+	}
+}
+
+function ColourGradient() 
+{
+	var startColour = 'ff0000';
+	var endColour = '0000ff';
+	var minNum = 0;
+	var maxNum = 100;
+
+	this.setGradient = function (colourStart, colourEnd)
+	{
+		startColour = getHexColour(colourStart);
+		endColour = getHexColour(colourEnd);
+	}
+
+	this.setNumberRange = function (minNumber, maxNumber)
+	{
+		if (maxNumber > minNumber) {
+			minNum = minNumber;
+			maxNum = maxNumber;
+		} else {
+			throw new RangeError('maxNumber (' + maxNumber + ') is not greater than minNumber (' + minNumber + ')');
+		}
+	}
+
+	this.colourAt = function (number)
+	{
+		return calcHex(number, startColour.substring(0,2), endColour.substring(0,2)) 
+			+ calcHex(number, startColour.substring(2,4), endColour.substring(2,4)) 
+			+ calcHex(number, startColour.substring(4,6), endColour.substring(4,6));
+	}
+	
+	function calcHex(number, channelStart_Base16, channelEnd_Base16)
+	{
+		var num = number;
+		if (num < minNum) {
+			num = minNum;
+		}
+		if (num > maxNum) {
+			num = maxNum;
+		} 
+		var numRange = maxNum - minNum;
+		var cStart_Base10 = parseInt(channelStart_Base16, 16);
+		var cEnd_Base10 = parseInt(channelEnd_Base16, 16); 
+		var cPerUnit = (cEnd_Base10 - cStart_Base10)/numRange;
+		var c_Base10 = Math.round(cPerUnit * (num - minNum) + cStart_Base10);
+		return formatHex(c_Base10.toString(16));
+	}
+
+	formatHex = function (hex) 
+	{
+		if (hex.length === 1) {
+			return '0' + hex;
+		} else {
+			return hex;
+		}
+	} 
+	
+	function isHexColour(string)
+	{
+		var regex = /^#?[0-9a-fA-F]{6}$/i;
+		return regex.test(string);
+	}
+
+	function getHexColour(string)
+	{
+		if (isHexColour(string)) {
+			return string.substring(string.length - 6, string.length);
+		} else {
+			var colourNames =
+			[
+				['red', 'ff0000'],
+				['lime', '00ff00'],
+				['blue', '0000ff'],
+				['yellow', 'ffff00'],
+				['orange', 'ff8000'],
+				['aqua', '00ffff'],
+				['fuchsia', 'ff00ff'],
+				['white', 'ffffff'],
+				['black', '000000'],
+				['gray', '808080'],
+				['grey', '808080'],
+				['silver', 'c0c0c0'],
+				['maroon', '800000'],
+				['olive', '808000'],
+				['green', '008000'],
+				['teal', '008080'],
+				['navy', '000080'],
+				['purple', '800080']
+			];
+			for (var i = 0; i < colourNames.length; i++) {
+				if (string.toLowerCase() === colourNames[i][0]) {
+					return colourNames[i][1];
+				}
+			}
+			throw new Error(string + ' is not a valid colour.');
+		}
+	}
+}
+
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/static/js/tweetbook.js b/asterix-examples/src/main/resources/tweetbook-demo/static/js/tweetbook.js
new file mode 100755
index 0000000..61ecedb
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/static/js/tweetbook.js
@@ -0,0 +1,1176 @@
+$(function() {
+
+	// Initialize connection to AsterixDB. Just one connection is needed and contains
+	// logic for connecting to each API endpoint. This object A is reused throughout the
+	// code but does not store information about any individual API call.
+	A = new AsterixDBConnection({
+
+	    // We will be using the twitter dataverse, which we can configure either like this
+	    // or by following our AsterixDBConnection with a dataverse call, like so:
+	    // A = new AsterixDBConnection().dataverse("twitter");
+	    "dataverse" : "twitter",
+
+	    // Due to the setup of this demo using the Bottle server, it is necessary to change the
+	    // default endpoint of API calls. The proxy server handles the call to http://localhost:19002
+	    // for us, and we reconfigure this connection to connect to the proxy server.
+	    "endpoint_root" : "/",
+
+	    // Finally, we want to make our error function nicer so that we show errors with a call to the
+	    // reportUserMessage function. Update the "error" property to do that.
+	    "error" : function(data) {
+	                // For an error, data will look like this:
+	                // {
+	                //     "error-code" : [error-number, error-text]
+	                //     "stacktrace" : ...stack trace...
+	                //     "summary"    : ...summary of error...
+	                // }
+	                // We will report this as an Asterix REST API Error, an error code, and a reason message.
+	                // Note the method signature: reportUserMessage(message, isPositiveMessage, target). We will provide
+	                // an error message to display, a positivity value (false in this case, errors are bad), and a
+	                // target html element in which to report the message.
+	                var showErrorMessage = "Asterix Error #" + data["error-code"][0] + ": " + data["error-code"][1];
+	                var isPositive = false;
+	                var showReportAt = "report-message";
+
+	                reportUserMessage(showErrorMessage, isPositive, showReportAt);
+	              }
+	});
+
+    // This little bit of code manages period checks of the asynchronous query manager,
+    // which holds onto handles asynchornously received. We can set the handle update
+    // frequency using seconds, and it will let us know when it is ready.
+    var intervalID = setInterval(
+        function() {
+            asynchronousQueryIntervalUpdate();
+        },
+        asynchronousQueryGetInterval()
+    );
+
+    // Legend Container
+    // Create a rainbow from a pretty color scheme.
+    // http://www.colourlovers.com/palette/292482/Terra
+    rainbow = new Rainbow();
+    rainbow.setSpectrum("#E8DDCB", "#CDB380", "#036564", "#033649", "#031634");
+    buildLegend();
+
+    // Initialization of UI Tabas
+    initDemoPrepareTabs();
+
+    // UI Elements - Creates Map, Location Auto-Complete, Selection Rectangle
+    var mapOptions = {
+        center: new google.maps.LatLng(38.89, -77.03),
+        zoom: 4,
+        mapTypeId: google.maps.MapTypeId.ROADMAP,
+        streetViewControl: false,
+        draggable : false,
+        mapTypeControl: false
+    };
+    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
+
+    var input = document.getElementById('location-text-box');
+    var autocomplete = new google.maps.places.Autocomplete(input);
+    autocomplete.bindTo('bounds', map);
+
+    google.maps.event.addListener(autocomplete, 'place_changed', function() {
+        var place = autocomplete.getPlace();
+        if (place.geometry.viewport) {
+            map.fitBounds(place.geometry.viewport);
+        } else {
+            map.setCenter(place.geometry.location);
+            map.setZoom(17);  // Why 17? Because it looks good.
+        }
+        var address = '';
+        if (place.address_components) {
+            address = [(place.address_components[0] && place.address_components[0].short_name || ''),
+              (place.address_components[1] && place.address_components[1].short_name || ''),
+              (place.address_components[2] && place.address_components[2].short_name || '') ].join(' ');
+        }
+    });
+
+    // Drawing Manager for selecting map regions. See documentation here:
+    // https://developers.google.com/maps/documentation/javascript/reference#DrawingManager
+    rectangleManager = new google.maps.drawing.DrawingManager({
+        drawingMode : google.maps.drawing.OverlayType.RECTANGLE,
+        drawingControl : false,
+        rectangleOptions : {
+            strokeWeight: 1,
+            clickable: false,
+            editable: true,
+            strokeColor: "#2b3f8c",
+            fillColor: "#2b3f8c",
+            zIndex: 1
+        }
+    });
+    rectangleManager.setMap(map);
+    selectionRectangle = null;
+
+    // Drawing Manager: Just one editable rectangle!
+    google.maps.event.addListener(rectangleManager, 'rectanglecomplete', function(rectangle) {
+        selectionRectangle = rectangle;
+        rectangleManager.setDrawingMode(null);
+    });
+
+    // Initialize data structures
+    APIqueryTracker = {};
+    asyncQueryManager = {};
+    map_cells = [];
+    map_tweet_markers = [];
+    map_info_windows = {};
+    review_mode_tweetbooks = [];
+
+    getAllDataverseTweetbooks();
+    initDemoUIButtonControls();
+
+    google.maps.event.addListenerOnce(map, 'idle', function(){
+        // Show tutorial tab only the first time the map is loaded
+        $('#mode-tabs a:first').tab('show');
+    });
+
+});
+
+function initDemoUIButtonControls() {
+
+    // Explore Mode - Update Sliders
+    var updateSliderDisplay = function(event, ui) {
+        if (event.target.id == "grid-lat-slider") {
+            $("#gridlat").text(""+ui.value);
+        } else {
+          $("#gridlng").text(""+ui.value);
+        }
+    };
+    sliderOptions = {
+        max: 10,
+        min: 2.0,
+        step: .1,
+        value: 3.0,
+        slidechange: updateSliderDisplay,
+        slide: updateSliderDisplay,
+        start: updateSliderDisplay,
+        stop: updateSliderDisplay
+    };
+    $("#gridlat").text(""+sliderOptions.value);
+    $("#gridlng").text(""+sliderOptions.value);
+    $(".grid-slider").slider(sliderOptions);
+
+    // Explore Mode - Query Builder Date Pickers
+    var dateOptions = {
+        dateFormat: "yy-mm-dd",
+        defaultDate: "2012-01-02",
+        navigationAsDateFormat: true,
+        constrainInput: true
+    };
+    var start_dp = $("#start-date").datepicker(dateOptions);
+    start_dp.val(dateOptions.defaultDate);
+    dateOptions['defaultDate'] = "2012-12-31";
+    var end_dp= $("#end-date").datepicker(dateOptions);
+    end_dp.val(dateOptions.defaultDate);
+
+    // Explore Mode: Toggle Selection/Location Search
+    $('#selection-button').on('change', function (e) {
+        $("#location-text-box").attr("disabled", "disabled");
+        rectangleManager.setMap(map);
+        if (selectionRectangle) {
+            selectionRectangle.setMap(null);
+            selectionRectangle = null;
+        } else {
+            rectangleManager.setDrawingMode(google.maps.drawing.OverlayType.RECTANGLE);
+        }
+    });
+    $('#location-button').on('change', function (e) {
+        $("#location-text-box").removeAttr("disabled");
+        selectionRectangle.setMap(null);
+        rectangleManager.setMap(null);
+        rectangleManager.setDrawingMode(google.maps.drawing.OverlayType.RECTANGLE);
+    });
+    $("#selection-button").trigger("click");
+
+    // Review Mode: New Tweetbook
+    $('#new-tweetbook-button').on('click', function (e) {
+        onCreateNewTweetBook($('#new-tweetbook-entry').val());
+
+        $('#new-tweetbook-entry').val("");
+        $('#new-tweetbook-entry').attr("placeholder", "Name a new tweetbook");
+    });
+
+    // Explore Mode - Clear Button
+    $("#clear-button").click(mapWidgetResetMap);
+
+    // Explore Mode: Query Submission
+    $("#submit-button").on("click", function () {
+
+        $("#report-message").html('');
+        $("#submit-button").attr("disabled", true);
+        rectangleManager.setDrawingMode(null);
+
+        var kwterm = $("#keyword-textbox").val();
+        var startdp = $("#start-date").datepicker("getDate");
+        var enddp = $("#end-date").datepicker("getDate");
+        var startdt = $.datepicker.formatDate("yy-mm-dd", startdp)+"T00:00:00Z";
+        var enddt = $.datepicker.formatDate("yy-mm-dd", enddp)+"T23:59:59Z";
+
+        var formData = {
+            "keyword": kwterm,
+            "startdt": startdt,
+            "enddt": enddt,
+            "gridlat": $("#grid-lat-slider").slider("value"),
+            "gridlng": $("#grid-lng-slider").slider("value")
+        };
+
+        // Get Map Bounds
+        var bounds;
+        if ($('#selection-label').hasClass("active") && selectionRectangle) {
+            bounds = selectionRectangle.getBounds();
+        } else {
+            bounds = map.getBounds();
+        }
+
+        var swLat = Math.abs(bounds.getSouthWest().lat());
+        var swLng = Math.abs(bounds.getSouthWest().lng());
+        var neLat = Math.abs(bounds.getNorthEast().lat());
+        var neLng = Math.abs(bounds.getNorthEast().lng());
+
+        formData["swLat"] = Math.min(swLat, neLat);
+        formData["swLng"] = Math.max(swLng, neLng);
+        formData["neLat"] = Math.max(swLat, neLat);
+        formData["neLng"] = Math.min(swLng, neLng);
+
+        var build_tweetbook_mode = "synchronous";
+        if ($('#asbox').is(":checked")) {
+            build_tweetbook_mode = "asynchronous";
+        }
+
+        var f = buildAQLQueryFromForm(formData);
+
+        APIqueryTracker = {
+            "query" : "use dataverse twitter;\n" + f.val(),
+            "data" : formData
+        };
+
+        if (build_tweetbook_mode == "synchronous") {
+            A.query(f.val(), tweetbookQuerySyncCallback, build_tweetbook_mode);
+        } else {
+            A.query(f.val(), tweetbookQueryAsyncCallback, build_tweetbook_mode);
+        }
+
+        // Clears selection rectangle on query execution, rather than waiting for another clear call.
+        if (selectionRectangle) {
+            selectionRectangle.setMap(null);
+            selectionRectangle = null;
+        }
+    });
+}
+
+/**
+* Builds AsterixDB REST Query from explore mode form.
+*/
+function buildAQLQueryFromForm(parameters) {
+
+    var bounds = {
+        "ne" : { "lat" : parameters["neLat"], "lng" : -1*parameters["neLng"]},
+		"sw" : { "lat" : parameters["swLat"], "lng" : -1*parameters["swLng"]}
+    };
+
+    var rectangle =
+        new FunctionExpression("create-rectangle",
+            new FunctionExpression("create-point", bounds["sw"]["lat"], bounds["sw"]["lng"]),
+            new FunctionExpression("create-point", bounds["ne"]["lat"], bounds["ne"]["lng"]));
+
+    // You can chain these all together, but let's take them one at a time.
+    // Let's start with a ForClause. Here we go through each tweet $t in the
+    // dataset TweetMessageShifted.
+    var aql = new FLWOGRExpression()
+        .ForClause("$t", new AExpression("dataset TweetMessagesShifted"));
+
+    // We know we have bounds for our region, so we can add that LetClause next.
+    aql = aql.LetClause("$region", rectangle);
+
+    // Now, let's change it up. The keyword term doesn't always show up, so it might be blank.
+    // We'll attach a new let clause for it, and then a WhereClause.
+    if (parameters["keyword"].length > 0) {
+        aql = aql
+                .LetClause("$keyword", new AExpression('"' + parameters["keyword"] + '"'))
+                .WhereClause().and(
+                    new FunctionExpression("spatial-intersect", "$t.sender-location", "$region"),
+                    new AExpression('$t.send-time > datetime("' + parameters["startdt"] + '")'),
+                    new AExpression('$t.send-time < datetime("' + parameters["enddt"] + '")'),
+                    new FunctionExpression("contains", "$t.message-text", "$keyword")
+                );
+    } else {
+        aql = aql
+                .WhereClause().and(
+                    new FunctionExpression("spatial-intersect", "$t.sender-location", "$region"),
+                    new AExpression('$t.send-time > datetime("' + parameters["startdt"] + '")'),
+                    new AExpression('$t.send-time < datetime("' + parameters["enddt"] + '")')
+                );
+    }
+
+    // Finally, we'll group our results into spatial cells.
+    aql = aql.GroupClause(
+                "$c",
+                new FunctionExpression("spatial-cell", "$t.sender-location",
+                new FunctionExpression("create-point", "24.5", "-125.5"),
+                parameters["gridlat"].toFixed(1), parameters["gridlng"].toFixed(1)),
+                "with",
+                "$t"
+            );
+
+    // ...and return a resulting cell and a count of results in that cell.
+    aql = aql.ReturnClause({ "cell" : "$c", "count" : "count($t)" });
+
+    return aql;
+}
+
+/**
+* getAllDataverseTweetbooks
+*
+* Returns all datasets of type TweetbookEntry, populates review_mode_tweetbooks
+*/
+function getAllDataverseTweetbooks(fn_tweetbooks) {
+
+    // This creates a query to the Metadata for datasets of type
+    // TweetBookEntry. Note that if we throw in a WhereClause (commented out below)
+    // there is an odd error. This is being fixed and will be removed from this demo.
+    var getTweetbooksQuery = new FLWOGRExpression()
+        .ForClause("$ds", new AExpression("dataset Metadata.Dataset"))
+        //.WhereClause(new AExpression('$ds.DataTypeName = "TweetbookEntry"'))
+        .ReturnClause({
+            "DataTypeName" : "$ds.DataTypeName",
+            "DatasetName" : "$ds.DatasetName"
+        });
+
+    // Now create a function that will be called when tweetbooks succeed.
+    // In this case, we want to parse out the results object from the Asterix
+    // REST API response.
+    var tweetbooksSuccess = function(r) {
+        // Parse tweetbook metadata results
+        $.each(r.results, function(i, data) {
+            if ($.parseJSON(data)["DataTypeName"] == "TweetbookEntry") {
+                review_mode_tweetbooks.push($.parseJSON(data)["DatasetName"]);
+            }
+        });
+
+        // Now, if any tweetbooks already exist, opulate review screen.
+        $('#review-tweetbook-titles').html('');
+        $.each(review_mode_tweetbooks, function(i, tweetbook) {
+            addTweetBookDropdownItem(tweetbook);
+        });
+    };
+
+    // Now, we are ready to run a query.
+    A.meta(getTweetbooksQuery.val(), tweetbooksSuccess);
+}
+
+/**
+* Checks through each asynchronous query to see if they are ready yet
+*/
+function asynchronousQueryIntervalUpdate() {
+    for (var handle_key in asyncQueryManager) {
+        if (!asyncQueryManager[handle_key].hasOwnProperty("ready")) {
+            asynchronousQueryGetAPIQueryStatus( asyncQueryManager[handle_key]["handle"], handle_key );
+        }
+    }
+}
+
+/**
+* Returns current time interval to check for asynchronous query readiness
+* @returns  {number}    milliseconds between asychronous query checks
+*/
+function asynchronousQueryGetInterval() {
+    var seconds = 10;
+    return seconds * 1000;
+}
+
+/**
+* Retrieves status of an asynchronous query, using an opaque result handle from API
+* @param    {Object}    handle, an object previously returned from an async call
+* @param    {number}    handle_id, the integer ID parsed from the handle object
+*/
+function asynchronousQueryGetAPIQueryStatus (handle, handle_id) {
+
+    A.query_status(
+        {
+            "handle" : JSON.stringify(handle)
+        },
+        function (res) {
+            if (res["status"] == "SUCCESS") {
+                // We don't need to check if this one is ready again, it's not going anywhere...
+                // Unless the life cycle of handles has changed drastically
+                asyncQueryManager[handle_id]["ready"] = true;
+
+                // Indicate success.
+                $('#handle_' + handle_id).removeClass("btn-disabled").prop('disabled', false).addClass("btn-success");
+            }
+        }
+     );
+}
+
+/**
+* On-success callback after async API query
+* @param    {object}    res, a result object containing an opaque result handle to Asterix
+*/
+function tweetbookQueryAsyncCallback(res) {
+
+    // Parse handle, handle id and query from async call result
+    var handle_query = APIqueryTracker["query"];
+    var handle = res;
+    var handle_id = res["handle"].toString().split(',')[0];
+
+    // Add to stored map of existing handles
+    asyncQueryManager[handle_id] = {
+        "handle" : handle,
+        "query" : handle_query, // This will show up when query control button is clicked.
+        "data" : APIqueryTracker["data"]
+    };
+
+    // Create a container for this async query handle
+    $('<div/>')
+        .css("margin-left", "1em")
+        .css("margin-bottom", "1em")
+        .css("display", "block")
+        .attr({
+            "class" : "btn-group",
+            "id" : "async_container_" + handle_id
+        })
+        .appendTo("#async-handle-controls");
+
+    // Adds the main button for this async handle
+    var handle_action_button = '<button class="btn btn-disabled" id="handle_' + handle_id + '">Handle ' + handle_id + '</button>';
+    $('#async_container_' + handle_id).append(handle_action_button);
+    $('#handle_' + handle_id).prop('disabled', true);
+    $('#handle_' + handle_id).on('click', function (e) {
+
+        // make sure query is ready to be run
+        if (asyncQueryManager[handle_id]["ready"]) {
+
+            APIqueryTracker = {
+                "query" : asyncQueryManager[handle_id]["query"],
+                "data"  : asyncQueryManager[handle_id]["data"]
+            };
+
+            if (!asyncQueryManager[handle_id].hasOwnProperty("result")) {
+                // Generate new Asterix Core API Query
+                A.query_result(
+                    { "handle" : JSON.stringify(asyncQueryManager[handle_id]["handle"]) },
+                    function(res) {
+                        asyncQueryManager[handle_id]["result"] = res;
+
+                        var resultTransform = {
+                            "results" : res.results
+                        };
+
+                        tweetbookQuerySyncCallback(resultTransform);
+                    }
+                );
+            } else {
+
+                var resultTransform = {
+                    "results" : asyncQueryManager[handle_id]["result"].results
+                };
+
+                tweetbookQuerySyncCallback(resultTransform);
+            }
+        }
+    });
+
+    // Adds a removal button for this async handle
+    var asyncDeleteButton = addDeleteButton(
+        "trashhandle_" + handle_id,
+        "async_container_" + handle_id,
+        function (e) {
+            $('#async_container_' + handle_id).remove();
+            delete asyncQueryManager[handle_id];
+        }
+    );
+
+    $('#async_container_' + handle_id).append('<br/>');
+
+    $("#submit-button").attr("disabled", false);
+}
+
+/**
+* A spatial data cleaning and mapping call
+* @param    {Object}    res, a result object from a tweetbook geospatial query
+*/
+function tweetbookQuerySyncCallback(res) {
+    // First, we check if any results came back in.
+    // If they didn't, return.
+    if (!res.hasOwnProperty("results")) {
+        reportUserMessage("Oops, no results found for those parameters.", false, "report-message");
+        return;
+    }
+
+    // Initialize coordinates and weights, to store
+    // coordinates of map cells and their weights
+    var coordinates = [];
+    var maxWeight = 0;
+    var minWeight = Number.MAX_VALUE;
+
+    // Parse resulting JSON objects. Here is an example record:
+    // { "cell": rectangle("21.5,-98.5 24.5,-95.5"), "count": 78i64 }
+    $.each(res.results, function(i, data) {
+
+        // 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"     : 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);
+}
+
+/**
+* Triggers a map update based on a set of spatial query result cells
+* @param    [Array]     mapPlotData, an array of coordinate and weight objects
+* @param    [Array]     plotWeights, a list of weights of the spatial cells - e.g., number of tweets
+*/
+function triggerUIUpdate(mapPlotData, maxWeight, minWeight) {
+    /** Clear anything currently on the map **/
+    mapWidgetClearMap();
+
+    // Initialize info windows.
+    map_info_windows = {};
+
+    $.each(mapPlotData, function (m) {
+
+        var point_center = new google.maps.LatLng(
+            (mapPlotData[m].latSW + mapPlotData[m].latNE)/2.0,
+            (mapPlotData[m].lngSW + mapPlotData[m].lngNE)/2.0);
+
+        var map_circle_options = {
+            center: point_center,
+            anchorPoint: point_center,
+            radius: mapWidgetComputeCircleRadius(mapPlotData[m], maxWeight),
+            map: map,
+            fillOpacity: 0.85,
+            fillColor: "#" + rainbow.colourAt(Math.ceil(100 * (mapPlotData[m].weight / maxWeight))),
+            clickable: true
+        };
+        var map_circle = new google.maps.Circle(map_circle_options);
+        map_circle.val = mapPlotData[m];
+
+        map_info_windows[m] = new google.maps.InfoWindow({
+            content: mapPlotData[m].weight + " tweets",
+            position: point_center
+        });
+
+        // Clicking on a circle drills down map to that value, hovering over it displays a count
+        // of tweets at that location.
+        google.maps.event.addListener(map_circle, 'click', function (event) {
+            $.each(map_info_windows, function(i) {
+                map_info_windows[i].close();
+            });
+            onMapPointDrillDown(map_circle.val);
+        });
+
+        google.maps.event.addListener(map_circle, 'mouseover', function(event) {
+            if (!map_info_windows[m].getMap()) {
+                map_info_windows[m].setPosition(map_circle.center);
+                map_info_windows[m].open(map);
+            }
+        });
+        google.maps.event.addListener(map, 'mousemove', function(event) {
+            map_info_windows[m].close();
+
+        });
+
+        // Add this marker to global marker cells
+        map_cells.push(map_circle);
+
+        // Show legend
+        $("#legend-min").html(minWeight);
+        $("#legend-max").html(maxWeight);
+        $("#rainbow-legend-container").show();
+    });
+}
+
+/**
+* prepares an Asterix API query to drill down in a rectangular spatial zone
+*
+* @params {object} marker_borders a set of bounds for a region from a previous api result
+*/
+function onMapPointDrillDown(marker_borders) {
+
+    var zoneData = APIqueryTracker["data"];
+
+    var zswBounds = new google.maps.LatLng(marker_borders.latSW, marker_borders.lngSW);
+    var zneBounds = new google.maps.LatLng(marker_borders.latNE, marker_borders.lngNE);
+
+    var zoneBounds = new google.maps.LatLngBounds(zswBounds, zneBounds);
+    zoneData["swLat"] = zoneBounds.getSouthWest().lat();
+    zoneData["swLng"] = zoneBounds.getSouthWest().lng();
+    zoneData["neLat"] = zoneBounds.getNorthEast().lat();
+    zoneData["neLng"] = zoneBounds.getNorthEast().lng();
+    var zB = {
+        "sw" : {
+            "lat" : zoneBounds.getSouthWest().lat(),
+            "lng" : zoneBounds.getSouthWest().lng()
+        },
+        "ne" : {
+            "lat" : zoneBounds.getNorthEast().lat(),
+            "lng" : zoneBounds.getNorthEast().lng()
+        }
+    };
+
+    mapWidgetClearMap();
+
+    var customBounds = new google.maps.LatLngBounds();
+    var zoomSWBounds = new google.maps.LatLng(zoneData["swLat"], zoneData["swLng"]);
+    var zoomNEBounds = new google.maps.LatLng(zoneData["neLat"], zoneData["neLng"]);
+    customBounds.extend(zoomSWBounds);
+    customBounds.extend(zoomNEBounds);
+    map.fitBounds(customBounds);
+
+    var df = getDrillDownQuery(zoneData, zB);
+
+    APIqueryTracker = {
+        "query_string" : "use dataverse twitter;\n" + df.val(),
+        "marker_path" : "static/img/mobile2.png"
+    };
+
+    A.query(df.val(), onTweetbookQuerySuccessPlot);
+}
+
+/**
+* Generates an aql query for zooming on a spatial cell and obtaining tweets contained therein.
+* @param parameters, the original query parameters
+* @param bounds, the bounds of the zone to zoom in on.
+*/
+function getDrillDownQuery(parameters, bounds) {
+
+    var zoomRectangle = new FunctionExpression("create-rectangle",
+        new FunctionExpression("create-point", bounds["sw"]["lat"], bounds["sw"]["lng"]),
+        new FunctionExpression("create-point", bounds["ne"]["lat"], bounds["ne"]["lng"]));
+
+    var drillDown = new FLWOGRExpression()
+        .ForClause("$t", new AExpression("dataset TweetMessagesShifted"))
+        .LetClause("$region", zoomRectangle);
+
+    if (parameters["keyword"].length == 0) {
+        drillDown = drillDown
+                        .WhereClause().and(
+                            new FunctionExpression('spatial-intersect', '$t.sender-location', '$region'),
+                            new AExpression().set('$t.send-time > datetime("' + parameters["startdt"] + '")'),
+                            new AExpression().set('$t.send-time < datetime("' + parameters["enddt"] + '")')
+                        );
+    } else {
+        drillDown = drillDown
+                        .LetClause("$keyword", new AExpression('"' + parameters["keyword"] + '"'))
+                        .WhereClause().and(
+                            new FunctionExpression('spatial-intersect', '$t.sender-location', '$region'),
+                            new AExpression().set('$t.send-time > datetime("' + parameters["startdt"] + '")'),
+                            new AExpression().set('$t.send-time < datetime("' + parameters["enddt"] + '")'),
+                            new FunctionExpression('contains', '$t.message-text', '$keyword')
+                        );
+    }
+
+    drillDown = drillDown
+                    .ReturnClause({
+                        "tweetId" : "$t.tweetid",
+                        "tweetText" : "$t.message-text",
+                        "tweetLoc" : "$t.sender-location"
+                    });
+
+    return drillDown;
+}
+
+/**
+* Given a location where a tweet exists, opens a modal to examine or update a tweet's content.
+* @param t0, a tweetobject that has a location, text, id, and optionally a comment.
+*/
+function onDrillDownAtLocation(tO) {
+
+    var tweetId = tO["tweetEntryId"];
+    var tweetText = tO["tweetText"];
+
+    // First, set tweet in drilldown modal to be this tweet's text
+    $('#modal-body-tweet').html('Tweet #' + tweetId + ": " + tweetText);
+
+    // Next, empty any leftover tweetbook comments or error/success messages
+    $("#modal-body-add-to").val('');
+    $("#modal-body-add-note").val('');
+    $("#modal-body-message-holder").html("");
+
+    // Next, if there is an existing tweetcomment reported, show it.
+    if (tO.hasOwnProperty("tweetComment")) {
+
+        // Show correct panel
+        $("#modal-existing-note").show();
+        $("#modal-save-tweet-panel").hide();
+
+        // Fill in existing tweet comment
+        $("#modal-body-tweet-note").val(tO["tweetComment"]);
+
+        // Change Tweetbook Badge
+        $("#modal-current-tweetbook").val(APIqueryTracker["active_tweetbook"]);
+
+        // Add deletion functionality
+        $("#modal-body-trash-icon").on('click', function () {
+            // Send comment deletion to asterix
+            var deleteTweetCommentOnId = '"' + tweetId + '"';
+            var toDelete = new DeleteStatement(
+                "$mt",
+                APIqueryTracker["active_tweetbook"],
+                new AExpression("$mt.tweetid = " + deleteTweetCommentOnId.toString())
+            );
+            A.update(
+                toDelete.val()
+            );
+
+            // Hide comment from map
+            $('#drilldown_modal').modal('hide');
+
+            // Replot tweetbook
+            onPlotTweetbook(APIqueryTracker["active_tweetbook"]);
+        });
+
+    } else {
+        // Show correct panel
+        $("#modal-existing-note").hide();
+        $("#modal-save-tweet-panel").show();
+
+        // Now, when adding a comment on an available tweet to a tweetbook
+        $('#save-comment-tweetbook-modal').unbind('click');
+        $("#save-comment-tweetbook-modal").on('click', function(e) {
+
+            // Stuff to save about new comment
+            var save_metacomment_target_tweetbook = $("#modal-body-add-to").val();
+            var save_metacomment_target_comment = '"' + $("#modal-body-add-note").val() + '"';
+            var save_metacomment_target_tweet = '"' + tweetId + '"';
+
+            // Make sure content is entered, and then save this comment.
+            if ($("#modal-body-add-note").val() == "") {
+
+                reportUserMessage("Please enter a comment about the tweet", false, "report-message");
+
+            } else if ($("#modal-body-add-to").val() == "") {
+
+                reportUserMessage("Please enter a tweetbook.", false, "report-message");
+
+            } else {
+
+                // Check if tweetbook exists. If not, create it.
+                if (!(existsTweetbook(save_metacomment_target_tweetbook))) {
+                    onCreateNewTweetBook(save_metacomment_target_tweetbook);
+                }
+
+                var toInsert = new InsertStatement(
+                    save_metacomment_target_tweetbook,
+                    {
+                        "tweetid" : save_metacomment_target_tweet.toString(),
+                        "comment-text" : save_metacomment_target_comment
+                    }
+                );
+
+                A.update(toInsert.val(), function () {
+                    var successMessage = "Saved comment on <b>Tweet #" + tweetId +
+                        "</b> in dataset <b>" + save_metacomment_target_tweetbook + "</b>.";
+                    reportUserMessage(successMessage, true, "report-message");
+
+                    $("#modal-body-add-to").val('');
+                    $("#modal-body-add-note").val('');
+                    $('#save-comment-tweetbook-modal').unbind('click');
+
+                    // Close modal
+                    $('#drilldown_modal').modal('hide');
+                });
+            }
+        });
+    }
+}
+
+/**
+* Adds a new tweetbook entry to the menu and creates a dataset of type TweetbookEntry.
+*/
+function onCreateNewTweetBook(tweetbook_title) {
+
+    var tweetbook_title = tweetbook_title.split(' ').join('_');
+
+    A.ddl(
+        "create dataset " + tweetbook_title + "(TweetbookEntry) primary key tweetid;",
+        function () {}
+    );
+
+    if (!(existsTweetbook(tweetbook_title))) {
+        review_mode_tweetbooks.push(tweetbook_title);
+        addTweetBookDropdownItem(tweetbook_title);
+    }
+}
+
+/**
+* Removes a tweetbook from both demo and from
+* dataverse metadata.
+*/
+function onDropTweetBook(tweetbook_title) {
+
+    // AQL Call
+    A.ddl(
+        "drop dataset " + tweetbook_title + " if exists;",
+        function () {}
+    );
+
+    // Removes tweetbook from review_mode_tweetbooks
+    var remove_position = $.inArray(tweetbook_title, review_mode_tweetbooks);
+    if (remove_position >= 0) review_mode_tweetbooks.splice(remove_position, 1);
+
+    // Clear UI with review tweetbook titles
+    $('#review-tweetbook-titles').html('');
+    for (r in review_mode_tweetbooks) {
+        addTweetBookDropdownItem(review_mode_tweetbooks[r]);
+    }
+}
+
+/**
+* Adds a tweetbook action button to the dropdown box in review mode.
+* @param tweetbook, a string representing a tweetbook
+*/
+function addTweetBookDropdownItem(tweetbook) {
+    // Add placeholder for this tweetbook
+    $('<div/>')
+        .attr({
+            "class" : "btn-group",
+            "id" : "rm_holder_" + tweetbook
+        }).appendTo("#review-tweetbook-titles");
+
+    // Add plotting button for this tweetbook
+    var plot_button = '<button class="btn btn-default" id="rm_plotbook_' + tweetbook + '">' + tweetbook + '</button>';
+    $("#rm_holder_" + tweetbook).append(plot_button);
+    $("#rm_plotbook_" + tweetbook).width("200px");
+    $("#rm_plotbook_" + tweetbook).on('click', function(e) {
+        onPlotTweetbook(tweetbook);
+    });
+
+    // Add trash button for this tweetbook
+    var onTrashTweetbookButton = addDeleteButton(
+        "rm_trashbook_" + tweetbook,
+        "rm_holder_" + tweetbook,
+        function(e) {
+            onDropTweetBook(tweetbook);
+        }
+    );
+}
+
+/**
+* Generates AsterixDB query to plot existing tweetbook commnets
+* @param tweetbook, a string representing a tweetbook
+*/
+function onPlotTweetbook(tweetbook) {
+
+    // Clear map for this one
+    mapWidgetClearMap();
+
+    var plotTweetQuery = new FLWOGRExpression()
+        .ForClause("$t", new AExpression("dataset TweetMessagesShifted"))
+        .ForClause("$m", new AExpression("dataset " + tweetbook))
+        .WhereClause(new AExpression("$m.tweetid = $t.tweetid"))
+        .ReturnClause({
+            "tweetId" : "$m.tweetid",
+            "tweetText" : "$t.message-text",
+            "tweetCom" : "$m.comment-text",
+            "tweetLoc" : "$t.sender-location"
+        });
+
+    APIqueryTracker = {
+        "query_string" : "use dataverse twitter;\n" + plotTweetQuery.val(),
+        "marker_path" : "static/img/mobile_green2.png",
+        "active_tweetbook" : tweetbook
+    };
+
+    A.query(plotTweetQuery.val(), onTweetbookQuerySuccessPlot);
+}
+
+/**
+* Given an output response set of tweet data,
+* prepares markers on map to represent individual tweets.
+* @param res, a JSON Object
+*/
+function onTweetbookQuerySuccessPlot (res) {
+
+    // First, we check if any results came back in.
+    // If they didn't, return.
+    if (!res.hasOwnProperty("results")) {
+        reportUserMessage("Oops, no data matches this query.", false, "report-message");
+        return;
+    }
+
+    // Parse out tweet Ids, texts, and locations
+    var tweets = [];
+    var al = 1;
+
+    $.each(res.results, function(i, 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" : 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;
+        }
+
+        tweets.push(tweetData)
+    });
+
+    // 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: APIqueryTracker["marker_path"],
+            clickable: true,
+        });
+        map_tweet_m["test"] = t;
+
+        // Open Tweet exploration window on click
+        google.maps.event.addListener(map_tweet_m, 'click', function (event) {
+            onClickTweetbookMapMarker(map_tweet_markers[i]["test"]);
+        });
+
+        // Add marker to index of tweets
+        map_tweet_markers.push(map_tweet_m);
+    });
+}
+
+/**
+* Checks if a tweetbook exists
+* @param tweetbook, a String
+*/
+function existsTweetbook(tweetbook) {
+    if (parseInt($.inArray(tweetbook, review_mode_tweetbooks)) == -1) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+/**
+* When a marker is clicked on in the tweetbook, it will launch a modal
+* view to examine or edit the appropriate tweet
+*/
+function onClickTweetbookMapMarker(t) {
+    onDrillDownAtLocation(t)
+    $('#drilldown_modal').modal();
+}
+
+/**
+* Explore mode: Initial map creation and screen alignment
+*/
+function onOpenExploreMap () {
+    var explore_column_height = $('#explore-well').height();
+    var right_column_width = $('#right-col').width();
+    $('#map_canvas').height(explore_column_height + "px");
+    $('#map_canvas').width(right_column_width + "px");
+
+    $('#review-well').height(explore_column_height + "px");
+    $('#review-well').css('max-height', explore_column_height + "px");
+    $('#right-col').height(explore_column_height + "px");
+}
+
+/**
+* initializes demo - adds some extra events when review/explore
+* mode are clicked, initializes tabs, aligns map box, moves
+* active tab to about tab
+*/
+function initDemoPrepareTabs() {
+
+    // Tab behavior for About, Explore, and Demo
+    $('#mode-tabs a').click(function (e) {
+        e.preventDefault()
+        $(this).tab('show')
+    })
+
+    // Explore mode should show explore-mode query-builder UI
+    $('#explore-mode').click(function(e) {
+        $('#review-well').hide();
+        $('#explore-well').show();
+        rectangleManager.setMap(map);
+        rectangleManager.setDrawingMode(google.maps.drawing.OverlayType.RECTANGLE);
+        mapWidgetResetMap();
+    });
+
+    // Review mode should show review well and hide explore well
+    $('#review-mode').click(function(e) {
+        $('#explore-well').hide();
+        $('#review-well').show();
+        mapWidgetResetMap();
+        rectangleManager.setMap(null);
+        rectangleManager.setDrawingMode(null);
+    });
+
+    // Does some alignment necessary for the map canvas
+    onOpenExploreMap();
+}
+
+/**
+* Creates a delete icon button using default trash icon
+* @param    {String}    id, id for this element
+* @param    {String}    attachTo, id string of an element to which I can attach this button.
+* @param    {Function}  onClick, a function to fire when this icon is clicked
+*/
+function addDeleteButton(iconId, attachTo, onClick) {
+
+    var trashIcon = '<button class="btn btn-default" id="' + iconId + '"><span class="glyphicon glyphicon-trash"></span></button>';
+    $('#' + attachTo).append(trashIcon);
+
+    // When this trash button is clicked, the function is called.
+    $('#' + iconId).on('click', onClick);
+}
+
+/**
+* Creates a message and attaches it to data management area.
+* @param    {String}    message, a message to post
+* @param    {Boolean}   isPositiveMessage, whether or not this is a positive message.
+* @param    {String}    target, the target div to attach this message.
+*/
+function reportUserMessage(message, isPositiveMessage, target) {
+    // Clear out any existing messages
+    $('#' + target).html('');
+
+    // Select appropriate alert-type
+    var alertType = "alert-success";
+    if (!isPositiveMessage) {
+        alertType = "alert-danger";
+    }
+
+    // Append the appropriate message
+    $('<div/>')
+        .attr("class", "alert " + alertType)
+        .html('<button type="button" class="close" data-dismiss="alert">&times;</button>' + message)
+        .appendTo('#' + target);
+}
+
+/**
+* mapWidgetResetMap
+*
+* [No Parameters]
+*
+* Clears ALL map elements - plotted items, overlays, then resets position
+*/
+function mapWidgetResetMap() {
+
+    mapWidgetClearMap();
+
+    // Reset map center and zoom
+    map.setCenter(new google.maps.LatLng(38.89, -77.03));
+    map.setZoom(4);
+
+    // Selection button
+    $("#selection-button").trigger("click");
+    rectangleManager.setMap(map);
+    rectangleManager.setDrawingMode(google.maps.drawing.OverlayType.RECTANGLE);
+}
+
+/**
+* mapWidgetClearMap
+* Removes data/markers
+*/
+function mapWidgetClearMap() {
+
+    // Remove previously plotted data/markers
+    for (c in map_cells) {
+        map_cells[c].setMap(null);
+    }
+    map_cells = [];
+
+    $.each(map_info_windows, function(i) {
+        map_info_windows[i].close();
+    });
+    map_info_windows = {};
+
+    for (m in map_tweet_markers) {
+        map_tweet_markers[m].setMap(null);
+    }
+    map_tweet_markers = [];
+
+    // Hide legend
+    $("#rainbow-legend-container").hide();
+
+    // Reenable submit button
+    $("#submit-button").attr("disabled", false);
+
+    // Hide selection rectangle
+    if (selectionRectangle) {
+        selectionRectangle.setMap(null);
+        selectionRectangle = null;
+    }
+}
+
+/**
+* buildLegend
+*
+* Generates gradient, button action for legend bar
+*/
+function buildLegend() {
+
+    // Fill in legend area with colors
+    var gradientColor;
+
+    for (i = 0; i<100; i++) {
+        //$("#rainbow-legend-container").append("" + rainbow.colourAt(i));
+        $("#legend-gradient").append('<div style="display:inline-block; max-width:2px; background-color:#' + rainbow.colourAt(i) +';">&nbsp;</div>');
+    }
+}
+
+/**
+* Computes radius for a given data point from a spatial cell
+* @param    {Object}    keys => ["latSW" "lngSW" "latNE" "lngNE" "weight"]
+* @returns  {number}    radius between 2 points in metres
+*/
+function mapWidgetComputeCircleRadius(spatialCell, wLimit) {
+
+    // Define Boundary Points
+    var point_center = new google.maps.LatLng((spatialCell.latSW + spatialCell.latNE)/2.0, (spatialCell.lngSW + spatialCell.lngNE)/2.0);
+    var point_left = new google.maps.LatLng((spatialCell.latSW + spatialCell.latNE)/2.0, spatialCell.lngSW);
+    var point_top = new google.maps.LatLng(spatialCell.latNE, (spatialCell.lngSW + spatialCell.lngNE)/2.0);
+
+    // Circle scale modifier =
+    var scale = 425 + 425*(spatialCell.weight / wLimit);
+
+    // Return proportionate value so that circles mostly line up.
+    return scale * Math.min(distanceBetweenPoints(point_center, point_left), distanceBetweenPoints(point_center, point_top));
+}
+
+/**
+* Calculates the distance between two latlng locations in km, using Google Geometry API.
+* @param p1, a LatLng
+* @param p2, a LatLng
+*/
+function distanceBetweenPoints (p1, p2) {
+  return 0.001 * google.maps.geometry.spherical.computeDistanceBetween(p1, p2);
+};
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/tweetbook.tpl b/asterix-examples/src/main/resources/tweetbook-demo/tweetbook.tpl
new file mode 100755
index 0000000..d6fb3b8
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/tweetbook.tpl
@@ -0,0 +1,299 @@
+<!DOCTYPE html>
+<html style="width: 100%; height: 100%;">
+<head>
+  <title>ASTERIX Demo</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+  <link rel="shortcut icon" type="image/png" href="static/img/hyrax.png">
+
+  <!-- Bootstrap & jQuery Styles -->
+  <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
+  <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" type="text/css">
+
+  <!-- Bootstrap Javascript -->
+  <script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places,drawing,geometry" type="text/javascript"></script>
+
+  <script src="http://code.jquery.com/jquery.min.js"></script>
+  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
+  <script src="static/js/bootstrap.min.js"></script>
+  <script src="static/js/asterix-sdk-stable.js"></script>
+  <script src="static/js/rainbowvis.js"></script>
+  <script src="static/js/tweetbook.js"></script>
+
+  <style type="text/css">
+
+  .tab-content {
+    clear: none;
+  }
+
+  #map_canvas img {
+    max-width: none;
+  }
+
+  .panel-primary {
+    border-color: #273f93;
+  }
+
+  .panel-primary .panel-heading {
+    color: white;
+    background-color: #273f93;
+    border-color: #273f93;
+  }
+
+  #start-date, #end-date {
+    position: relative; z-index:100;
+  }
+
+  #keyword-textbox, #location-text-box {
+    width: 100%;
+  }
+  </style>
+</head>
+<body style="width: 100%; height: 100%;">
+
+  <!-- Nav -->
+  <div class="navbar navbar-default navbar-static-top">
+    <div class="container">
+      <div class="navbar-header">
+        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a class="navbar-brand" href="#" style="padding: 0.25em;">
+          <img src="static/img/finalasterixlogo.png">
+        </a>
+      </div>
+      <div class="navbar-collapse collapse">
+        <ul class="nav navbar-nav" id="mode-tabs">
+          <li id="about-active"><a data-toggle="tab" id="about-mode" href="#about-tab">About</a></li>
+          <li id="explore-active" class="active"><a data-toggle="tab" id="explore-mode" href="#demo-tab">Explore</a></li>
+          <li id="review-active"><a data-toggle="tab" id="review-mode" href="#demo-tab">Review</a></li>
+        </ul>
+      </div>
+    </div>
+  </div><!-- /Nav -->
+
+  <div class="tab-content">
+
+    <!-- Begin About Tab -->
+    <div class="tab-pane" id="about-tab">
+      <div class="container">
+        <!-- Welcome Message -->
+        <div class="row">
+          <p>Welcome to the top-level page of the Tweetbook Demo of AsterixDB.  The purpose of this demo is to illustrate how a "cool application" can be built using the JavaScript SDK of AsterixDB and to exercise all of the AsterixDB HTTP APIs.  If you are building an app of your own, reading the code for this app is a great way to get acquainted with what you'll need to know.</p>
+
+          <p>In this demo, which is based on spatial analysis of Tweets, you will see how to formulate aggregate queries and drill-down queries using the query door of the AsterixDB API.  You will see how to do this either synchronously or asynchronously (for larger queries whose results may take a while to cook).  You will also see how to create and drop datasets (to manage Tweetbooks, notebooks with user commentary on Tweets) and how to perform inserts and deletes (to add/remove Tweetbook entries). Let's walk through the demo.</p>
+        </div>
+        
+        <hr/>
+
+        <!-- Tutorial Part 1: Overview -->
+        <div style="margin-bottom: 2em; text-align: center;">
+          <img src="static/img/Tutorial1.png" style="max-width:100%;">
+        </div><hr/>
+
+        <!-- Tutorial Part 2: Location Search -->
+        <div style="margin-bottom: 2em; text-align: center;">
+          <img src="static/img/Tutorial2.png" style="max-width:100%;">
+        </div><hr/>
+
+        <!-- Tutorial Part 3: Search Results, Drilling Down, Saving Comments -->
+        <div style="margin-bottom: 2em; text-align: center;">
+          <img src="static/img/Tutorial3.png" style="max-width:100%;">
+        </div><hr/>
+
+        <!-- Tutorial Part 4: Review Mode -->
+        <div style="margin-bottom: 2em; text-align: center;">
+          <img src="static/img/Tutorial4.png" style="max-width:100%;">
+        </div> 
+      </div>
+    </div><!-- End About Tab -->
+
+    <!-- Begin Main Demo Tab -->
+    <div class="tab-pane active" id="demo-tab">
+      <div class="container">
+        <div class="row">
+          <!-- Left Column -->
+          <div class="col-md-5">
+
+            <!-- Explore Mode: Query Builder Column -->
+            <div class="container well" id="explore-well">
+
+              <!-- Query Builder -->
+              <div class="panel panel-primary">
+                <div class="panel-heading"><h4><b>Query Builder</b></h4></div>
+                <ul class="list-group">
+
+                  <!-- Search Keyword -->
+                  <li class="list-group-item">
+                    <h4 class="list-group-item-heading">Keyword</h4>
+                    <input type="text" id="keyword-textbox" placeholder="Enter a keyword, e.g., verizon">
+                  </li>
+
+                  <!-- Location -->
+                  <li class="list-group-item">
+                    <h4 class="list-group-item-heading">Location</h4>
+                    <input class="textbox" type="text" id="location-text-box">
+                    <div class="btn-group" data-toggle="buttons">
+                      <label id="location-label" class="btn btn-default">
+                        <input type="radio" id="location-button"> Location
+                      </label>
+                      <label id="selection-label" class="btn btn-default">
+                        <input type="radio" id="selection-button"> Selection
+                      </label>
+                    </div>
+                  </li>
+
+                  <!-- Date Range -->
+                  <li class="list-group-item">
+                    <h4 class="list-group-item-heading">Limit Date Range</h4>
+                    <input type="text" class="textbox" id="start-date"><span class="badge">Start Date</span><br/>
+                    <input type="text" class="textbox" id="end-date"><span class="badge">End Date</span>
+                  </li>
+
+                  <!-- Results Resolution -->
+                  <li class="list-group-item">
+                    <h4 class="list-group-item-heading">Result Group Size</h4>
+
+                    <div class="grid-slider" id="grid-lat-slider"></div>
+                    <div class="control-label">Latitude: <span id="gridlat">3.0</span></div>
+
+                    <div class="grid-slider" id="grid-lng-slider"></div>
+                    <div class="control-label">Longitude: <span id="gridlng">3.0</span></div>
+                  </li>
+
+                  <!-- Submission Buttons -->
+                  <li class="list-group-item">
+                    <button class="btn btn-primary" type="button" id="submit-button">Submit</button>
+                    <button class="btn btn-primary" type="button" id="clear-button">Clear</button><br/>
+                    <input type="checkbox" value="Submit Asynchronously" name="async" id="asbox" />
+                    Submit asynchronously?
+                  </li>
+                </ul>
+              </div>
+            </div><!-- End Query Build Column -->
+
+            <!-- Review Mode: Tweetbooks and Async Query Review Column -->
+            <div class="container well" id="review-well" style="display:none;">
+              <div class="panel panel-default">
+                <div class="panel-heading">
+                  <h4 class="panel-title">Tweetbooks</h4>
+                </div>
+                <div class="panel-body">
+                  <!-- Box to add a new Tweetbook -->
+                  <div class="input-group">
+                    <input type="text" class="form-control" id="new-tweetbook-entry" placeholder="Name a new tweetbook">
+                    <span class="input-group-btn">
+                      <button type="button" class="btn" id="new-tweetbook-button">Add</button>
+                    </span>
+                  </div>
+                  <hr/>
+
+                  <!-- List to add existing tweetbooks -->
+                  <div class="btn-group-vertical" id="review-tweetbook-titles"></div>
+                </div>
+              </div>
+
+              <!-- Background queries -->
+              <div class="panel panel-default">
+                <div class="panel-heading">
+                  <h4 class="panel-title">Background Queries</h4>
+                </div>
+                <div class="panel-body">
+                  <!-- Add existing background queries to list -->
+                  <div class="btn-group-vertical" id="review-tweetbook-titles"></div>
+                  <div id="async-handle-controls"></div>
+                </div>
+              </div>
+            </div><!-- end Review Mode Column -->
+            
+            <!-- Container to hold success/error messages -->
+            <div id="report-message"></div>
+          </div><!-- End Left Column -->
+
+          <!-- Right column holds map & legend -->
+          <div class="col-md-7">
+          <!-- Map Container -->
+          <div class="container well" id="right-col">
+            <div id="map_canvas" style="max-width: 100%; height: auto;"></div>
+          </div> 
+
+          <!-- Legend Container -->
+          <div id="rainbow-legend-container" class="container well" style="display:none;">
+            <div class="row">
+              <div class="col-md-4 col-md-offset-4" style="text-align: center;"># Tweets</div>
+            </div>
+
+            <div class="row">
+              <div id="legend-min" class="col-md-2 col-md-offset-1" style="text-align:right;"></div>
+              <div id="legend-gradient" class="col-md-5" style="text-align: center;"></div>
+              <div id="legend-max" class="col-md-2"></div>
+            </div>
+          </div><!-- End Legend Container -->
+          </div><!-- End Right Column -->
+        </div><!-- End Row -->
+
+        <!-- Tweetbook Comment Container -->
+        <div class="modal fade" id="drilldown_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+        <div class="modal-dialog">
+          <div class="modal-content">
+            <div class="modal-body" id="drilldown_modal_body">
+
+              <!-- Tweet -->
+              <div id="modal-body-tweet" class="well well-sm"></div>
+
+              <!-- Existing comments about this tweet -->
+              <!-- Create new comment -->
+              <div class="panel panel-default" id="modal-existing-note">
+                <div class="panel-heading">About this Tweetbook</div>
+                <div class="panel-body" id="modal-body-notes-holder">
+
+                  <div class="input-group">
+                    <input type="text" class="form-control" id="modal-body-tweet-note">
+                    <span class="input-group-btn">
+                      <button class="btn btn-default" id="modal-body-trash-icon">
+                        <span class="glyphicon glyphicon-trash"></span>
+                      </button>
+                    </span>
+                    <span class="badge" id="modal-current-tweetbook"></span>
+                  </div>
+
+                </div>
+              </div> 
+
+              <!-- Create new comment -->
+              <div class="panel panel-default" id="modal-save-tweet-panel">
+                <div class="panel-heading">Save to tweetbook</div>
+                <div class="panel-body" id="modal-save-body">
+
+                  <div class="input-group">
+                    <span class="input-group-addon">Note</span>
+                    <input type="text" class="form-control" id="modal-body-add-note" placeholder="Add a note about this tweet">
+                  </div>
+
+                  <div class="input-group">
+                    <span class="input-group-addon">Add to</span>
+                    <input type="text" class="form-control" id="modal-body-add-to" placeholder="Add it to a Tweetbook">
+                  </div><br/>
+
+                  <!-- Comment on tweet to save -->
+                  <button type="button" class="btn btn-default" id="save-comment-tweetbook-modal">Save</button>
+
+                  <div id="modal-body-message-holder"></div>
+
+                </div>
+              </div> 
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+            </div>
+          </div>
+        </div>
+        </div><!-- Modal -->     
+      </div><!-- End Container -->
+    </div><!-- End Main Demo Tab -->
+
+  </div><!-- End tab list -->
+</body>
+</html>
diff --git a/asterix-examples/src/main/resources/tweetbook-demo/tweetbook_bootstrap.py b/asterix-examples/src/main/resources/tweetbook-demo/tweetbook_bootstrap.py
new file mode 100755
index 0000000..d27939a
--- /dev/null
+++ b/asterix-examples/src/main/resources/tweetbook-demo/tweetbook_bootstrap.py
@@ -0,0 +1,46 @@
+import os
+import json
+import sys
+
+import requests
+from requests import ConnectionError, HTTPError
+
+def bootstrap():
+    asterix_host = "localhost"
+    asterix_port = 19002
+
+    # First, let's get the path to this script, we'll need it to configure the demo.
+    base = os.path.dirname(os.path.realpath(__file__))
+    print "Running Tweetbook Demo from",base
+
+    # First, we bootstrap our request query
+    print "Preparing Dataset..."
+    query_statement = open("static/data/query.txt").read().split("load")
+    query_statement[1] = "load" + query_statement[1].replace("FULL_PATH",base + "/static/data")
+
+    ddl = {
+        'ddl': query_statement[0]
+    }
+
+    load = {
+        "statements" : "use dataverse twitter; " + query_statement[1]
+    }
+
+    http_header = {
+        'content-type': 'application/json'
+    }
+
+    # Now we run our query
+    print "Running query...\n"
+
+    ddl_url = "http://" + asterix_host + ":" + str(asterix_port) + "/ddl"
+    update_url = "http://" + asterix_host + ":" + str(asterix_port) + "/update"
+
+    try:
+        requests.get(ddl_url, params=ddl)
+        response = requests.get(update_url, params=load, headers=http_header)
+    except (ConnectionError, HTTPError):
+        print "Encountered connection error; stopping execution"
+        sys.exit(1)
+
+    return True
